Permalink
Browse files

Fix invalid LLVM module from recursive procedure

  • Loading branch information...
nickg committed Dec 27, 2012
1 parent cb27343 commit 7c97446005fc23d782799d511f0268383c0b9122
Showing with 48 additions and 35 deletions.
  1. +29 −20 src/cgen.c
  2. +8 −14 test/regress/access1.vhd
  3. +10 −0 test/regress/gold/access1.txt
  4. +1 −1 test/regress/testlist.txt
View
@@ -2466,38 +2466,44 @@ static void cgen_case(tree_t t, cgen_ctx_t *ctx)
cgen_case_scalar(t, ctx);
}
+static void cgen_builtin_pcall(ident_t builtin, LLVMValueRef *args)
+{
+ if (icmp(builtin, "deallocate")) {
+ LLVMBuildFree(builder, args[0]);
+ // XXX: setting pointer to NULL broken until inout parameters work
+ //LLVMBuildStore(builder, LLVMConstNull(LLVMTypeOf(args[0])), args[0]);
+ }
+ else
+ fatal("cannot generate code for builtin %s", istr(builtin));
+}
+
static void cgen_pcall(tree_t t, cgen_ctx_t *ctx)
{
tree_t decl = tree_ref(t);
- const int nparams = tree_params(t);
- LLVMValueRef args[nparams + 1];
- cgen_call_args(t, args, ctx);
-
- // Final parameter to a procedure is its dynamic context
- args[nparams] = NULL;
-
const bool in_function =
(ctx->fdecl != NULL) && (tree_kind(ctx->fdecl) == T_FUNC_BODY);
+ const int nparams = tree_params(t);
+
ident_t builtin = tree_attr_str(decl, ident_new("builtin"));
- if (builtin != NULL) {
- if (icmp(builtin, "deallocate")) {
- LLVMBuildFree(builder, args[0]);
- // XXX: setting pointer to NULL broken until inout parameters work
- //LLVMBuildStore(builder, LLVMConstNull(LLVMTypeOf(args[0])), args[0]);
- }
- else
- fatal_at(tree_loc(t), "cannot generate code for builtin %s",
- istr(builtin));
- return;
- }
- if (tree_attr_int(decl, never_waits_i, 0) || in_function) {
+ if (tree_attr_int(decl, never_waits_i, 0) || in_function || builtin) {
// Simple case where the called procedure never waits so we can ignore
// the return value
+
+ LLVMValueRef args[nparams + 1];
+ cgen_call_args(t, args, ctx);
+
+ // Final parameter to a procedure is its dynamic context
args[nparams] = LLVMConstNull(llvm_void_ptr());
- LLVMBuildCall(builder, cgen_pdecl(decl), args, nparams + 1, "");
+
+ if (builtin != NULL)
+ cgen_builtin_pcall(builtin, args);
+ else {
+ // Regular procedure call
+ LLVMBuildCall(builder, cgen_pdecl(decl), args, nparams + 1, "");
+ }
}
else {
// Find the basic block to jump to when the procedure resumes
@@ -2515,7 +2521,10 @@ static void cgen_pcall(tree_t t, cgen_ctx_t *ctx)
LLVMValueRef context_ptr = LLVMBuildStructGEP(builder, ctx->state, 1, "");
LLVMBuildStore(builder, llvm_int32(it->state_num), state_ptr);
+ LLVMValueRef args[nparams + 1];
+ cgen_call_args(t, args, ctx);
args[nparams] = LLVMBuildLoad(builder, context_ptr, "context");
+
LLVMValueRef ret =
LLVMBuildCall(builder, cgen_pdecl(decl), args, nparams + 1, "");
View
@@ -22,13 +22,13 @@ architecture test of access1 is
return n;
end function;
- --procedure list_print(l : in list_ptr) is
- --begin
- -- if l /= null then
- -- report integer'image(l.all.value);
- -- list_print(l.all.link);
- -- end if;
- --end procedure;
+ procedure list_print(l : in list_ptr) is
+ begin
+ if l /= null then
+ report integer'image(l.all.value);
+ list_print(l.all.link);
+ end if;
+ end procedure;
signal p1_done : boolean := false;
@@ -60,13 +60,7 @@ begin
l := list_add(l, i);
end loop;
- --p := l;
- --while p /= null loop
- -- --report integer'image(p.value);
- -- p := p.link;
- --end loop;
-
- --list_print(l);
+ list_print(l);
--list_free(l);
wait;
@@ -0,0 +1,10 @@
+0ms+1: Report Note: 10
+0ms+1: Report Note: 9
+0ms+1: Report Note: 8
+0ms+1: Report Note: 7
+0ms+1: Report Note: 6
+0ms+1: Report Note: 5
+0ms+1: Report Note: 4
+0ms+1: Report Note: 3
+0ms+1: Report Note: 2
+0ms+1: Report Note: 1
@@ -77,4 +77,4 @@ driver2 normal
delay1 normal
record1 normal
proc3 normal
-access1 normal
+access1 normal,gold

0 comments on commit 7c97446

Please sign in to comment.