aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGraydon Hoare <[email protected]>2010-11-26 17:47:27 -0800
committerGraydon Hoare <[email protected]>2010-11-26 17:47:27 -0800
commit7be7c23b6b5ead25529814ccdbc0101d6b6d7683 (patch)
tree2c9ebc1ddeea78f47ca398408ad2c57216f0aaad /src
parentLoad structural values through pointer before passing structs as args. (diff)
downloadrust-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/Makefile1
-rw-r--r--src/comp/middle/trans.rs39
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);