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 "HandlerEmitter.h"
00014 #include "comma/ast/Decl.h"
00015 #include "comma/ast/DSTDefinition.h"
00016 #include "comma/ast/Expr.h"
00017 #include "comma/ast/Pragma.h"
00018 #include "comma/ast/RangeAttrib.h"
00019 #include "comma/ast/Stmt.h"
00020 
00021 using namespace comma;
00022 
00023 using llvm::dyn_cast;
00024 using llvm::cast;
00025 using llvm::isa;
00026 
00027 void CodeGenRoutine::emitStmt(Stmt *stmt)
00028 {
00029     switch (stmt->getKind()) {
00030 
00031     default:
00032         assert(false && "Cannot codegen stmt yet!");
00033 
00034     case Ast::AST_ProcedureCallStmt:
00035         emitProcedureCallStmt(cast<ProcedureCallStmt>(stmt));
00036         break;
00037 
00038     case Ast::AST_AssignmentStmt:
00039         emitAssignmentStmt(cast<AssignmentStmt>(stmt));
00040         break;
00041 
00042     case Ast::AST_StmtSequence:
00043         emitStmtSequence(cast<StmtSequence>(stmt));
00044         break;
00045 
00046     case Ast::AST_BlockStmt:
00047         emitBlockStmt(cast<BlockStmt>(stmt), Builder.GetInsertBlock());
00048         break;
00049 
00050     case Ast::AST_IfStmt:
00051         emitIfStmt(cast<IfStmt>(stmt));
00052         break;
00053 
00054     case Ast::AST_WhileStmt:
00055         emitWhileStmt(cast<WhileStmt>(stmt));
00056         break;
00057 
00058     case Ast::AST_ForStmt:
00059         emitForStmt(cast<ForStmt>(stmt));
00060         break;
00061 
00062     case Ast::AST_LoopStmt:
00063         emitLoopStmt(cast<LoopStmt>(stmt));
00064         break;
00065 
00066     case Ast::AST_ReturnStmt:
00067         emitReturnStmt(cast<ReturnStmt>(stmt));
00068         break;
00069 
00070     case Ast::AST_RaiseStmt:
00071         emitRaiseStmt(cast<RaiseStmt>(stmt));
00072         break;
00073 
00074     case Ast::AST_PragmaStmt:
00075         emitPragmaStmt(cast<PragmaStmt>(stmt));
00076         break;
00077 
00078     case Ast::AST_NullStmt:
00079         break;
00080     }
00081 }
00082 
00083 void CodeGenRoutine::emitReturnStmt(ReturnStmt *ret)
00084 {
00085     if (!ret->hasReturnExpr()) {
00086         SRF->emitReturn();
00087         return;
00088     }
00089 
00090     FunctionDecl *fdecl = cast<FunctionDecl>(SRI->getDeclaration());
00091     FunctionType *fTy = fdecl->getType();
00092     Type *targetTy = resolveType(fTy->getReturnType());
00093     Expr *expr = ret->getReturnExpr();
00094     llvm::Value *returnValue = SRF->getReturnValue();
00095 
00096     if (ArrayType *arrTy = dyn_cast<ArrayType>(targetTy)) {
00097         
00098         
00099         if (arrTy->isConstrained())
00100             emitArrayExpr(expr, returnValue, false);
00101         else {
00102             assert(returnValue == 0);
00103             emitVStackReturn(expr, arrTy);
00104         }
00105     }
00106     else if (targetTy->isRecordType()) {
00107         
00108         emitRecordExpr(expr, returnValue, false);
00109     }
00110     else if (targetTy->isFatAccessType()) {
00111         
00112         
00113         llvm::Value *res = emitValue(ret->getReturnExpr()).first();
00114         Builder.CreateStore(Builder.CreateLoad(res), returnValue);
00115     }
00116     else {
00117         
00118         
00119         llvm::Value *res = emitValue(ret->getReturnExpr()).first();
00120         Builder.CreateStore(res, returnValue);
00121     }
00122 
00123     
00124     SRF->emitReturn();
00125 }
00126 
00127 void CodeGenRoutine::emitVStackReturn(Expr *expr, ArrayType *arrTy)
00128 {
00129     if (FunctionCallExpr *call = dyn_cast<FunctionCallExpr>(expr)) {
00130         emitSimpleCall(call);
00131         return;
00132     }
00133 
00134     BoundsEmitter emitter(*this);
00135     CValue arrValue = emitArrayExpr(expr, 0, false);
00136     const llvm::Type *componentTy = CGT.lowerType(arrTy->getComponentType());
00137     llvm::Value *data = arrValue.first();
00138     llvm::Value *bounds = arrValue.second();
00139     llvm::Value *length = emitter.computeTotalBoundLength(Builder, bounds);
00140     const llvm::Type *boundsTy = bounds->getType();
00141 
00142     
00143     
00144     llvm::Value *dataSize;
00145     dataSize = llvm::ConstantExpr::getSizeOf(componentTy);
00146     dataSize = Builder.CreateTrunc(dataSize, CG.getInt32Ty());
00147     dataSize = Builder.CreateMul(dataSize, length);
00148 
00149     
00150     
00151     llvm::Value *boundsSize;
00152     if (boundsTy->isAggregateType())
00153         boundsSize = llvm::ConstantExpr::getSizeOf(boundsTy);
00154     else {
00155         const llvm::PointerType *ptr;
00156         ptr = llvm::cast<llvm::PointerType>(boundsTy);
00157         boundsSize = llvm::ConstantExpr::getSizeOf(ptr->getElementType());
00158     }
00159     boundsSize = Builder.CreateTrunc(boundsSize, CG.getInt32Ty());
00160 
00161     
00162     
00163     if (boundsTy->isAggregateType()) {
00164         llvm::Value *slot = SRF->createTemp(boundsTy);
00165         Builder.CreateStore(bounds, slot);
00166         bounds = slot;
00167     }
00168 
00169     CRT.vstack_push(Builder, data, dataSize);
00170     CRT.vstack_push(Builder, bounds, boundsSize);
00171 }
00172 
00173 void CodeGenRoutine::emitStmtSequence(StmtSequence *seq)
00174 {
00175     for (StmtSequence::stmt_iter iter = seq->stmt_begin();
00176          iter != seq->stmt_end(); ++iter)
00177         emitStmt(*iter);
00178 }
00179 
00180 llvm::BasicBlock *CodeGenRoutine::emitBlockStmt(BlockStmt *block,
00181                                                 llvm::BasicBlock *predecessor)
00182 {
00183     assert(block && "NULL block statement!");
00184 
00185     std::string label;
00186     if (block->hasLabel())
00187         label = block->getLabel()->getString();
00188 
00189     llvm::BasicBlock *BB = SRF->makeBasicBlock(label);
00190     SRF->pushFrame(BB);
00191 
00192     if (block->isHandled())
00193         SRF->addLandingPad();
00194 
00195     if (predecessor) {
00196         Builder.CreateBr(BB);
00197         BB->moveAfter(predecessor);
00198     }
00199 
00200     Builder.SetInsertPoint(BB);
00201 
00202     
00203     
00204     typedef DeclRegion::DeclIter iterator;
00205     for (iterator I = block->beginDecls(); I != block->endDecls(); ++I) {
00206         Decl *decl = *I;
00207         switch (decl->getKind()) {
00208         default:
00209             break;
00210 
00211         case Ast::AST_ObjectDecl:
00212             emitObjectDecl(cast<ObjectDecl>(decl));
00213             break;
00214 
00215         case Ast::AST_RenamedObjectDecl:
00216             emitRenamedObjectDecl(cast<RenamedObjectDecl>(decl));
00217             break;
00218         }
00219     }
00220     emitStmtSequence(block);
00221 
00222     if (block->isHandled()) {
00223         
00224         
00225         llvm::BasicBlock *mergeBB = SRF->makeBasicBlock("handler.merge");
00226         if (!Builder.GetInsertBlock()->getTerminator())
00227             Builder.CreateBr(mergeBB);
00228 
00229         
00230         HandlerEmitter emitter(*this);
00231         emitter.emitHandlers(block, mergeBB);
00232     }
00233 
00234     SRF->popFrame();
00235     return BB;
00236 }
00237 
00238 void CodeGenRoutine::emitIfStmt(IfStmt *ite)
00239 {
00240     CValue condition = emitValue(ite->getCondition());
00241     llvm::BasicBlock *thenBB = SRF->makeBasicBlock("then");
00242     llvm::BasicBlock *mergeBB = SRF->makeBasicBlock("merge");
00243     llvm::BasicBlock *elseBB;
00244 
00245     if (ite->hasElsif())
00246         elseBB = SRF->makeBasicBlock("elsif");
00247     else if (ite->hasAlternate())
00248         elseBB = SRF->makeBasicBlock("else");
00249     else
00250         elseBB = mergeBB;
00251 
00252     Builder.CreateCondBr(condition.first(), thenBB, elseBB);
00253     Builder.SetInsertPoint(thenBB);
00254 
00255     
00256     
00257     SRF->pushFrame(thenBB);
00258     emitStmt(ite->getConsequent());
00259     if (!Builder.GetInsertBlock()->getTerminator())
00260         Builder.CreateBr(mergeBB);
00261     SRF->popFrame();
00262 
00263     
00264     for (IfStmt::iterator I = ite->beginElsif(); I != ite->endElsif(); ++I) {
00265         Builder.SetInsertPoint(elseBB);
00266         IfStmt::iterator J = I;
00267         if (++J != ite->endElsif())
00268             elseBB = SRF->makeBasicBlock("elsif");
00269         else if (ite->hasAlternate())
00270             elseBB = SRF->makeBasicBlock("else");
00271         else
00272             elseBB = mergeBB;
00273         llvm::BasicBlock *bodyBB = SRF->makeBasicBlock("body");
00274         llvm::Value *pred = emitValue(I->getCondition()).first();
00275         Builder.CreateCondBr(pred, bodyBB, elseBB);
00276         Builder.SetInsertPoint(bodyBB);
00277 
00278         SRF->pushFrame(bodyBB);
00279         emitStmt(I->getConsequent());
00280         if (!Builder.GetInsertBlock()->getTerminator())
00281             Builder.CreateBr(mergeBB);
00282         SRF->popFrame();
00283     }
00284 
00285     if (ite->hasAlternate()) {
00286         Builder.SetInsertPoint(elseBB);
00287 
00288         SRF->pushFrame(elseBB);
00289         emitStmt(ite->getAlternate());
00290         if (!Builder.GetInsertBlock()->getTerminator())
00291             Builder.CreateBr(mergeBB);
00292         SRF->popFrame();
00293     }
00294 
00295     Builder.SetInsertPoint(mergeBB);
00296 }
00297 
00298 void CodeGenRoutine::emitWhileStmt(WhileStmt *stmt)
00299 {
00300     llvm::BasicBlock *entryBB = SRF->makeBasicBlock("while.top");
00301     llvm::BasicBlock *bodyBB = SRF->makeBasicBlock("while.entry");
00302     llvm::BasicBlock *mergeBB = SRF->makeBasicBlock("while.merge");
00303 
00304     
00305     
00306     
00307     Builder.CreateBr(entryBB);
00308     Builder.SetInsertPoint(entryBB);
00309     CValue condition = emitValue(stmt->getCondition());
00310 
00311     
00312     Builder.CreateCondBr(condition.first(), bodyBB, mergeBB);
00313 
00314     
00315     Builder.SetInsertPoint(bodyBB);
00316     SRF->pushFrame(bodyBB);
00317     emitStmt(stmt->getBody());
00318     SRF->popFrame();
00319 
00320     
00321     
00322     if (!Builder.GetInsertBlock()->getTerminator())
00323         Builder.CreateBr(entryBB);
00324 
00325     
00326     Builder.SetInsertPoint(mergeBB);
00327 }
00328 
00329 void CodeGenRoutine::emitForStmt(ForStmt *loop)
00330 {
00331     llvm::Value *iter;          
00332     llvm::Value *sentinal;      
00333 
00334     DSTDefinition *control = loop->getControl();
00335     if (control->definedUsingAttrib()) {
00336         std::pair<llvm::Value*, llvm::Value*> bounds;
00337         RangeAttrib *attrib = control->getAttrib();
00338         bounds = emitRangeAttrib(attrib);
00339         iter = bounds.first;
00340         sentinal = bounds.second;
00341     }
00342     else {
00343         BoundsEmitter emitter(*this);
00344         BoundsEmitter::LUPair bounds;
00345         bounds = emitter.getScalarBounds(Builder, control->getType());
00346         iter = bounds.first;
00347         sentinal = bounds.second;
00348     }
00349 
00350     
00351     if (loop->isReversed())
00352         std::swap(iter, sentinal);
00353 
00354     
00355     
00356     
00357     llvm::BasicBlock *dominatorBB = Builder.GetInsertBlock();
00358     llvm::BasicBlock *entryBB = SRF->makeBasicBlock("for.top");
00359     llvm::BasicBlock *iterBB = SRF->makeBasicBlock("for.iter");
00360     llvm::BasicBlock *bodyBB = SRF->makeBasicBlock("for.body");
00361     llvm::BasicBlock *mergeBB = SRF->makeBasicBlock("for.merge");
00362     llvm::Value *pred;
00363     llvm::Value *iterSlot;
00364     llvm::Value *next;
00365     llvm::PHINode *phi;
00366     const llvm::Type *iterTy = iter->getType();
00367 
00368     
00369     
00370     iterSlot = SRF->createTemp(iterTy);
00371     Builder.CreateStore(iter, iterSlot);
00372 
00373     
00374     
00375     
00376     
00377     if (loop->isReversed())
00378         pred = Builder.CreateICmpSLT(iter, sentinal);
00379     else
00380         pred = Builder.CreateICmpSGT(iter, sentinal);
00381     Builder.CreateCondBr(pred, mergeBB, bodyBB);
00382 
00383     
00384     
00385     
00386     
00387     
00388     
00389     Builder.SetInsertPoint(entryBB);
00390     next = Builder.CreateLoad(iterSlot);
00391     pred = Builder.CreateICmpEQ(next, sentinal);
00392     Builder.CreateCondBr(pred, mergeBB, iterBB);
00393 
00394     
00395     Builder.SetInsertPoint(iterBB);
00396     if (loop->isReversed())
00397         next = Builder.CreateSub(next, llvm::ConstantInt::get(iterTy, 1));
00398     else
00399         next = Builder.CreateAdd(next, llvm::ConstantInt::get(iterTy, 1));
00400     Builder.CreateStore(next, iterSlot);
00401     Builder.CreateBr(bodyBB);
00402 
00403     
00404     
00405     Builder.SetInsertPoint(bodyBB);
00406     SRF->pushFrame(bodyBB);
00407     phi = Builder.CreatePHI(iterTy, "loop.param");
00408     phi->addIncoming(iter, dominatorBB);
00409     phi->addIncoming(next, iterBB);
00410     SRF->associate(loop->getLoopDecl(), activation::Slot, phi);
00411     emitStmtSequence(loop->getBody());
00412     SRF->popFrame();
00413     if (!Builder.GetInsertBlock()->getTerminator())
00414         Builder.CreateBr(entryBB);
00415 
00416     
00417     Builder.SetInsertPoint(mergeBB);
00418 }
00419 
00420 void CodeGenRoutine::emitLoopStmt(LoopStmt *stmt)
00421 {
00422     llvm::BasicBlock *bodyBB = SRF->makeBasicBlock("loop.body");
00423     llvm::BasicBlock *mergeBB = SRF->makeBasicBlock("loop.merge");
00424 
00425     
00426     Builder.CreateBr(bodyBB);
00427     Builder.SetInsertPoint(bodyBB);
00428 
00429     
00430     SRF->pushFrame(bodyBB);
00431     emitStmt(stmt->getBody());
00432     SRF->popFrame();
00433 
00434     
00435     
00436     if (!Builder.GetInsertBlock()->getTerminator())
00437         Builder.CreateBr(bodyBB);
00438 
00439     
00440     Builder.SetInsertPoint(mergeBB);
00441 }
00442 
00443 void CodeGenRoutine::emitRaiseStmt(RaiseStmt *stmt)
00444 {
00445     CommaRT &CRT = CG.getRuntime();
00446     ExceptionDecl *exception = stmt->getExceptionDecl();
00447     llvm::Value *fileName = CG.getModuleName();
00448     llvm::Value *lineNum = CG.getSourceLine(stmt->getLocation());
00449 
00450     if (stmt->hasMessage()) {
00451         BoundsEmitter emitter(*this);
00452         CValue arrValue = emitArrayExpr(stmt->getMessage(), 0, false);
00453         llvm::Value *message;
00454         llvm::Value *length;
00455 
00456         message = arrValue.first();
00457         length = emitter.computeBoundLength(Builder, arrValue.second(), 0);
00458         CRT.raise(SRF, exception, fileName, lineNum, message, length);
00459     }
00460     else
00461         CRT.raise(SRF, exception, fileName, lineNum, 0, 0);
00462 }
00463 
00464 void CodeGenRoutine::emitPragmaStmt(PragmaStmt *stmt)
00465 {
00466     
00467     Pragma *pragma = stmt->getPragma();
00468 
00469     switch (pragma->getKind()) {
00470 
00471     default:
00472         assert(false && "Cannot codegen pragma yet!");
00473         break;
00474 
00475     case pragma::Assert:
00476         emitPragmaAssert(cast<PragmaAssert>(pragma));
00477         break;
00478     };
00479 }