示例#1
0
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 {
示例#2
0
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;
}
示例#3
0
文件: stmt.cpp 项目: jcazzie/chapel
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;
}