Skip to content

Commit

Permalink
support references for end-values
Browse files Browse the repository at this point in the history
  • Loading branch information
mhasel committed Jun 17, 2024
1 parent 3043033 commit bc599cf
Show file tree
Hide file tree
Showing 12 changed files with 215 additions and 124 deletions.
108 changes: 73 additions & 35 deletions src/codegen/generators/statement_generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -391,63 +391,101 @@ impl<'a, 'b> StatementCodeGenerator<'a, 'b> {
let (builder, current_function, context) = self.get_llvm_deps();
let exp_gen = self.create_expr_generator();
self.generate_assignment_statement(counter, start)?;
let predicate_incrementing = context.append_basic_block(current_function, "predicate_inc");
let predicate_decrementing = context.append_basic_block(current_function, "predicate_dec");
let loop_body = context.append_basic_block(current_function, "loop");
let afterloop = context.append_basic_block(current_function, "continue");

let counter = exp_gen.generate_lvalue(counter)?;
let end = exp_gen.generate_expression(end)?;
let counter_value = builder.build_load(counter, "");

let by_step = by_step.as_ref().map_or_else(
|| self.llvm.create_const_numeric(&counter_value.get_type(), "1", SourceLocation::undefined()),
|step| {
self.register_debug_location(step);
exp_gen.generate_expression(step)
},
)?;
// let predicate_select = context.append_basic_block(current_function, "predicate_select");
let predicate_incrementing = context.append_basic_block(current_function, "predicate_sle");
let predicate_decrementing = context.append_basic_block(current_function, "predicate_sge");
let loop_body = context.append_basic_block(current_function, "loop");
let increment = context.append_basic_block(current_function, "increment");
let afterloop = context.append_basic_block(current_function, "continue");

// XXX(mhasel): could the generated IR be improved by using phi instructions?
// select loop predicate
let is_incrementing = builder.build_int_compare(
inkwell::IntPredicate::SGT,
by_step.into_int_value(),
self.llvm.i32_type().const_zero(),
"is_incrementing",
);

// --check loop predicate--
builder.build_conditional_branch(is_incrementing, predicate_incrementing, predicate_decrementing);
// --incrementing loops--
builder.position_at_end(predicate_incrementing);
let value = builder.build_load(counter, "");
let inc_cmp = builder.build_int_compare(
inkwell::IntPredicate::SLE,
value.into_int_value(),
end.into_int_value(),
"condition",
);
builder.build_conditional_branch(inc_cmp, loop_body, afterloop);
// --decrementing loops--
builder.position_at_end(predicate_decrementing);
let value = builder.build_load(counter, "");
let dec_cmp = builder.build_int_compare(
inkwell::IntPredicate::SGE,
value.into_int_value(),
end.into_int_value(),
"condition",
);
builder.build_conditional_branch(dec_cmp, loop_body, afterloop);

// --body--
let end = exp_gen.generate_expression_value(end)?;
let generate_predicate = |predicate| {
builder.position_at_end(
match predicate {
inkwell::IntPredicate::SLE => predicate_incrementing,
inkwell::IntPredicate::SGE => predicate_decrementing,
_ => unreachable!()
}
);
let end_value = match end {
super::expression_generator::ExpressionValue::LValue(ptr) => builder.build_load(ptr ,""),
super::expression_generator::ExpressionValue::RValue(val) => val,
};
let counter_value = builder.build_load(counter, "");
let cmp = builder.build_int_compare(
predicate,
counter_value.into_int_value(),
end_value.into_int_value(),
"condition",
);
builder.build_conditional_branch(cmp, loop_body, afterloop);
};
generate_predicate(inkwell::IntPredicate::SLE);
generate_predicate(inkwell::IntPredicate::SGE);
// // incrementing loop predicate
// builder.position_at_end(predicate_incrementing);
// let counter_value = builder.build_load(counter, "");
// let end_value = builder.build_load(end ,"");
// let inc_cmp = builder.build_int_compare(
// inkwell::IntPredicate::SLE,
// counter_value.into_int_value(),
// end_value.into_int_value(),
// "condition",
// );
// builder.build_conditional_branch(inc_cmp, loop_body, afterloop);

// // decrementing loop predicate
// builder.position_at_end(predicate_decrementing);
// let counter_value = builder.build_load(counter, "");
// let end_value = builder.build_load(end ,"");
// let dec_cmp = builder.build_int_compare(
// inkwell::IntPredicate::SGE,
// counter_value.into_int_value(),
// end_value.into_int_value(),
// "condition",
// );
// builder.build_conditional_branch(dec_cmp, loop_body, afterloop);

// loop body
builder.position_at_end(loop_body);
self.generate_body(body)?;
let body_builder = StatementCodeGenerator {
current_loop_continue: Some(increment),
current_loop_exit: Some(afterloop),
load_prefix: self.load_prefix.clone(),
load_suffix: self.load_suffix.clone(),
..*self
};
body_builder.generate_body(body)?;

// --increment--
builder.build_unconditional_branch(increment);
builder.position_at_end(increment);
let value = builder.build_load(counter, "");
let inc = builder.build_int_add(value.into_int_value(), by_step.into_int_value(), "increment");
let inc = builder.build_int_add(value.into_int_value(), by_step.into_int_value(), "next");
builder.build_store(counter, inc);
//--check condition again--
// builder.build_phi(self.llvm.i32_type(), "phi");

// check condition
builder.build_conditional_branch(is_incrementing, predicate_incrementing, predicate_decrementing);
// --continue--
// continue
builder.position_at_end(afterloop);
Ok(())
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,26 +12,29 @@ entry:
store i32 0, i32* %myFunc, align 4, !dbg !8
store i32 1, i32* %myFunc, align 4, !dbg !12
%0 = load i32, i32* %myFunc, align 4, !dbg !12
br i1 true, label %predicate_inc, label %predicate_dec, !dbg !13
br i1 true, label %predicate_sle, label %predicate_sge, !dbg !13

predicate_inc: ; preds = %loop, %entry
predicate_sle: ; preds = %increment, %entry
%1 = load i32, i32* %myFunc, align 4, !dbg !13
%condition = icmp sle i32 %1, 20, !dbg !13
br i1 %condition, label %loop, label %continue, !dbg !13

predicate_dec: ; preds = %loop, %entry
predicate_sge: ; preds = %increment, %entry
%2 = load i32, i32* %myFunc, align 4, !dbg !13
%condition1 = icmp sge i32 %2, 20, !dbg !13
br i1 %condition1, label %loop, label %continue, !dbg !13

loop: ; preds = %predicate_dec, %predicate_inc
loop: ; preds = %predicate_sge, %predicate_sle
store i32 1, i32* %myFunc, align 4, !dbg !14
br label %increment, !dbg !14

increment: ; preds = %loop
%3 = load i32, i32* %myFunc, align 4, !dbg !14
%increment = add i32 %3, 2, !dbg !14
store i32 %increment, i32* %myFunc, align 4, !dbg !14
br i1 true, label %predicate_inc, label %predicate_dec, !dbg !14
%next = add i32 %3, 2, !dbg !14
store i32 %next, i32* %myFunc, align 4, !dbg !14
br i1 true, label %predicate_sle, label %predicate_sge, !dbg !14

continue: ; preds = %predicate_dec, %predicate_inc
continue: ; preds = %predicate_sge, %predicate_sle
%myFunc_ret = load i32, i32* %myFunc, align 4, !dbg !14
ret i32 %myFunc_ret, !dbg !14
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,25 +14,28 @@ entry:
%x = getelementptr inbounds %prg, %prg* %0, i32 0, i32 0
store i32 3, i32* %x, align 4
%1 = load i32, i32* %x, align 4
br i1 true, label %predicate_inc, label %predicate_dec
br i1 true, label %predicate_sle, label %predicate_sge

predicate_inc: ; preds = %loop, %entry
predicate_sle: ; preds = %increment, %entry
%2 = load i32, i32* %x, align 4
%condition = icmp sle i32 %2, 10
br i1 %condition, label %loop, label %continue

predicate_dec: ; preds = %loop, %entry
predicate_sge: ; preds = %increment, %entry
%3 = load i32, i32* %x, align 4
%condition1 = icmp sge i32 %3, 10
br i1 %condition1, label %loop, label %continue

loop: ; preds = %predicate_dec, %predicate_inc
loop: ; preds = %predicate_sge, %predicate_sle
br label %increment

increment: ; preds = %loop
%4 = load i32, i32* %x, align 4
%increment = add i32 %4, 1
store i32 %increment, i32* %x, align 4
br i1 true, label %predicate_inc, label %predicate_dec
%next = add i32 %4, 1
store i32 %next, i32* %x, align 4
br i1 true, label %predicate_sle, label %predicate_sge

continue: ; preds = %predicate_dec, %predicate_inc
continue: ; preds = %predicate_sge, %predicate_sle
%load_x = load i32, i32* %x, align 4
ret void
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,25 +14,28 @@ entry:
%x = getelementptr inbounds %prg, %prg* %0, i32 0, i32 0
store i16 3, i16* %x, align 2
%1 = load i16, i16* %x, align 2
br i1 true, label %predicate_inc, label %predicate_dec
br i1 true, label %predicate_sle, label %predicate_sge

predicate_inc: ; preds = %loop, %entry
predicate_sle: ; preds = %increment, %entry
%2 = load i16, i16* %x, align 2
%condition = icmp sle i16 %2, 10
br i1 %condition, label %loop, label %continue

predicate_dec: ; preds = %loop, %entry
predicate_sge: ; preds = %increment, %entry
%3 = load i16, i16* %x, align 2
%condition1 = icmp sge i16 %3, 10
br i1 %condition1, label %loop, label %continue

loop: ; preds = %predicate_dec, %predicate_inc
loop: ; preds = %predicate_sge, %predicate_sle
%load_x = load i16, i16* %x, align 2
br label %increment

increment: ; preds = %loop
%4 = load i16, i16* %x, align 2
%increment = add i16 %4, 1
store i16 %increment, i16* %x, align 2
br i1 true, label %predicate_inc, label %predicate_dec
%next = add i16 %4, 1
store i16 %next, i16* %x, align 2
br i1 true, label %predicate_sle, label %predicate_sge

continue: ; preds = %predicate_dec, %predicate_inc
continue: ; preds = %predicate_sge, %predicate_sle
ret void
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,25 +14,28 @@ entry:
%x = getelementptr inbounds %prg, %prg* %0, i32 0, i32 0
store i64 3, i64* %x, align 4
%1 = load i64, i64* %x, align 4
br i1 true, label %predicate_inc, label %predicate_dec
br i1 true, label %predicate_sle, label %predicate_sge

predicate_inc: ; preds = %loop, %entry
predicate_sle: ; preds = %increment, %entry
%2 = load i64, i64* %x, align 4
%condition = icmp sle i64 %2, 10
br i1 %condition, label %loop, label %continue

predicate_dec: ; preds = %loop, %entry
predicate_sge: ; preds = %increment, %entry
%3 = load i64, i64* %x, align 4
%condition1 = icmp sge i64 %3, 10
br i1 %condition1, label %loop, label %continue

loop: ; preds = %predicate_dec, %predicate_inc
loop: ; preds = %predicate_sge, %predicate_sle
%load_x = load i64, i64* %x, align 4
br label %increment

increment: ; preds = %loop
%4 = load i64, i64* %x, align 4
%increment = add i64 %4, 1
store i64 %increment, i64* %x, align 4
br i1 true, label %predicate_inc, label %predicate_dec
%next = add i64 %4, 1
store i64 %next, i64* %x, align 4
br i1 true, label %predicate_sle, label %predicate_sge

continue: ; preds = %predicate_dec, %predicate_inc
continue: ; preds = %predicate_sge, %predicate_sle
ret void
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,25 +14,28 @@ entry:
%x = getelementptr inbounds %prg, %prg* %0, i32 0, i32 0
store i8 3, i8* %x, align 1
%1 = load i8, i8* %x, align 1
br i1 true, label %predicate_inc, label %predicate_dec
br i1 true, label %predicate_sle, label %predicate_sge

predicate_inc: ; preds = %loop, %entry
predicate_sle: ; preds = %increment, %entry
%2 = load i8, i8* %x, align 1
%condition = icmp sle i8 %2, 10
br i1 %condition, label %loop, label %continue

predicate_dec: ; preds = %loop, %entry
predicate_sge: ; preds = %increment, %entry
%3 = load i8, i8* %x, align 1
%condition1 = icmp sge i8 %3, 10
br i1 %condition1, label %loop, label %continue

loop: ; preds = %predicate_dec, %predicate_inc
loop: ; preds = %predicate_sge, %predicate_sle
%load_x = load i8, i8* %x, align 1
br label %increment

increment: ; preds = %loop
%4 = load i8, i8* %x, align 1
%increment = add i8 %4, 1
store i8 %increment, i8* %x, align 1
br i1 true, label %predicate_inc, label %predicate_dec
%next = add i8 %4, 1
store i8 %next, i8* %x, align 1
br i1 true, label %predicate_sle, label %predicate_sge

continue: ; preds = %predicate_dec, %predicate_inc
continue: ; preds = %predicate_sge, %predicate_sle
ret void
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,34 +14,36 @@ entry:
%x = getelementptr inbounds %prg, %prg* %0, i32 0, i32 0
store i32 3, i32* %x, align 4
%1 = load i32, i32* %x, align 4
%is_incrementing = icmp sgt i32 %1, 0
br i1 %is_incrementing, label %predicate_inc, label %predicate_dec
br i1 true, label %predicate_sle, label %predicate_sge

predicate_inc: ; preds = %buffer_block, %loop, %entry
predicate_sle: ; preds = %increment, %entry
%2 = load i32, i32* %x, align 4
%condition = icmp sle i32 %2, 10
br i1 %condition, label %loop, label %continue

predicate_dec: ; preds = %buffer_block, %entry
predicate_sge: ; preds = %increment, %entry
%3 = load i32, i32* %x, align 4
%condition1 = icmp sge i32 %3, 10
br i1 %condition1, label %loop, label %continue

loop: ; preds = %predicate_dec, %predicate_inc
loop: ; preds = %predicate_sge, %predicate_sle
%load_x = load i32, i32* %x, align 4
%tmpVar = add i32 %load_x, 1
store i32 %tmpVar, i32* %x, align 4
br label %predicate_inc
br label %increment

buffer_block: ; No predecessors!
%load_x2 = load i32, i32* %x, align 4
%tmpVar3 = sub i32 %load_x2, 1
store i32 %tmpVar3, i32* %x, align 4
br label %increment

increment: ; preds = %buffer_block, %loop
%4 = load i32, i32* %x, align 4
%increment = add i32 %4, 7
store i32 %increment, i32* %x, align 4
br i1 %is_incrementing, label %predicate_inc, label %predicate_dec
%next = add i32 %4, 7
store i32 %next, i32* %x, align 4
br i1 true, label %predicate_sle, label %predicate_sge

continue: ; preds = %predicate_dec, %predicate_inc
continue: ; preds = %predicate_sge, %predicate_sle
ret void
}
Loading

0 comments on commit bc599cf

Please sign in to comment.