예제 #1
0
파일: Generator.cpp 프로젝트: mijara/vfl
llvm::Value * Generator::visit(For & node)
{
    VarDecl initial(node.variable, nullptr, node.initial);
    auto counter = initial.accept(this);

    // create the block.
    auto function = builder.GetInsertBlock()->getParent();
    auto block = llvm::BasicBlock::Create(*context, "forloop", function);
    auto after = llvm::BasicBlock::Create(*context, "forcont");
    auto condition = node.condition->accept(this);

    // fall to the block.
    builder.CreateCondBr(condition, block, after);

    builder.SetInsertPoint(block);

    createScope();
    node.block->accept(this);
    popScope();

    // increment the counter.
    auto variable = builder.CreateLoad(counter);
    auto result = builder.CreateAdd(variable, node.increment->accept(this), "counter");
    builder.CreateStore(result, counter);

    // execute again or stop.
    condition = node.condition->accept(this);
    builder.CreateCondBr(condition, block, after);

    // insert the after block.
    function->getBasicBlockList().push_back(after);
    builder.SetInsertPoint(after);

    return nullptr;
}
예제 #2
0
파일: builtins.cpp 프로젝트: boardwalk/xra
void BWhile::Compile(Compiler& compiler, const vector<ExprPtr>& args)
{
  assert(args.size() == 2);

  auto& builder = compiler.builder;
  auto& ctx = compiler.module.getContext();
  auto func = builder.GetInsertBlock()->getParent();

  auto condBlock = llvm::BasicBlock::Create(ctx, "while", func);
  auto doBlock = llvm::BasicBlock::Create(ctx, "do", func);
  auto lastEndLoopBlock = compiler.endLoopBlock;
  compiler.endLoopBlock = llvm::BasicBlock::Create(ctx, "endwhile");

  builder.CreateBr(condBlock);

  // while
  builder.SetInsertPoint(condBlock);
  compiler.Visit(args[0].get());
  builder.CreateCondBr(compiler.result, doBlock, compiler.endLoopBlock);
  compiler.result = nullptr;

  // do
  builder.SetInsertPoint(doBlock);
  compiler.Visit(args[1].get());
  compiler.result = nullptr;
  builder.CreateBr(condBlock);

  // endloop
  func->getBasicBlockList().push_back(compiler.endLoopBlock);
  builder.SetInsertPoint(compiler.endLoopBlock);
  compiler.endLoopBlock = lastEndLoopBlock;
}
예제 #3
0
파일: Generator.cpp 프로젝트: mijara/vfl
llvm::Value * Generator::visit(If & node)
{
    auto condition = node.condition->accept(this);

    auto function = builder.GetInsertBlock()->getParent();

    auto thenBlock = llvm::BasicBlock::Create(*context, "then", function);
    auto elseBlock = llvm::BasicBlock::Create(*context, "else");
    auto mergeBlock = llvm::BasicBlock::Create(*context, "ifcont");

    if (node.elseBlock) {
        builder.CreateCondBr(condition, thenBlock, elseBlock);
    } else {
        builder.CreateCondBr(condition, thenBlock, mergeBlock);
    }

    builder.SetInsertPoint(thenBlock);

    createScope();
    node.thenBlock->accept(this);
    popScope();

    thenBlock = builder.GetInsertBlock();

    if (thenBlock->getTerminator() == nullptr) {
        builder.CreateBr(mergeBlock);
    }

    if (node.elseBlock) {
        function->getBasicBlockList().push_back(elseBlock);
        builder.SetInsertPoint(elseBlock);

        createScope();
        node.elseBlock->accept(this);
        popScope();

        builder.CreateBr(mergeBlock);
    }

    function->getBasicBlockList().push_back(mergeBlock);
    builder.SetInsertPoint(mergeBlock);

    return nullptr;
}
예제 #4
0
파일: builtins.cpp 프로젝트: boardwalk/xra
void BIf::Compile(Compiler& compiler, const vector<ExprPtr>& args)
{
  assert(args.size() >= 2 && args.size() % 2 == 0);

  const size_t nclauses = args.size() / 2;
  auto& builder = compiler.builder;
  auto& ctx = compiler.module.getContext();
  auto func = builder.GetInsertBlock()->getParent();

  llvm::AllocaInst* alloc = nullptr;
  if(args.size() > 2)
    alloc = builder.CreateAlloca(ToLLVM(*args[1]->value->type, ctx), nullptr, "iftmp");
  auto endifBlock = llvm::BasicBlock::Create(ctx, "endif");

  for(size_t i = 0; i < nclauses; i++)
  {
    auto thenBlock = llvm::BasicBlock::Create(ctx, "then", func);
    auto contBlock = (i < nclauses - 1) ? llvm::BasicBlock::Create(ctx, "else", func) : endifBlock;

    // if
    compiler.Visit(args[i * 2].get());
    compiler.result = compiler.Load(compiler.result);
    builder.CreateCondBr(compiler.result, thenBlock, contBlock);
    compiler.result = nullptr;

    // then
    builder.SetInsertPoint(thenBlock);
    compiler.Visit(args[i * 2 + 1].get());
    if(alloc)
      builder.CreateStore(compiler.Load(compiler.result), alloc);
    compiler.result = nullptr;
    builder.CreateBr(endifBlock);

    // else or endif
    builder.SetInsertPoint(contBlock);
  }

  func->getBasicBlockList().push_back(endifBlock);

  if(alloc)
    compiler.result = builder.CreateLoad(alloc);
}
예제 #5
0
파일: ForGen.cpp 프로젝트: mijara/xvfl
llvm::Value * ForGen::emit(VflModule & module, ForAST & node)
{
    VarDeclAST initial(node.getVariable(), nullptr, node.getInitial());
    auto counter = initial.accept(demux);

    // create the block.
    auto function = module.getBuilder().GetInsertBlock()->getParent();
    auto block = llvm::BasicBlock::Create(llvm::getGlobalContext(), "forloop", function);
    auto after = llvm::BasicBlock::Create(llvm::getGlobalContext(), "forcont");
    auto condition = module.loadIfPtr(demux, node.getCondition());

    // fall to the block.
    module.getBuilder().CreateCondBr(condition, block, after);

    module.getBuilder().SetInsertPoint(block);

    module.createScope();
    node.getBlock()->accept(demux);
    module.popScope();

    // increment the counter.
    auto variable = module.getBuilder().CreateLoad(counter);
    auto result = module.getBuilder().CreateAdd(variable, module.loadIfPtr(demux, node.getIncrement()),
            "counter");
    module.getBuilder().CreateStore(result, counter);

    // execute again or stop.
    condition = node.getCondition()->accept(demux);
    module.getBuilder().CreateCondBr(condition, block, after);

    // insert the after block.
    function->getBasicBlockList().push_back(after);
    module.getBuilder().SetInsertPoint(after);

    return nullptr;
}