From 43abbf64217a7ff4de3f1cb28bcbc511e0a9e9e0 Mon Sep 17 00:00:00 2001 From: Jeffrey C Johnson Date: Sun, 29 May 2016 00:13:08 -0700 Subject: [PATCH] Short circuit && and || --- ast_expr.cc | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/ast_expr.cc b/ast_expr.cc index ecc44c8..f82d56c 100644 --- a/ast_expr.cc +++ b/ast_expr.cc @@ -187,11 +187,35 @@ static llvm::Value* typeConvert(llvm::Value* val, llvm::Value* target) { return ret; } -// TODO ++ and -- on vectors? llvm::Value* CompoundExpr::Emit() { + llvm::BasicBlock* b = irgen.GetBasicBlock(); + llvm::Function * func = irgen.GetFunction(); + llvm::LLVMContext* context = irgen.GetContext(); + //weird bc of short circuting + if(op->getToken() == "&&" || op->getToken() == "||") { + llvm::Value* val = new llvm::AllocaInst(llvm::Type::getInt1Ty(*context), "", b); + llvm::BasicBlock * otherBlock = llvm::BasicBlock::Create(*context, "otherBlock", func); + llvm::BasicBlock * falseBlock = llvm::BasicBlock::Create(*context, "falseBlock", func); + llvm::BasicBlock * trueBlock = llvm::BasicBlock::Create(*context, "trueBlock", func); + llvm::BasicBlock * footBlock = llvm::BasicBlock::Create(*context, "footBlock", func); + llvm::Value* l = left->Emit(); + b = irgen.GetBasicBlock(); + if(op->getToken() == "&&") llvm::BranchInst::Create(otherBlock, falseBlock, l, b); + if(op->getToken() == "||") llvm::BranchInst::Create(trueBlock, otherBlock, l, b); + irgen.SetBasicBlock(otherBlock); + llvm::Value* r = right->Emit(); + b = irgen.GetBasicBlock(); + llvm::BranchInst::Create(trueBlock, falseBlock, r, b); + new llvm::StoreInst(llvm::ConstantInt::get(llvm::Type::getInt1Ty(*context), true), val, false, trueBlock); + llvm::BranchInst::Create(footBlock, trueBlock); + new llvm::StoreInst(llvm::ConstantInt::get(llvm::Type::getInt1Ty(*context), false), val, false, falseBlock); + llvm::BranchInst::Create(footBlock, falseBlock); + irgen.SetBasicBlock(footBlock); + return new llvm::LoadInst(val, "", footBlock); + } llvm::Value* l = left ? left->Emit() : NULL; llvm::Value* r = right ? right->Emit() : NULL; - llvm::BasicBlock* b = irgen.GetBasicBlock(); + b = irgen.GetBasicBlock(); //austins additional value llvm::Value *val; if(!l || !r) { @@ -267,12 +291,6 @@ llvm::Value* CompoundExpr::Emit() { if(op->getToken() == ">") return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_SGT, l, r, "", b); } - if(op->getToken() == "&&") { - return llvm::BinaryOperator::Create(llvm::Instruction::And, l, r, "", b); - } - if(op->getToken() == "||") { - return llvm::BinaryOperator::Create(llvm::Instruction::Or, l, r, "", b); - } return NULL; } -- 1.9.1