GenRet BlockStmt::codegen() { GenInfo* info = gGenInfo; FILE* outfile = info->cfile; GenRet ret; codegenStmt(this); if( outfile ) { if (blockInfo) { if (blockInfo->isPrimitive(PRIM_BLOCK_WHILEDO_LOOP)) { std::string hdr = "while (" + codegenValue(blockInfo->get(1)).c + ") "; info->cStatements.push_back(hdr); } else if (blockInfo->isPrimitive(PRIM_BLOCK_DOWHILE_LOOP)) { info->cStatements.push_back("do "); } else if (blockInfo->isPrimitive(PRIM_BLOCK_FOR_LOOP)) { std::string hdr = "for (;" + codegenValue(blockInfo->get(1)).c + ";) "; info->cStatements.push_back(hdr); } else if (blockInfo->isPrimitive(PRIM_BLOCK_XMT_PRAGMA_FORALL_I_IN_N)) { std::string hdr = "_Pragma(\"mta for all streams "; hdr += codegenValue(blockInfo->get(1)).c; hdr += " of "; hdr += codegenValue(blockInfo->get(2)).c; hdr += "\")\n"; info->cStatements.push_back(hdr); } } if (this != getFunction()->body) info->cStatements.push_back("{\n"); if (!(fNoRepositionDefExpr)) { Vec<BaseAST*> asts; collect_top_asts(this, asts); forv_Vec(BaseAST, ast, asts) { if (DefExpr* def = toDefExpr(ast)) { if (def->parentExpr == this) { if (!toTypeSymbol(def->sym)) { if (fGenIDS && isVarSymbol(def->sym)) info->cStatements.push_back("/* " + numToString(def->sym->id) + " */ "); def->sym->codegenDef(); } } } } } body.codegen(""); if (blockInfo && blockInfo->isPrimitive(PRIM_BLOCK_DOWHILE_LOOP)) { std::string ftr = "} while (" + codegenValue(blockInfo->get(1)).c + ");\n"; info->cStatements.push_back(ftr); } else if (this != getFunction()->body) { std::string end = "}"; CondStmt* cond = toCondStmt(parentExpr); if (!cond || !(cond->thenStmt == this && cond->elseStmt)) end += "\n"; info->cStatements.push_back(end); } } else {
GenRet BlockStmt::codegen() { GenInfo* info = gGenInfo; FILE* outfile = info->cfile; GenRet ret; codegenStmt(this); if (outfile) { if (this != getFunction()->body) { if (this->blockInfoGet()) { if (this->blockInfoGet()->isPrimitive(PRIM_BLOCK_LOCAL)) { info->cStatements.push_back("/* local block */\n"); } } info->cStatements.push_back("{\n"); } body.codegen(""); if (this != getFunction()->body) { std::string end = "}"; CondStmt* cond = toCondStmt(parentExpr); if (!cond || !(cond->thenStmt == this && cond->elseStmt)) end += "\n"; info->cStatements.push_back(end); } } else { #ifdef HAVE_LLVM llvm::Function* func = info->builder->GetInsertBlock()->getParent(); llvm::BasicBlock* blockStmtBody = NULL; getFunction()->codegenUniqueNum++; blockStmtBody = llvm::BasicBlock::Create(info->module->getContext(), FNAME("blk_body")); info->builder->CreateBr(blockStmtBody); // Now add the body. func->getBasicBlockList().push_back(blockStmtBody); info->builder->SetInsertPoint(blockStmtBody); info->lvt->addLayer(); body.codegen(""); info->lvt->removeLayer(); INT_ASSERT(blockStmtBody->getParent() == func); #endif } return ret; }
GenRet GotoStmt::codegen() { GenInfo* info = gGenInfo; FILE* outfile = info->cfile; GenRet ret; codegenStmt(this); if( outfile ) { info->cStatements.push_back("goto " + label->codegen().c + ";\n"); } else { #ifdef HAVE_LLVM llvm::Function *func = info->builder->GetInsertBlock()->getParent(); const char *cname; if(isDefExpr(label)) { cname = toDefExpr(label)->sym->cname; } else { cname = toSymExpr(label)->symbol()->cname; } llvm::BasicBlock *blockLabel; if(!(blockLabel = info->lvt->getBlock(cname))) { blockLabel = llvm::BasicBlock::Create(info->module->getContext(), cname); info->lvt->addBlock(cname, blockLabel); } info->builder->CreateBr(blockLabel); getFunction()->codegenUniqueNum++; llvm::BasicBlock *afterGoto = llvm::BasicBlock::Create( info->module->getContext(), FNAME("afterGoto")); func->getBasicBlockList().push_back(afterGoto); info->builder->SetInsertPoint(afterGoto); #endif } return ret; }
GenRet DoWhileStmt::codegen() { GenInfo* info = gGenInfo; FILE* outfile = info->cfile; GenRet ret; codegenStmt(this); if (outfile) { codegenOrderIndependence(); info->cStatements.push_back("do "); if (this != getFunction()->body) info->cStatements.push_back("{\n"); body.codegen(""); std::string ftr= "} while (" + codegenValue(condExprGet()).c + ");\n"; info->cStatements.push_back(ftr); } else { #ifdef HAVE_LLVM llvm::Function* func = info->builder->GetInsertBlock()->getParent(); llvm::BasicBlock* blockStmtBody = NULL; llvm::BasicBlock* blockStmtEnd = NULL; llvm::BasicBlock* blockStmtEndCond = NULL; getFunction()->codegenUniqueNum++; blockStmtBody = llvm::BasicBlock::Create(info->module->getContext(), FNAME("blk_body")); blockStmtEnd = llvm::BasicBlock::Create(info->module->getContext(), FNAME("blk_end")); info->builder->CreateBr(blockStmtBody); // Now add the body. func->getBasicBlockList().push_back(blockStmtBody); info->builder->SetInsertPoint(blockStmtBody); info->lvt->addLayer(); body.codegen(""); info->lvt->removeLayer(); // Add the condition block. blockStmtEndCond = llvm::BasicBlock::Create(info->module->getContext(), FNAME("blk_end_cond")); func->getBasicBlockList().push_back(blockStmtEndCond); // Insert an explicit branch from the body block to the loop condition. info->builder->CreateBr(blockStmtEndCond); // set insert point info->builder->SetInsertPoint(blockStmtEndCond); GenRet condValueRet = codegenValue(condExprGet()); llvm::Value* condValue = condValueRet.val; if (condValue->getType() != llvm::Type::getInt1Ty(info->module->getContext())) { condValue = info->builder->CreateICmpNE(condValue, llvm::ConstantInt::get(condValue->getType(), 0), FNAME("condition")); } info->builder->CreateCondBr(condValue, blockStmtBody, blockStmtEnd); func->getBasicBlockList().push_back(blockStmtEnd); info->builder->SetInsertPoint(blockStmtEnd); if (blockStmtBody ) INT_ASSERT(blockStmtBody->getParent() == func); if (blockStmtEndCond) INT_ASSERT(blockStmtEndCond->getParent() == func); if (blockStmtEnd ) INT_ASSERT(blockStmtEnd->getParent() == func); #endif } return ret; }
GenRet CondStmt::codegen() { GenInfo* info = gGenInfo; FILE* outfile = info->cfile; GenRet ret; codegenStmt(this); if ( outfile ) { //here it's very possible that we end up with ( ) around condExpr. Extra //parentheses generated warnings from the backend compiler in some cases. //It didn't feel very safe to strip them at expr level as it might mess up //precedence thus, following conditional -- Engin std::string c_condExpr = codegenValue(condExpr).c; int numExtraPar = 0; //if (c_condExpr[0] == '(' && c_condExpr[c_condExpr.size()-1] == ')') { if (c_condExpr[numExtraPar] == '(' && c_condExpr[c_condExpr.size()-(numExtraPar+1)] == ')') { numExtraPar++; } c_condExpr = c_condExpr.substr(numExtraPar, c_condExpr.length()-2*numExtraPar); info->cStatements.push_back("if (" + c_condExpr + ") "); thenStmt->codegen(); if (elseStmt) { info->cStatements.push_back(" else "); elseStmt->codegen(); } } else { #ifdef HAVE_LLVM llvm::Function* func = info->builder->GetInsertBlock()->getParent(); getFunction()->codegenUniqueNum++; llvm::BasicBlock *condStmtIf = llvm::BasicBlock::Create( info->module->getContext(), FNAME("cond_if")); llvm::BasicBlock *condStmtThen = llvm::BasicBlock::Create( info->module->getContext(), FNAME("cond_then")); llvm::BasicBlock *condStmtElse = NULL; llvm::BasicBlock *condStmtEnd = llvm::BasicBlock::Create( info->module->getContext(), FNAME("cond_end")); if (elseStmt) { condStmtElse = llvm::BasicBlock::Create(info->module->getContext(), FNAME("cond_else")); } info->lvt->addLayer(); info->builder->CreateBr(condStmtIf); func->getBasicBlockList().push_back(condStmtIf); info->builder->SetInsertPoint(condStmtIf); GenRet condValueRet = codegenValue(condExpr); llvm::Value *condValue = condValueRet.val; if( condValue->getType() != llvm::Type::getInt1Ty(info->module->getContext()) ) { condValue = info->builder->CreateICmpNE( condValue, llvm::ConstantInt::get(condValue->getType(), 0), FNAME("condition")); } info->builder->CreateCondBr( condValue, condStmtThen, (elseStmt) ? condStmtElse : condStmtEnd); func->getBasicBlockList().push_back(condStmtThen); info->builder->SetInsertPoint(condStmtThen); info->lvt->addLayer(); thenStmt->codegen(); info->builder->CreateBr(condStmtEnd); info->lvt->removeLayer(); if(elseStmt) { func->getBasicBlockList().push_back(condStmtElse); info->builder->SetInsertPoint(condStmtElse); info->lvt->addLayer(); elseStmt->codegen(); info->builder->CreateBr(condStmtEnd); info->lvt->removeLayer(); } func->getBasicBlockList().push_back(condStmtEnd); info->builder->SetInsertPoint(condStmtEnd); info->lvt->removeLayer(); #endif } return ret; }