diff options
| author | Graydon Hoare <[email protected]> | 2010-11-26 17:47:27 -0800 |
|---|---|---|
| committer | Graydon Hoare <[email protected]> | 2010-11-26 17:47:27 -0800 |
| commit | 7be7c23b6b5ead25529814ccdbc0101d6b6d7683 (patch) | |
| tree | 2c9ebc1ddeea78f47ca398408ad2c57216f0aaad /src | |
| parent | Load structural values through pointer before passing structs as args. (diff) | |
| download | rust-7be7c23b6b5ead25529814ccdbc0101d6b6d7683.tar.xz rust-7be7c23b6b5ead25529814ccdbc0101d6b6d7683.zip | |
Copy args to allocas, change llargs lookups to 'in mem'. Un-XFAIL tup.rs.
Diffstat (limited to 'src')
| -rw-r--r-- | src/Makefile | 1 | ||||
| -rw-r--r-- | src/comp/middle/trans.rs | 39 |
2 files changed, 36 insertions, 4 deletions
diff --git a/src/Makefile b/src/Makefile index 0a944ec3..c965f7b6 100644 --- a/src/Makefile +++ b/src/Makefile @@ -535,6 +535,7 @@ TEST_XFAILS_SELF := $(filter-out \ lazy-init.rs \ multiline-comment.rs \ return-nil.rs \ + tup.rs \ u32-decr.rs \ u8-incr.rs \ u8-incr-decr.rs \ diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 70d6d62f..2f078f04 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -1071,7 +1071,7 @@ fn trans_name(@block_ctxt cx, &ast.name n, &option.t[ast.def] dopt) case (ast.def_arg(?did)) { check (cx.fcx.llargs.contains_key(did)); ret tup(res(cx, cx.fcx.llargs.get(did)), - false); + true); } case (ast.def_local(?did)) { check (cx.fcx.lllocals.contains_key(did)); @@ -1521,15 +1521,46 @@ fn new_fn_ctxt(@crate_ctxt cx, ccx=cx); } + +// Recommended LLVM style, strange though this is, is to copy from args to +// allocas immediately upon entry; this permits us to GEP into structures we +// were passed and whatnot. Apparently mem2reg will mop up. + +fn copy_args_to_allocas(@block_ctxt cx, &ast._fn f, &ast.ann ann) { + + let vec[typeck.arg] arg_ts = vec(); + let @typeck.ty fty = node_ann_type(cx.fcx.ccx, ann); + alt (fty.struct) { + case (typeck.ty_fn(?a, _)) { arg_ts += a; } + } + + let uint arg_n = 0u; + + for (ast.arg aarg in f.inputs) { + auto arg = arg_ts.(arg_n); + auto arg_t = type_of(cx.fcx.ccx, arg.ty); + auto alloca = cx.build.Alloca(arg_t); + auto argval = cx.fcx.llargs.get(aarg.id); + cx.build.Store(argval, alloca); + // Overwrite the llargs entry for this arg with its alloca. + cx.fcx.llargs.insert(aarg.id, alloca); + arg_n += 1u; + } +} + fn is_terminated(@block_ctxt cx) -> bool { auto inst = llvm.LLVMGetLastInstruction(cx.llbb); ret llvm.LLVMIsATerminatorInst(inst) as int != 0; } -impure fn trans_fn(@crate_ctxt cx, &ast._fn f, ast.def_id fid) { +impure fn trans_fn(@crate_ctxt cx, &ast._fn f, ast.def_id fid, + &ast.ann ann) { auto fcx = new_fn_ctxt(cx, cx.path, f, fid); auto bcx = new_top_block_ctxt(fcx); + + copy_args_to_allocas(bcx, f, ann); + auto res = trans_block(bcx, f.body); if (!is_terminated(res.bcx)) { // FIXME: until LLVM has a unit type, we are moving around @@ -1540,9 +1571,9 @@ impure fn trans_fn(@crate_ctxt cx, &ast._fn f, ast.def_id fid) { impure fn trans_item(@crate_ctxt cx, &ast.item item) { alt (item.node) { - case (ast.item_fn(?name, ?f, _, ?fid, _)) { + case (ast.item_fn(?name, ?f, _, ?fid, ?ann)) { auto sub_cx = @rec(path=cx.path + "." + name with *cx); - trans_fn(sub_cx, f, fid); + trans_fn(sub_cx, f, fid, ann); } case (ast.item_mod(?name, ?m, _)) { auto sub_cx = @rec(path=cx.path + "." + name with *cx); |