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 }