I want to use LLVM APIs to translate own language to IR code. I implement it like below. But I got nothing in if_then tag, and if_else is missing too.
Value* NIfStatement::codeGen(CodeGenContext& context)
{
std::cout << "Creating if statement " << std::endl;
Value *condValue = condition.codeGen(context);
if (condValue == nullptr) return nullptr;
std::cout << condValue->getType()->getTypeID() << std::endl;
condValue = new FCmpInst(*context.currentBlock(), CmpInst::FCMP_ONE,
condValue, ConstantFP::get(getGlobalContext(), APFloat(0.0)));
Function *function = context.currentBlock()->getParent();
BasicBlock *thenBlock = BasicBlock::Create(getGlobalContext(), “if.then”, function);
BasicBlock *elseBlock = BasicBlock::Create(getGlobalContext(), “if.else”);
BasicBlock *mergeBlock = BasicBlock::Create(getGlobalContext(), “if.cont”);
BranchInst::Create(thenBlock, elseBlock, condValue, context.currentBlock());
// create then block
context.pushBlock(thenBlock);
Value *thenValue = conditionCodeGen(context, thenblock);
if (thenValue == nullptr) return nullptr;
BranchInst::Create(mergeBlock, context.currentBlock());
context.popBlock();
// create else block
function->getBasicBlockList().push_back(elseBlock);
context.pushBlock(elseBlock);
Value *elseValue = conditionCodeGen(context, elseblock);
if (elseValue == nullptr) return nullptr;
BranchInst::Create(mergeBlock, context.currentBlock());
context.popBlock();
// create PHI node
function->getBasicBlockList().push_back(mergeBlock);
context.pushBlock(mergeBlock);
PHINode *PN = PHINode::Create(Type::getVoidTy(getGlobalContext()), 2, “if.tmp”, mergeBlock);
PN->addIncoming(thenValue, thenBlock);
PN->addIncoming(elseValue, elseBlock);
context.popBlock();
return PN;
}
Value* NIfStatement::conditionCodeGen(CodeGenContext& context, StatementList& block)
{
std::cout << “Generate conditional block” << std::endl;
StatementList::const_iterator it;
Value *last = nullptr;
for (it = block.begin(); it != block.end(); it++) {
std::cout << "Generating code for " << typeid(**it).name() << ’ ’ << std::endl;
last = (**it).codeGen(context);
}
return last;
}
AST:
class NIfStatement : public NStatement {
public:
NBinaryOperator& condition;
StatementList thenblock;
StatementList elseblock;
NIfStatement(NBinaryOperator& condition, StatementList& thenblock) :
condition(condition), thenblock(thenblock) {}
NIfStatement(NBinaryOperator& condition, StatementList& thenblock, StatementList& elseblock) :
condition(condition), thenblock(thenblock), elseblock(elseblock) {}
virtual llvm::Value* codeGen(CodeGenContext& context);
virtual llvm::Value* conditionCodeGen(CodeGenContext& context, StatementList& block);
};
Running result:
define internal i64 @main() {
entry:
%x = alloca i64
%y = alloca i64
%z = alloca i64
%str = alloca double
store i64 5, i64* %z
%0 = load i64* %x
%cmptmp = icmp uge i64 %0, 0
%1 = fcmp one double %booltmp, 0.000000e+00
br i1 %1, label %if.then, label %if.else
ret void
if.then: ; preds = %entry
}
Can anyone help me? What’s wrong? Thank you!