00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "BoundsEmitter.h"
00010 #include "CodeGenRoutine.h"
00011 #include "CodeGenTypes.h"
00012 #include "CommaRT.h"
00013 #include "comma/ast/AttribExpr.h"
00014 #include "comma/ast/Expr.h"
00015
00016 using namespace comma;
00017
00018 using llvm::dyn_cast;
00019 using llvm::dyn_cast_or_null;
00020 using llvm::cast;
00021 using llvm::isa;
00022
00023 CValue CodeGenRoutine::emitDeclRefExpr(DeclRefExpr *expr)
00024 {
00025 ValueDecl *refDecl = expr->getDeclaration();
00026 Type *exprType = resolveType(expr->getType());
00027 llvm::Value *exprValue = SRF->lookup(refDecl, activation::Slot);
00028
00029
00030
00031
00032 if (exprType->isFatAccessType())
00033 return CValue::getFat(exprValue);
00034
00035
00036
00037
00038
00039 if (RenamedObjectDecl *ROD = dyn_cast<RenamedObjectDecl>(refDecl)) {
00040 Expr *renamedExpr = ROD->getRenamedExpr()->ignoreInjPrj();
00041 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(renamedExpr))
00042 return emitDeclRefExpr(DRE);
00043 else
00044 return CValue::get(Builder.CreateLoad(exprValue));
00045 }
00046
00047
00048 if (isa<ObjectDecl>(refDecl))
00049 return CValue::get(Builder.CreateLoad(exprValue));
00050
00051
00052
00053 if (ParamValueDecl *pvDecl = dyn_cast<ParamValueDecl>(refDecl)) {
00054 PM::ParameterMode paramMode = pvDecl->getParameterMode();
00055 if (paramMode == PM::MODE_OUT || paramMode == PM::MODE_IN_OUT)
00056 exprValue = Builder.CreateLoad(exprValue);
00057 return CValue::get(exprValue);
00058 }
00059
00060
00061 if (isa<LoopDecl>(refDecl))
00062 return CValue::get(exprValue);
00063
00064 assert(false && "Unexpected type of expression!");
00065 return CValue::get(0);
00066 }
00067
00068 CValue CodeGenRoutine::emitInjExpr(InjExpr *expr)
00069 {
00070 return emitValue(expr->getOperand());
00071 }
00072
00073 CValue CodeGenRoutine::emitPrjExpr(PrjExpr *expr)
00074 {
00075 return emitValue(expr->getOperand());
00076 }
00077
00078 CValue CodeGenRoutine::emitNullExpr(NullExpr *expr)
00079 {
00080 AccessType *access = cast<AccessType>(resolveType(expr));
00081
00082 if (access->isThinAccessType()) {
00083 const llvm::PointerType *loweredTy;
00084 loweredTy = CGT.lowerThinAccessType(access);
00085 return CValue::get(llvm::ConstantPointerNull::get(loweredTy));
00086 }
00087 else {
00088 const llvm::StructType *loweredTy;
00089 const llvm::PointerType *dataTy;
00090 llvm::Value *fatPtr;
00091
00092 loweredTy = CGT.lowerFatAccessType(access);
00093 fatPtr = SRF->createTemp(loweredTy);
00094 dataTy = cast<llvm::PointerType>(loweredTy->getElementType(0));
00095
00096 Builder.CreateStore(llvm::ConstantPointerNull::get(dataTy),
00097 Builder.CreateStructGEP(fatPtr, 0));
00098 return CValue::getFat(fatPtr);
00099 }
00100 }
00101
00102 CValue CodeGenRoutine::emitIntegerLiteral(IntegerLiteral *expr)
00103 {
00104 const llvm::IntegerType *ty =
00105 cast<llvm::IntegerType>(CGT.lowerType(expr->getType()));
00106 llvm::APInt val(expr->getValue());
00107
00108
00109
00110 unsigned valWidth = val.getBitWidth();
00111 unsigned tyWidth = ty->getBitWidth();
00112 assert(valWidth <= tyWidth && "Value/Type width mismatch!");
00113
00114 if (valWidth < tyWidth)
00115 val.sext(tyWidth);
00116
00117 return CValue::get(llvm::ConstantInt::get(CG.getLLVMContext(), val));
00118 }
00119
00120 CValue CodeGenRoutine::emitIndexedArrayRef(IndexedArrayExpr *IAE)
00121 {
00122 assert(IAE->getNumIndices() == 1 &&
00123 "Multidimensional arrays are not yet supported!");
00124
00125 Expr *arrExpr = IAE->getPrefix();
00126 Expr *idxExpr = IAE->getIndex(0);
00127 ArrayType *arrTy = cast<ArrayType>(arrExpr->getType());
00128
00129
00130 llvm::Value *data;
00131 llvm::Value *bounds;
00132
00133
00134 const llvm::ArrayType *dataTy = CGT.lowerArrayType(arrTy);
00135 const llvm::Type *boundTy = CGT.lowerArrayBounds(arrTy);
00136
00137
00138
00139
00140 bool popVstack = false;
00141
00142 BoundsEmitter BE(*this);
00143
00144 if (FunctionCallExpr *call = dyn_cast<FunctionCallExpr>(arrExpr)) {
00145 if (!arrTy->isConstrained()) {
00146
00147
00148 emitSimpleCall(call);
00149
00150
00151 bounds = CRT.vstack(Builder, boundTy->getPointerTo());
00152 bounds = Builder.CreateLoad(bounds);
00153 CRT.vstack_pop(Builder);
00154
00155
00156 data = CRT.vstack(Builder, dataTy->getPointerTo());
00157 popVstack = true;
00158 }
00159 else {
00160
00161
00162 assert(arrTy->isStaticallyConstrained() &&
00163 "Cannot codegen dynamicly constrained arrays yet!");
00164
00165
00166
00167 bounds = BE.synthStaticArrayBounds(Builder, arrTy);
00168 data = SRF->createTemp(dataTy);
00169 emitCompositeCall(call, data);
00170 }
00171 }
00172 else {
00173 CValue arrValue = emitArrayExpr(arrExpr, 0, false);
00174 data = arrValue.first();
00175 bounds = arrValue.second();
00176 }
00177
00178
00179
00180 llvm::Value *index = emitValue(idxExpr).first();
00181 llvm::Value *lowerBound = BE.getLowerBound(Builder, bounds, 0);
00182 index = Builder.CreateSub(index, lowerBound);
00183 if (index->getType() != CG.getIntPtrTy())
00184 index = Builder.CreateIntCast(index, CG.getIntPtrTy(), false);
00185
00186
00187
00188 llvm::Value *component;
00189 llvm::Value *indices[2];
00190 indices[0] = llvm::ConstantInt::get(CG.getInt32Ty(), (uint64_t)0);
00191 indices[1] = index;
00192 component = Builder.CreateInBoundsGEP(data, indices, indices + 2);
00193
00194
00195
00196
00197
00198 if (popVstack) {
00199 llvm::Value *componentSlot = SRF->createTemp(dataTy->getElementType());
00200 Builder.CreateStore(Builder.CreateLoad(component), componentSlot);
00201 CRT.vstack_pop(Builder);
00202 component = componentSlot;
00203 }
00204
00205
00206 Type *componentTy = resolveType(arrTy->getComponentType());
00207
00208 if (componentTy->isArrayType()) {
00209 arrTy = cast<ArrayType>(componentTy);
00210 return CValue::getArray(component, BE.synthArrayBounds(Builder, arrTy));
00211 }
00212
00213 if (componentTy->isFatAccessType())
00214 return CValue::getFat(component);
00215
00216 return CValue::get(component);
00217 }
00218
00219 CValue CodeGenRoutine::emitIndexedArrayValue(IndexedArrayExpr *expr)
00220 {
00221 CValue addr = emitIndexedArrayRef(expr);
00222 if (addr.isSimple())
00223 return CValue::get(Builder.CreateLoad(addr.first()));
00224 else
00225 return addr;
00226 }
00227
00228 CValue CodeGenRoutine::emitSelectedRef(SelectedExpr *expr)
00229 {
00230
00231 CValue record = emitRecordExpr(expr->getPrefix(), 0, false);
00232 ComponentDecl *component = cast<ComponentDecl>(expr->getSelectorDecl());
00233
00234
00235 unsigned index = CGT.getComponentIndex(component);
00236 llvm::Value *ptr = Builder.CreateStructGEP(record.first(), index);
00237
00238 Type *componentTy = resolveType(expr);
00239 if (componentTy->isFatAccessType())
00240 return CValue::getFat(ptr);
00241
00242
00243 if (componentTy->isArrayType()) {
00244 ArrayType *arrTy = cast<ArrayType>(componentTy);
00245 BoundsEmitter emitter(*this);
00246 llvm::Value *bounds = emitter.synthArrayBounds(Builder, arrTy);
00247 return CValue::getArray(ptr, bounds);
00248 }
00249
00250 return CValue::get(ptr);
00251 }
00252
00253 CValue CodeGenRoutine::emitSelectedValue(SelectedExpr *expr)
00254 {
00255 CValue componentPtr = emitSelectedRef(expr);
00256 if (componentPtr.isSimple())
00257 return CValue::get(Builder.CreateLoad(componentPtr.first()));
00258 else
00259 return componentPtr;
00260 }
00261
00262 CValue CodeGenRoutine::emitDereferencedValue(DereferenceExpr *expr)
00263 {
00264 CValue value = emitValue(expr->getPrefix());
00265 llvm::Value *pointer = value.first();
00266 emitNullAccessCheck(pointer, expr->getLocation());
00267 return CValue::get(Builder.CreateLoad(pointer));
00268 }
00269
00270 CValue CodeGenRoutine::emitConversionValue(ConversionExpr *expr)
00271 {
00272
00273
00274 if (DiscreteType *target = dyn_cast<DiscreteType>(expr->getType())) {
00275 llvm::Value *value = emitDiscreteConversion(expr->getOperand(), target);
00276 return CValue::get(value);
00277 }
00278
00279 assert(false && "Cannot codegen given conversion yet!");
00280 return CValue::get(0);
00281 }
00282
00283 CValue CodeGenRoutine::emitDefaultValue(Type *type)
00284 {
00285 type = resolveType(type);
00286 const llvm::Type *loweredTy = CGT.lowerType(type);
00287
00288
00289 if (type->isFatAccessType()) {
00290 llvm::Value *slot = SRF->createTemp(loweredTy);
00291 llvm::Value *fatValue = llvm::ConstantAggregateZero::get(loweredTy);
00292 Builder.CreateStore(fatValue, slot);
00293 return CValue::getFat(slot);
00294 }
00295
00296
00297 if (type->isThinAccessType()) {
00298 const llvm::PointerType *ptrTy = cast<llvm::PointerType>(loweredTy);
00299 return CValue::get(llvm::ConstantPointerNull::get(ptrTy));
00300 }
00301
00302
00303 return CValue::get(llvm::ConstantInt::get(loweredTy, 0));
00304 }
00305
00306 CValue CodeGenRoutine::emitAllocatorValue(AllocatorExpr *expr)
00307 {
00308 Type *allocatedType = resolveType(expr->getAllocatedType());
00309 if (allocatedType->isCompositeType())
00310 return emitCompositeAllocator(expr);
00311
00312
00313 AccessType *exprTy = expr->getType();
00314 const llvm::PointerType *resultTy = CGT.lowerThinAccessType(exprTy);
00315 const llvm::Type *pointeeTy = resultTy->getElementType();
00316
00317 uint64_t size = CGT.getTypeSize(pointeeTy);
00318 unsigned align = CGT.getTypeAlignment(pointeeTy);
00319
00320
00321
00322 llvm::Value *pointer = CRT.comma_alloc(Builder, size, align);
00323 pointer = Builder.CreatePointerCast(pointer, resultTy);
00324
00325
00326
00327 if (expr->isInitialized()) {
00328 Expr *init = expr->getInitializer();
00329 Builder.CreateStore(emitValue(init).first(), pointer);
00330 }
00331
00332 return CValue::get(pointer);
00333 }
00334
00335 void
00336 CodeGenRoutine::emitDiscreteRangeCheck(llvm::Value *sourceVal, Location loc,
00337 Type *sourceTy, DiscreteType *targetTy)
00338 {
00339 const llvm::IntegerType *loweredSourceTy;
00340 const llvm::IntegerType *loweredTargetTy;
00341 loweredSourceTy = cast<llvm::IntegerType>(CGT.lowerType(sourceTy));
00342 loweredTargetTy = cast<llvm::IntegerType>(CGT.lowerType(targetTy));
00343
00344
00345 const llvm::IntegerType *docTy;
00346
00347
00348
00349 bool isSigned;
00350 if (DiscreteType *discTy = dyn_cast<DiscreteType>(sourceTy))
00351 isSigned = discTy->isSigned();
00352 else {
00353 assert(sourceTy->isUniversalIntegerType());
00354 isSigned = false;
00355 }
00356
00357
00358
00359 if (loweredTargetTy->getBitWidth() > loweredSourceTy->getBitWidth()) {
00360 docTy = loweredTargetTy;
00361 if (isSigned)
00362 sourceVal = Builder.CreateSExt(sourceVal, docTy);
00363 else
00364 sourceVal = Builder.CreateZExt(sourceVal, docTy);
00365 }
00366 else
00367 docTy = loweredSourceTy;
00368
00369 llvm::Value *lower = 0;
00370 llvm::Value *upper = 0;
00371
00372 if (llvm::Value *bounds = SRF->lookup(targetTy, activation::Bounds)) {
00373 lower = BoundsEmitter::getLowerBound(Builder, bounds, 0);
00374 upper = BoundsEmitter::getUpperBound(Builder, bounds, 0);
00375 }
00376 else {
00377 BoundsEmitter emitter(*this);
00378 BoundsEmitter::LUPair bounds =
00379 emitter.getScalarBounds(Builder, targetTy);
00380 lower = bounds.first;
00381 upper = bounds.second;
00382 }
00383
00384
00385 if (loweredTargetTy->getBitWidth() < docTy->getBitWidth()) {
00386 if (targetTy->isSigned()) {
00387 lower = Builder.CreateSExt(lower, docTy);
00388 upper = Builder.CreateSExt(upper, docTy);
00389 }
00390 else {
00391 lower = Builder.CreateZExt(lower, docTy);
00392 upper = Builder.CreateZExt(upper, docTy);
00393 }
00394 }
00395
00396
00397 llvm::BasicBlock *checkHighBB = SRF->makeBasicBlock("high.check");
00398 llvm::BasicBlock *checkFailBB = SRF->makeBasicBlock("check.fail");
00399 llvm::BasicBlock *checkMergeBB = SRF->makeBasicBlock("check.merge");
00400
00401
00402 llvm::Value *lowPass;
00403 if (targetTy->isSigned())
00404 lowPass = Builder.CreateICmpSLE(lower, sourceVal);
00405 else
00406 lowPass = Builder.CreateICmpULE(lower, sourceVal);
00407 Builder.CreateCondBr(lowPass, checkHighBB, checkFailBB);
00408
00409
00410 Builder.SetInsertPoint(checkHighBB);
00411 llvm::Value *highPass;
00412 if (targetTy->isSigned())
00413 highPass = Builder.CreateICmpSLE(sourceVal, upper);
00414 else
00415 highPass = Builder.CreateICmpULE(sourceVal, upper);
00416 Builder.CreateCondBr(highPass, checkMergeBB, checkFailBB);
00417
00418
00419 Builder.SetInsertPoint(checkFailBB);
00420 llvm::Value *fileName = CG.getModuleName();
00421 llvm::Value *lineNum = CG.getSourceLine(loc);
00422 llvm::GlobalVariable *msg = CG.emitInternString("Range check failed!");
00423 CRT.raiseConstraintError(SRF, fileName, lineNum, msg);
00424
00425
00426 Builder.SetInsertPoint(checkMergeBB);
00427 }
00428
00429 void CodeGenRoutine::emitNullAccessCheck(llvm::Value *pointer, Location loc)
00430 {
00431 llvm::BasicBlock *passBlock = SRF->makeBasicBlock("null.check.pass");
00432 llvm::BasicBlock *failBlock = SRF->makeBasicBlock("null.check.fail");
00433
00434 llvm::Value *pred = Builder.CreateIsNull(pointer);
00435
00436 Builder.CreateCondBr(pred, failBlock, passBlock);
00437
00438 Builder.SetInsertPoint(failBlock);
00439 llvm::Value *fileName = CG.getModuleName();
00440 llvm::Value *lineNum = CG.getSourceLine(loc);
00441 llvm::GlobalVariable *msg = CG.emitInternString("Null check failed.");
00442 CRT.raiseProgramError(SRF, fileName, lineNum, msg);
00443
00444
00445 Builder.SetInsertPoint(passBlock);
00446 }
00447
00448 llvm::Value *CodeGenRoutine::emitDiscreteConversion(Expr *expr,
00449 DiscreteType *targetTy)
00450 {
00451
00452 Type *exprTy = expr->getType();
00453 llvm::Value *sourceVal = emitValue(expr).first();
00454 const llvm::IntegerType *loweredTy = CGT.lowerDiscreteType(targetTy);
00455
00456
00457 if (exprTy == targetTy)
00458 return sourceVal;
00459
00460 unsigned sourceWidth = cast<llvm::IntegerType>(sourceVal->getType())->getBitWidth();
00461 unsigned targetWidth = loweredTy->getBitWidth();
00462
00463 if (DiscreteType *sourceTy = dyn_cast<DiscreteType>(exprTy)) {
00464
00465
00466 if (targetTy->contains(sourceTy) == DiscreteType::Is_Contained) {
00467 if (targetWidth == sourceWidth)
00468 return sourceVal;
00469 else if (targetWidth > sourceWidth) {
00470 if (targetTy->isSigned())
00471 return Builder.CreateSExt(sourceVal, loweredTy);
00472 else
00473 return Builder.CreateZExt(sourceVal, loweredTy);
00474 }
00475 }
00476 }
00477 else {
00478
00479
00480 assert(exprTy->isUniversalIntegerType() &&
00481 "Unexpected expression type!");
00482 }
00483
00484 emitDiscreteRangeCheck(sourceVal, expr->getLocation(), exprTy, targetTy);
00485
00486
00487 if (targetWidth < sourceWidth)
00488 sourceVal = Builder.CreateTrunc(sourceVal, loweredTy);
00489 else if (targetWidth > sourceWidth) {
00490 if (targetTy->isSigned())
00491 sourceVal = Builder.CreateSExt(sourceVal, loweredTy);
00492 else
00493 sourceVal = Builder.CreateZExt(sourceVal, loweredTy);
00494 }
00495 return sourceVal;
00496 }
00497
00498 CValue CodeGenRoutine::emitAttribExpr(AttribExpr *expr)
00499 {
00500 llvm::Value *result;
00501
00502 if (ScalarBoundAE *scalarAE = dyn_cast<ScalarBoundAE>(expr))
00503 result = emitScalarBoundAE(scalarAE);
00504 else if (ArrayBoundAE *arrayAE = dyn_cast<ArrayBoundAE>(expr))
00505 result = emitArrayBoundAE(arrayAE);
00506 else {
00507 assert(false && "Cannot codegen attribute yet!");
00508 result = 0;
00509 }
00510
00511 return CValue::get(result);
00512 }
00513
00514 llvm::Value *CodeGenRoutine::emitScalarBoundAE(ScalarBoundAE *AE)
00515 {
00516 BoundsEmitter emitter(*this);
00517 DiscreteType *Ty = AE->getType();
00518 if (AE->isFirst())
00519 return emitter.getLowerBound(Builder, Ty);
00520 else
00521 return emitter.getUpperBound(Builder, Ty);
00522 }
00523
00524 llvm::Value *CodeGenRoutine::emitArrayBoundAE(ArrayBoundAE *AE)
00525 {
00526 BoundsEmitter emitter(*this);
00527 ArrayType *arrTy = AE->getPrefixType();
00528
00529 if (arrTy->isConstrained()) {
00530
00531
00532 IntegerType *indexTy = AE->getType();
00533 if (AE->isFirst())
00534 return emitter.getLowerBound(Builder, indexTy);
00535 else
00536 return emitter.getUpperBound(Builder, indexTy);
00537 }
00538
00539
00540
00541 CValue arrValue = emitCompositeExpr(AE->getPrefix(), 0, false);
00542 llvm::Value *bounds = arrValue.second();
00543 unsigned dimension = AE->getDimension();
00544
00545 if (AE->isFirst())
00546 return emitter.getLowerBound(Builder, bounds, dimension);
00547 else
00548 return emitter.getUpperBound(Builder, bounds, dimension);
00549 }