Commit ebc2ecde2e455f49e58ba69cb88d8952cde643ab

Authored by Jeffrey Johnson
1 parent 43abbf6421
Exists in master

Ternary short circuiting

Showing 2 changed files with 23 additions and 6 deletions Side-by-side Diff

... ... @@ -72,7 +72,7 @@
72 72 llvm::Value* val;
73 73 if(b) {
74 74 val = new llvm::AllocaInst(convertType(type), id->GetName(), b);
75   - if(assignTo) new llvm::StoreInst(assignTo->Emit(), val, false, b);
  75 + if(assignTo) new llvm::StoreInst(assignTo->Emit(), val, false, irgen.GetBasicBlock());
76 76 }
77 77 else {
78 78 llvm::Constant* e = assignTo ? (llvm::Constant*)assignTo->Emit() : llvm::Constant::getNullValue(convertType(type));
... ... @@ -167,12 +167,29 @@
167 167 }
168 168  
169 169 llvm::Value* ConditionalExpr::Emit() {
  170 + llvm::LLVMContext * context = irgen.GetContext();
  171 + llvm::Function * func = irgen.GetFunction();
170 172 llvm::BasicBlock* b = irgen.GetBasicBlock();
171   - llvm::Value* t = trueExpr->Emit();
172   - llvm::Value* f = falseExpr->Emit();
173   - llvm::Value* c = cond->Emit();
  173 + llvm::BasicBlock * thenBlock = llvm::BasicBlock::Create(*context, "thenBlock", func);
  174 + llvm::BasicBlock * footBlock = llvm::BasicBlock::Create(*context, "footBlock", func);
  175 + llvm::BasicBlock * elseBlock = llvm::BasicBlock::Create(*context, "elseBlock", func);
  176 + llvm::Value * condition = cond->Emit();
174 177  
175   - return llvm::SelectInst::Create(c, t, f, "", b);
  178 + irgen.SetBasicBlock(thenBlock);
  179 + llvm::Value* tVal = trueExpr->Emit();
  180 + llvm::Value* val = new llvm::AllocaInst(tVal->getType(), "", b);
  181 + new llvm::StoreInst(tVal, val, false, irgen.GetBasicBlock());
  182 + llvm::BranchInst::Create(thenBlock, elseBlock, condition, b);
  183 +
  184 + llvm::BranchInst::Create(footBlock, irgen.GetBasicBlock());
  185 +
  186 + irgen.SetBasicBlock(elseBlock);
  187 + llvm::Value* fVal = falseExpr->Emit();
  188 + new llvm::StoreInst(fVal, val, false, irgen.GetBasicBlock());
  189 +
  190 + llvm::BranchInst::Create(footBlock, irgen.GetBasicBlock());
  191 + irgen.SetBasicBlock(footBlock);
  192 + return new llvm::LoadInst(val, "", footBlock);
176 193 }
177 194  
178 195 static llvm::Value* typeConvert(llvm::Value* val, llvm::Value* target) {