Skip to content

Commit 41f3f1d

Browse files
committed
Implementing while loops
1 parent ecf25ff commit 41f3f1d

File tree

2 files changed

+50
-27
lines changed

2 files changed

+50
-27
lines changed

codegenVis.cpp

Lines changed: 42 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ void CodeGenVisitor::visit(NIfExpression* element, uint64_t flag)
146146
{
147147
case V_FLAG_GUARD | V_FLAG_EXIT:
148148
{
149-
if (verbose) std::cout << "CodeGenVisitor if-guard-enter" << typeid(element).name() << std::endl;
149+
if (verbose) std::cout << "CodeGenVisitor if-guard-exit" << typeid(element).name() << std::endl;
150150
Value *CondV = vals.front();
151151
vals.pop_front(); // Pop guard
152152
if (CondV == NULL) {
@@ -199,52 +199,67 @@ void CodeGenVisitor::visit(NIfExpression* element, uint64_t flag)
199199
// No need to add anything to vals
200200
}
201201

202-
// TODO: Fix bug
203202
void CodeGenVisitor::visit(NWhileExpression* element, uint64_t flag)
204203
{
205204
switch (flag)
206205
{
207-
case V_FLAG_GUARD | V_FLAG_EXIT:
206+
case V_FLAG_GUARD | V_FLAG_ENTER:
208207
{
209208
if (verbose) std::cout << "CodeGenVisitor while-guard-enter" << typeid(element).name() << std::endl;
209+
While* myWhile = new While();
210+
whiles.push_front(myWhile);
211+
whiles.front()->function = Builder.GetInsertBlock()->getParent();
212+
// There will be three basic blocks:
213+
// 1) condBB ("while.cond")
214+
// perform the check for the loop condition. If true, branch to while.body, otherwise branch to while.end
215+
// 2) bodyBB ("while.body")
216+
// run the loop body then unconditionally branch to while.cond
217+
// 3) endBB ("while.end")
218+
// gets branched to from while.cond
219+
//
220+
// Note that initially there will be an unconditional branch to while.cond
221+
// to see if the loop need to be executed at least once,
222+
// or if the loop is to be skipped without executing at all
223+
whiles.front()->condBB = BasicBlock::Create(getGlobalContext(), "while.cond", whiles.front()->function);
224+
whiles.front()->bodyBB = BasicBlock::Create(getGlobalContext(), "while.body");
225+
whiles.front()->endBB = BasicBlock::Create(getGlobalContext(), "while.end");
226+
Builder.CreateBr(whiles.front()->condBB);
227+
Builder.SetInsertPoint(whiles.front()->condBB);
228+
}
229+
break;
230+
case V_FLAG_GUARD | V_FLAG_EXIT:
231+
{
232+
if (verbose) std::cout << "CodeGenVisitor while-guard-exit" << typeid(element).name() << std::endl;
233+
}
234+
break;
235+
case V_FLAG_THEN | V_FLAG_ENTER:
236+
{
237+
if (verbose) std::cout << "CodeGenVisitor body-enter " << typeid(element).name() << std::endl;
210238
Value *CondV = vals.front();
211-
//vals.pop_front(); // Pop guard
239+
vals.pop_front(); // Pop guard
212240
if (CondV == NULL) {
213241
assert(0);
214242
}
215-
If* myIf = new If();
216-
myIf->function = Builder.GetInsertBlock()->getParent();
217-
// Create blocks for the body of the loop and the fall through.
218-
myIf->thenBB = BasicBlock::Create(getGlobalContext(), "while.then", myIf->function);
219-
myIf->mergeBB = BasicBlock::Create(getGlobalContext(), "while.end");
220-
Builder.CreateCondBr(CondV, myIf->thenBB, myIf->mergeBB);
221-
ifs.push_front(myIf);
243+
Builder.CreateCondBr(CondV, whiles.front()->bodyBB, whiles.front()->endBB);
244+
whiles.front()->function->getBasicBlockList().push_back(whiles.front()->bodyBB);
245+
Builder.SetInsertPoint(whiles.front()->bodyBB);
222246
}
223247
break;
224-
case V_FLAG_THEN | V_FLAG_ENTER:
225-
if (verbose) std::cout << "CodeGenVisitor then-enter " << typeid(element).name() << std::endl;
226-
// Emit then block.
227-
Builder.SetInsertPoint(ifs.front()->thenBB);
228-
break;
229248
case V_FLAG_THEN | V_FLAG_EXIT:
230249
{
231-
if (verbose) std::cout << "CodeGenVisitor then-exit " << typeid(element).name() << std::endl;
232-
Value *CondV = vals.front();
233-
vals.pop_front(); // Pop guard
234-
Builder.CreateCondBr(CondV, ifs.front()->thenBB, ifs.front()->mergeBB);
235-
//Builder.CreateBr(ifs.front()->thenBB);
250+
if (verbose) std::cout << "CodeGenVisitor body-exit " << typeid(element).name() << std::endl;
251+
Builder.CreateBr(whiles.front()->condBB);
236252
}
237253
break;
238254
case V_FLAG_EXIT:
239255
if (verbose) std::cout << "CodeGenVisitor exit " << typeid(element).name() << std::endl;
240-
// Emit merge block.
241-
ifs.front()->function->getBasicBlockList().push_back(ifs.front()->mergeBB);
242-
Builder.SetInsertPoint(ifs.front()->mergeBB);
256+
whiles.front()->function->getBasicBlockList().push_back(whiles.front()->endBB);
257+
Builder.SetInsertPoint(whiles.front()->endBB);
243258
{
244-
If* myIf = ifs.front();
245-
delete myIf;
259+
While* myWhile = whiles.front();
260+
delete myWhile;
246261
}
247-
ifs.pop_front();
262+
whiles.pop_front();
248263
break;
249264
default:
250265
return;

codegenVis.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,21 @@ class CodeGenVisitor : public Visitor {
1717
llvm::BasicBlock *elseBB = NULL;
1818
llvm::BasicBlock *mergeBB = NULL;
1919
};
20+
class While {
21+
public:
22+
llvm::Function *function = NULL;
23+
llvm::BasicBlock *condBB = NULL;
24+
llvm::BasicBlock *bodyBB = NULL;
25+
llvm::BasicBlock *endBB = NULL;
26+
};
2027

2128
char* filename;
2229
bool verbose = false;
2330
llvm::Function *mainFunction;
2431
//llvm::IRBuilder<> *Builder = NULL;
2532
std::list<llvm::Value*> vals;
2633
std::list<If*> ifs;
34+
std::list<While*> whiles;
2735

2836
class CodeGenContext {
2937
public:

0 commit comments

Comments
 (0)