Commit 43abbf64217a7ff4de3f1cb28bcbc511e0a9e9e0

Authored by Jeffrey Johnson
1 parent 9399459476
Exists in master

Short circuit && and ||

Showing 1 changed file with 26 additions and 8 deletions Side-by-side Diff

... ... @@ -187,11 +187,35 @@
187 187 return ret;
188 188 }
189 189  
190   -// TODO ++ and -- on vectors?
191 190 llvm::Value* CompoundExpr::Emit() {
  191 + llvm::BasicBlock* b = irgen.GetBasicBlock();
  192 + llvm::Function * func = irgen.GetFunction();
  193 + llvm::LLVMContext* context = irgen.GetContext();
  194 + //weird bc of short circuting
  195 + if(op->getToken() == "&&" || op->getToken() == "||") {
  196 + llvm::Value* val = new llvm::AllocaInst(llvm::Type::getInt1Ty(*context), "", b);
  197 + llvm::BasicBlock * otherBlock = llvm::BasicBlock::Create(*context, "otherBlock", func);
  198 + llvm::BasicBlock * falseBlock = llvm::BasicBlock::Create(*context, "falseBlock", func);
  199 + llvm::BasicBlock * trueBlock = llvm::BasicBlock::Create(*context, "trueBlock", func);
  200 + llvm::BasicBlock * footBlock = llvm::BasicBlock::Create(*context, "footBlock", func);
  201 + llvm::Value* l = left->Emit();
  202 + b = irgen.GetBasicBlock();
  203 + if(op->getToken() == "&&") llvm::BranchInst::Create(otherBlock, falseBlock, l, b);
  204 + if(op->getToken() == "||") llvm::BranchInst::Create(trueBlock, otherBlock, l, b);
  205 + irgen.SetBasicBlock(otherBlock);
  206 + llvm::Value* r = right->Emit();
  207 + b = irgen.GetBasicBlock();
  208 + llvm::BranchInst::Create(trueBlock, falseBlock, r, b);
  209 + new llvm::StoreInst(llvm::ConstantInt::get(llvm::Type::getInt1Ty(*context), true), val, false, trueBlock);
  210 + llvm::BranchInst::Create(footBlock, trueBlock);
  211 + new llvm::StoreInst(llvm::ConstantInt::get(llvm::Type::getInt1Ty(*context), false), val, false, falseBlock);
  212 + llvm::BranchInst::Create(footBlock, falseBlock);
  213 + irgen.SetBasicBlock(footBlock);
  214 + return new llvm::LoadInst(val, "", footBlock);
  215 + }
192 216 llvm::Value* l = left ? left->Emit() : NULL;
193 217 llvm::Value* r = right ? right->Emit() : NULL;
194   - llvm::BasicBlock* b = irgen.GetBasicBlock();
  218 + b = irgen.GetBasicBlock();
195 219 //austins additional value
196 220 llvm::Value *val;
197 221 if(!l || !r) {
... ... @@ -266,12 +290,6 @@
266 290 return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_SLT, l, r, "", b);
267 291 if(op->getToken() == ">")
268 292 return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_SGT, l, r, "", b);
269   - }
270   - if(op->getToken() == "&&") {
271   - return llvm::BinaryOperator::Create(llvm::Instruction::And, l, r, "", b);
272   - }
273   - if(op->getToken() == "||") {
274   - return llvm::BinaryOperator::Create(llvm::Instruction::Or, l, r, "", b);
275 293 }
276 294 return NULL;
277 295 }