Commit 43abbf64217a7ff4de3f1cb28bcbc511e0a9e9e0
1 parent
9399459476
Exists in
master
Short circuit && and ||
Showing 1 changed file with 26 additions and 8 deletions Side-by-side Diff
ast_expr.cc
View file @
43abbf6
... | ... | @@ -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 | } |