Implement tuple access for LLVM.
This involved adding an Ast.ty return to trans_lval. I also included the code for record and box access, but their tests don't completely pass yet.
This commit is contained in:
parent
c070c11248
commit
09885b5b87
2 changed files with 77 additions and 21 deletions
|
@ -477,7 +477,6 @@ TEST_XFAILS_LLVM := $(addprefix test/run-pass/, \
|
||||||
task-comm-4.rs \
|
task-comm-4.rs \
|
||||||
task-comm-5.rs \
|
task-comm-5.rs \
|
||||||
threads.rs \
|
threads.rs \
|
||||||
tup.rs \
|
|
||||||
type-sizes.rs \
|
type-sizes.rs \
|
||||||
unit.rs \
|
unit.rs \
|
||||||
use-import-export.rs \
|
use-import-export.rs \
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
*)
|
*)
|
||||||
|
|
||||||
open Common;;
|
open Common;;
|
||||||
|
open Semant;;
|
||||||
open Transutil;;
|
open Transutil;;
|
||||||
|
|
||||||
let log cx = Session.log "trans"
|
let log cx = Session.log "trans"
|
||||||
|
@ -549,6 +550,37 @@ let trans_crate
|
||||||
end
|
end
|
||||||
in
|
in
|
||||||
|
|
||||||
|
(* Dereferences the box referred to by ptr, whose type is ty. Looks
|
||||||
|
straight through all mutable and constrained-type boxes, and loads
|
||||||
|
pointers per dctrl. Returns the dereferenced value and its type. *)
|
||||||
|
let rec deref_ty
|
||||||
|
(llbuilder:Llvm.llbuilder) (dctrl:deref_ctrl)
|
||||||
|
(ptr:Llvm.llvalue) (ty:Ast.ty)
|
||||||
|
: (Llvm.llvalue * Ast.ty) =
|
||||||
|
match (ty, dctrl) with
|
||||||
|
|
||||||
|
| (Ast.TY_mutable ty, _)
|
||||||
|
| (Ast.TY_constrained (ty, _), _) ->
|
||||||
|
deref_ty llbuilder dctrl ptr ty
|
||||||
|
|
||||||
|
| (Ast.TY_box ty', DEREF_one_box)
|
||||||
|
| (Ast.TY_box ty', DEREF_all_boxes) ->
|
||||||
|
let content =
|
||||||
|
Llvm.build_load
|
||||||
|
(get_element_ptr llbuilder ptr (Abi.box_rc_field_body))
|
||||||
|
(anon_llid "deref") llbuilder
|
||||||
|
in
|
||||||
|
let inner_dctrl =
|
||||||
|
if dctrl = DEREF_one_box
|
||||||
|
then DEREF_none
|
||||||
|
else DEREF_all_boxes
|
||||||
|
in
|
||||||
|
(* Possibly deref recursively. *)
|
||||||
|
deref_ty llbuilder inner_dctrl content ty'
|
||||||
|
|
||||||
|
| _ -> (ptr, ty)
|
||||||
|
in
|
||||||
|
|
||||||
let (llitems:(node_id, Llvm.llvalue) Hashtbl.t) = Hashtbl.create 0 in
|
let (llitems:(node_id, Llvm.llvalue) Hashtbl.t) = Hashtbl.create 0 in
|
||||||
(* Maps a fn's or block's id to an LLVM metadata node (subprogram or
|
(* Maps a fn's or block's id to an LLVM metadata node (subprogram or
|
||||||
lexical block) representing it. *)
|
lexical block) representing it. *)
|
||||||
|
@ -724,28 +756,52 @@ let trans_crate
|
||||||
|
|
||||||
(* Translates an lval by reference into the appropriate pointer
|
(* Translates an lval by reference into the appropriate pointer
|
||||||
* value. *)
|
* value. *)
|
||||||
let trans_lval (lval:Ast.lval) : Llvm.llvalue =
|
let rec trans_lval (lval:Ast.lval) : (Llvm.llvalue * Ast.ty) =
|
||||||
iflog (fun _ -> log sem_cx "trans_lval: %a" Ast.sprintf_lval lval);
|
iflog (fun _ -> log sem_cx "trans_lval: %a" Ast.sprintf_lval lval);
|
||||||
match lval with
|
match lval with
|
||||||
Ast.LVAL_base { id = base_id } ->
|
Ast.LVAL_base { id = base_id } ->
|
||||||
set_debug_loc base_id;
|
set_debug_loc base_id;
|
||||||
let id =
|
let referent = lval_to_referent sem_cx base_id in
|
||||||
Hashtbl.find sem_cx.Semant.ctxt_lval_to_referent base_id
|
|
||||||
in
|
|
||||||
let referent = Hashtbl.find sem_cx.Semant.ctxt_all_defns id in
|
|
||||||
begin
|
begin
|
||||||
match referent with
|
match resolve_lval_id sem_cx base_id with
|
||||||
Semant.DEFN_slot _ -> Hashtbl.find slot_to_llvalue id
|
Semant.DEFN_slot slot ->
|
||||||
| Semant.DEFN_item _ -> Hashtbl.find llitems id
|
(Hashtbl.find slot_to_llvalue referent, slot_ty slot)
|
||||||
|
| Semant.DEFN_item _ ->
|
||||||
|
(Hashtbl.find llitems referent, lval_ty sem_cx lval)
|
||||||
| _ ->
|
| _ ->
|
||||||
Common.unimpl (Some id)
|
Common.unimpl (Some referent)
|
||||||
"LLVM base-referent translation of: %a"
|
"LLVM base-referent translation of: %a"
|
||||||
Ast.sprintf_lval lval
|
Ast.sprintf_lval lval
|
||||||
end
|
end
|
||||||
| Ast.LVAL_ext _ ->
|
| Ast.LVAL_ext (base, component) ->
|
||||||
Common.unimpl (Some (Semant.lval_base_id lval))
|
let (llbase, base_ty) = trans_lval base in
|
||||||
"LLVM lval translation of: %a"
|
let base_ty = strip_mutable_or_constrained_ty base_ty in
|
||||||
Ast.sprintf_lval lval
|
(*
|
||||||
|
* All lval components aside from explicit-deref just
|
||||||
|
* auto-deref through all boxes to find their indexable
|
||||||
|
* referent.
|
||||||
|
*)
|
||||||
|
let (llbase, base_ty) =
|
||||||
|
if component = Ast.COMP_deref
|
||||||
|
then (llbase, base_ty)
|
||||||
|
else deref_ty llbuilder DEREF_all_boxes llbase base_ty
|
||||||
|
in
|
||||||
|
match (base_ty, component) with
|
||||||
|
(Ast.TY_rec entries,
|
||||||
|
Ast.COMP_named (Ast.COMP_ident id)) ->
|
||||||
|
let i = arr_idx (Array.map fst entries) id in
|
||||||
|
(get_element_ptr llbuilder llbase i, snd entries.(i))
|
||||||
|
|
||||||
|
| (Ast.TY_tup entries,
|
||||||
|
Ast.COMP_named (Ast.COMP_idx i)) ->
|
||||||
|
(get_element_ptr llbuilder llbase i, entries.(i))
|
||||||
|
|
||||||
|
| (Ast.TY_box _, Ast.COMP_deref) ->
|
||||||
|
deref_ty llbuilder DEREF_one_box llbase base_ty
|
||||||
|
|
||||||
|
| _ -> (Common.unimpl (Some (Semant.lval_base_id lval))
|
||||||
|
"LLVM lval translation of: %a"
|
||||||
|
Ast.sprintf_lval lval)
|
||||||
in
|
in
|
||||||
|
|
||||||
let trans_atom (atom:Ast.atom) : Llvm.llvalue =
|
let trans_atom (atom:Ast.atom) : Llvm.llvalue =
|
||||||
|
@ -753,7 +809,8 @@ let trans_crate
|
||||||
match atom with
|
match atom with
|
||||||
Ast.ATOM_literal { node = lit } -> trans_literal lit
|
Ast.ATOM_literal { node = lit } -> trans_literal lit
|
||||||
| Ast.ATOM_lval lval ->
|
| Ast.ATOM_lval lval ->
|
||||||
Llvm.build_load (trans_lval lval) (anon_llid "tmp") llbuilder
|
Llvm.build_load (fst (trans_lval lval)) (anon_llid "tmp")
|
||||||
|
llbuilder
|
||||||
in
|
in
|
||||||
|
|
||||||
let build_binop (op:Ast.binop) (lllhs:Llvm.llvalue) (llrhs:Llvm.llvalue)
|
let build_binop (op:Ast.binop) (lllhs:Llvm.llvalue) (llrhs:Llvm.llvalue)
|
||||||
|
@ -867,7 +924,7 @@ let trans_crate
|
||||||
match head.node with
|
match head.node with
|
||||||
Ast.STMT_init_tup (dest, elems) ->
|
Ast.STMT_init_tup (dest, elems) ->
|
||||||
let zero = const_i32 0 in
|
let zero = const_i32 0 in
|
||||||
let lldest = trans_lval dest in
|
let (lldest, _) = trans_lval dest in
|
||||||
let trans_tup_elem idx (_, atom) =
|
let trans_tup_elem idx (_, atom) =
|
||||||
let indices = [| zero; const_i32 idx |] in
|
let indices = [| zero; const_i32 idx |] in
|
||||||
let gep_id = anon_llid "init_tup_gep" in
|
let gep_id = anon_llid "init_tup_gep" in
|
||||||
|
@ -881,12 +938,12 @@ let trans_crate
|
||||||
|
|
||||||
| Ast.STMT_copy (dest, src) ->
|
| Ast.STMT_copy (dest, src) ->
|
||||||
let llsrc = trans_expr src in
|
let llsrc = trans_expr src in
|
||||||
let lldest = trans_lval dest in
|
let (lldest, _) = trans_lval dest in
|
||||||
ignore (Llvm.build_store llsrc lldest llbuilder);
|
ignore (Llvm.build_store llsrc lldest llbuilder);
|
||||||
trans_tail ()
|
trans_tail ()
|
||||||
|
|
||||||
| Ast.STMT_copy_binop (dest, op, src) ->
|
| Ast.STMT_copy_binop (dest, op, src) ->
|
||||||
let lldest = trans_lval dest in
|
let (lldest, _) = trans_lval dest in
|
||||||
let llsrc = trans_atom src in
|
let llsrc = trans_atom src in
|
||||||
(* FIXME: Handle vecs and strs. *)
|
(* FIXME: Handle vecs and strs. *)
|
||||||
let lldest_deref =
|
let lldest_deref =
|
||||||
|
@ -898,8 +955,8 @@ let trans_crate
|
||||||
|
|
||||||
| Ast.STMT_call (dest, fn, args) ->
|
| Ast.STMT_call (dest, fn, args) ->
|
||||||
let llargs = Array.map trans_atom args in
|
let llargs = Array.map trans_atom args in
|
||||||
let lldest = trans_lval dest in
|
let (lldest, _) = trans_lval dest in
|
||||||
let llfn = trans_lval fn in
|
let (llfn, _) = trans_lval fn in
|
||||||
let llallargs = Array.append [| lldest; lltask |] llargs in
|
let llallargs = Array.append [| lldest; lltask |] llargs in
|
||||||
let llrv = build_call llfn llallargs "" llbuilder in
|
let llrv = build_call llfn llallargs "" llbuilder in
|
||||||
Llvm.set_instruction_call_conv Llvm.CallConv.c llrv;
|
Llvm.set_instruction_call_conv Llvm.CallConv.c llrv;
|
||||||
|
@ -966,7 +1023,7 @@ let trans_crate
|
||||||
trans_tail_with_builder llokbuilder
|
trans_tail_with_builder llokbuilder
|
||||||
|
|
||||||
| Ast.STMT_init_str (dst, str) ->
|
| Ast.STMT_init_str (dst, str) ->
|
||||||
let d = trans_lval dst in
|
let (d, _) = trans_lval dst in
|
||||||
let s = static_str str in
|
let s = static_str str in
|
||||||
let len =
|
let len =
|
||||||
Llvm.const_int word_ty ((String.length str) + 1)
|
Llvm.const_int word_ty ((String.length str) + 1)
|
||||||
|
|
Loading…
Add table
Reference in a new issue