Skip to content

Instantly share code, notes, and snippets.

@fjolnir
Created June 28, 2012 06:13
Show Gist options
  • Save fjolnir/3009456 to your computer and use it in GitHub Desktop.
Save fjolnir/3009456 to your computer and use it in GitHub Desktop.
- (llvm::Value *)generateCodeInProgram:(TQProgram *)aProgram block:(TQNodeBlock *)aBlock error:(NSError **)aoErr
{
IRBuilder<> *builder = aBlock.builder;
Module *mod = aProgram.llModule;
// Pose as the parent block for the duration of code generation
self.function = aBlock.function;
self.autoreleasePool = aBlock.autoreleasePool;
Value *testExpr = [_condition generateCodeInProgram:aProgram block:aBlock error:aoErr];
if(*aoErr)
return NULL;
Value *testResult = builder->CreateICmpNE(testExpr, ConstantPointerNull::get(aProgram.llInt8PtrTy), "ifTest");
BOOL hasElse = (_elseBlockStatements.count > 0);
BasicBlock *thenBB = BasicBlock::Create(mod->getContext(), "then", aBlock.function);
IRBuilder<> *thenBuilder = NULL;
BasicBlock *elseBB = NULL;
IRBuilder<> *elseBuilder = NULL;
thenBuilder = new IRBuilder<>(thenBB);
self.basicBlock = thenBB;
self.builder = thenBuilder;
for(TQNode *stmt in self.statements) {
[stmt generateCodeInProgram:aProgram block:self error:aoErr];
if(*aoErr)
return NULL;
}
if(hasElse) {
elseBB = BasicBlock::Create(mod->getContext(), "else", aBlock.function);
elseBuilder = new IRBuilder<>(elseBB);
self.basicBlock = elseBB;
self.builder = elseBuilder;
for(TQNode *stmt in _elseBlockStatements) {
[stmt generateCodeInProgram:aProgram block:self error:aoErr];
if(*aoErr)
return NULL;
}
}
BasicBlock *endifBB = BasicBlock::Create(mod->getContext(), "endif", aBlock.function);
IRBuilder<> *endifBuilder = new IRBuilder<>(endifBB);
// If our basic block has been changed that means there was a nested conditional
// We need to fix it by adding a br pointing to the endif
if(self.basicBlock != thenBB && self.basicBlock != elseBB) {
BasicBlock *tailBlock = self.basicBlock;
IRBuilder<> *tailBuilder = self.builder;
if(!tailBlock->getTerminator())
tailBuilder->CreateBr(endifBB);
}
if(!thenBB->getTerminator())
thenBuilder->CreateBr(endifBB);
if(elseBB && !elseBB->getTerminator())
elseBuilder->CreateBr(endifBB);
delete thenBuilder;
delete elseBuilder;
builder->CreateCondBr(testResult, thenBB, elseBB ? elseBB : endifBB);
// Make the parent block continue from the end of the statement
aBlock.basicBlock = endifBB;
aBlock.builder = endifBuilder;
self.builder = NULL;
self.function = NULL;
return testResult;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment