diff options
| author | Or Brostovski <[email protected]> | 2010-08-07 16:43:08 +0300 |
|---|---|---|
| committer | Or Brostovski <[email protected]> | 2010-08-07 16:43:08 +0300 |
| commit | 4467d7683dae87d6d4c55e446910f7a5b85abd13 (patch) | |
| tree | e2578dbe8e2350eb4e82ae2941fc2efb7478253b /src/boot | |
| parent | Added AST pretty printing for communication alt statement, closes issue 19. (diff) | |
| parent | Add Or to the AUTHORS file. (diff) | |
| download | rust-4467d7683dae87d6d4c55e446910f7a5b85abd13.tar.xz rust-4467d7683dae87d6d4c55e446910f7a5b85abd13.zip | |
Merge branch 'master' of git://github.com/graydon/rust
Conflicts:
src/boot/fe/ast.ml
Diffstat (limited to 'src/boot')
| -rw-r--r-- | src/boot/be/il.ml | 4 | ||||
| -rw-r--r-- | src/boot/be/x86.ml | 61 | ||||
| -rw-r--r-- | src/boot/fe/item.ml | 5 | ||||
| -rw-r--r-- | src/boot/fe/pexp.ml | 50 | ||||
| -rw-r--r-- | src/boot/llvm/lltrans.ml | 39 | ||||
| -rw-r--r-- | src/boot/me/trans.ml | 59 | ||||
| -rw-r--r-- | src/boot/me/type.ml | 9 |
7 files changed, 149 insertions, 78 deletions
diff --git a/src/boot/be/il.ml b/src/boot/be/il.ml index 792e83e2..172d8661 100644 --- a/src/boot/be/il.ml +++ b/src/boot/be/il.ml @@ -695,7 +695,7 @@ type emitter = { mutable emit_pc: int; emit_target_specific: (emitter -> quad -> unit); mutable emit_quads: quads; emit_annotations: (int,string) Hashtbl.t; - emit_size_cache: ((size,operand) Hashtbl.t) Stack.t; + emit_size_cache: (size,operand) Hashtbl.t; emit_node: node_id option; } @@ -722,7 +722,7 @@ let new_emitter emit_target_specific = emit_target_specific; emit_quads = Array.create 4 badq; emit_annotations = Hashtbl.create 0; - emit_size_cache = Stack.create (); + emit_size_cache = Hashtbl.create 0; emit_node = node; } ;; diff --git a/src/boot/be/x86.ml b/src/boot/be/x86.ml index 217149c7..55b101bb 100644 --- a/src/boot/be/x86.ml +++ b/src/boot/be/x86.ml @@ -302,11 +302,41 @@ let emit_target_specific | Il.IMOD | Il.UMOD -> let dst_eax = hr_like_cell eax dst in let lhs_eax = hr_like_op eax lhs in - let rhs_ecx = hr_like_op ecx lhs in - if lhs <> (Il.Cell lhs_eax) - then mov lhs_eax lhs; - if rhs <> (Il.Cell rhs_ecx) - then mov rhs_ecx rhs; + let rhs_ecx = hr_like_op ecx rhs in + (* Horrible: we bounce complex mul inputs off spill slots + * to ensure non-interference between the temporaries used + * during mem-base-reg reloads and the registers we're + * preparing. *) + let next_spill_like op = + Il.Mem (Il.next_spill_slot e + (Il.ScalarTy (Il.operand_scalar_ty op))) + in + let is_mem op = + match op with + Il.Cell (Il.Mem _) -> true + | _ -> false + in + let bounce_lhs = is_mem lhs in + let bounce_rhs = is_mem rhs in + let lhs_spill = next_spill_like lhs in + let rhs_spill = next_spill_like rhs in + + if bounce_lhs + then mov lhs_spill lhs; + + if bounce_rhs + then mov rhs_spill rhs; + + mov lhs_eax + (if bounce_lhs + then (Il.Cell lhs_spill) + else lhs); + + mov rhs_ecx + (if bounce_rhs + then (Il.Cell rhs_spill) + else rhs); + put (Il.Binary { b with Il.binary_lhs = (Il.Cell lhs_eax); @@ -314,7 +344,7 @@ let emit_target_specific Il.binary_dst = dst_eax; }); if dst <> dst_eax then mov dst (Il.Cell dst_eax); - + | _ when (Il.Cell dst) <> lhs -> mov dst lhs; put (Il.Binary @@ -1936,15 +1966,20 @@ let zero (dst:Il.cell) (count:Il.operand) : Asm.frag = ;; let mov (signed:bool) (dst:Il.cell) (src:Il.operand) : Asm.frag = - if is_ty8 (Il.cell_scalar_ty dst) || is_ty8 (Il.operand_scalar_ty src) + if is_ty8 (Il.cell_scalar_ty dst) then begin - (match dst with - Il.Reg (Il.Hreg r, _) - -> assert (is_ok_r8 r) | _ -> ()); - (match src with - Il.Cell (Il.Reg (Il.Hreg r, _)) - -> assert (is_ok_r8 r) | _ -> ()); + match dst with + Il.Reg (Il.Hreg r, _) -> assert (is_ok_r8 r) + | _ -> () + end; + + if is_ty8 (Il.operand_scalar_ty src) + then + begin + match src with + Il.Cell (Il.Reg (Il.Hreg r, _)) -> assert (is_ok_r8 r) + | _ -> () end; match (signed, dst, src) with diff --git a/src/boot/fe/item.ml b/src/boot/fe/item.ml index 69fe5fc2..82ec2faf 100644 --- a/src/boot/fe/item.ml +++ b/src/boot/fe/item.ml @@ -253,7 +253,10 @@ and parse_stmts (ps:pstate) : Ast.stmt array = let lv = name_to_lval apos bpos name in Ast.PAT_tag (lv, paren_comma_list parse_pat ps) - | LIT_INT _ | LIT_CHAR _ | LIT_BOOL _ -> + | LIT_INT _ + | LIT_UINT _ + | LIT_CHAR _ + | LIT_BOOL _ -> Ast.PAT_lit (Pexp.parse_lit ps) | UNDERSCORE -> bump ps; Ast.PAT_wild diff --git a/src/boot/fe/pexp.ml b/src/boot/fe/pexp.ml index fb2d91a0..3e17e0e4 100644 --- a/src/boot/fe/pexp.ml +++ b/src/boot/fe/pexp.ml @@ -817,11 +817,33 @@ and parse_or_pexp (ps:pstate) : pexp = step lhs +and parse_as_pexp (ps:pstate) : pexp = + let apos = lexpos ps in + let pexp = ctxt "as pexp" parse_or_pexp ps in + let rec step accum = + match peek ps with + AS -> + bump ps; + let tapos = lexpos ps in + let t = parse_ty ps in + let bpos = lexpos ps in + let t = span ps tapos bpos t in + let node = + span ps apos bpos + (PEXP_unop ((Ast.UNOP_cast t), accum)) + in + step node + + | _ -> accum + in + step pexp + + and parse_relational_pexp (ps:pstate) : pexp = let name = "relational pexp" in let apos = lexpos ps in - let lhs = ctxt (name ^ " lhs") parse_or_pexp ps in - let build = binop_build ps name apos parse_or_pexp in + let lhs = ctxt (name ^ " lhs") parse_as_pexp ps in + let build = binop_build ps name apos parse_as_pexp in let rec step accum = match peek ps with LT -> build accum step Ast.BINOP_lt @@ -883,30 +905,8 @@ and parse_oror_pexp (ps:pstate) : pexp = step lhs -and parse_as_pexp (ps:pstate) : pexp = - let apos = lexpos ps in - let pexp = ctxt "as pexp" parse_oror_pexp ps in - let rec step accum = - match peek ps with - AS -> - bump ps; - let tapos = lexpos ps in - let t = parse_ty ps in - let bpos = lexpos ps in - let t = span ps tapos bpos t in - let node = - span ps apos bpos - (PEXP_unop ((Ast.UNOP_cast t), accum)) - in - step node - - | _ -> accum - in - step pexp - - and parse_pexp (ps:pstate) : pexp = - parse_as_pexp ps + parse_oror_pexp ps and parse_mutable_and_pexp (ps:pstate) : (Ast.mutability * pexp) = let mutability = parse_mutability ps in diff --git a/src/boot/llvm/lltrans.ml b/src/boot/llvm/lltrans.ml index ee192725..c1ef49af 100644 --- a/src/boot/llvm/lltrans.ml +++ b/src/boot/llvm/lltrans.ml @@ -588,7 +588,7 @@ let trans_crate (* Maps a fn's or block's id to an LLVM metadata node (subprogram or lexical block) representing it. *) let (dbg_llscopes:(node_id, Llvm.llvalue) Hashtbl.t) = Hashtbl.create 0 in - let declare_mod_item + let rec declare_mod_item (name:Ast.ident) mod_item : unit = @@ -616,9 +616,8 @@ let trans_crate | Ast.MOD_ITEM_type _ -> () (* Types get translated with their terms. *) - | Ast.MOD_ITEM_mod _ -> - () (* Modules simply contain other items that are translated - on their own. *) + | Ast.MOD_ITEM_mod (_, items) -> + Hashtbl.iter declare_mod_item items | _ -> Common.unimpl (Some id) @@ -807,6 +806,17 @@ let trans_crate Ast.sprintf_lval lval) in + let trans_callee (fn:Ast.lval) : (Llvm.llvalue * Ast.ty) = + let fty = Hashtbl.find sem_cx.ctxt_all_lval_types (lval_base_id fn) in + if lval_base_is_item sem_cx fn then + let fn_item = lval_item sem_cx fn in + let llfn = Hashtbl.find llitems (fn_item.id) in + (llfn, fty) + else + (* indirect call to computed slot *) + trans_lval fn + in + let trans_atom (atom:Ast.atom) : Llvm.llvalue = iflog (fun _ -> log sem_cx "trans_atom: %a" Ast.sprintf_atom atom); match atom with @@ -959,7 +969,7 @@ let trans_crate | Ast.STMT_call (dest, fn, args) -> let llargs = Array.map trans_atom args in let (lldest, _) = trans_lval dest in - let (llfn, _) = trans_lval fn in + let (llfn, _) = trans_callee fn in let llallargs = Array.append [| lldest; lltask |] llargs in let llrv = build_call llfn llallargs "" llbuilder in Llvm.set_instruction_call_conv Llvm.CallConv.c llrv; @@ -1072,13 +1082,22 @@ let trans_crate ignore (Llvm.build_br llbodyblock llinitbuilder) in - let trans_mod_item - (_:Ast.ident) - { node = { Ast.decl_item = (item:Ast.mod_item') }; id = id } + let rec trans_mod_item + (name:Ast.ident) + mod_item : unit = + let { node = { Ast.decl_item = (item:Ast.mod_item') }; id = id } = + mod_item in match item with - Ast.MOD_ITEM_fn fn -> trans_fn fn id - | _ -> () + Ast.MOD_ITEM_type _ -> + () (* Types get translated with their terms. *) + | Ast.MOD_ITEM_mod (_, items) -> + Hashtbl.iter trans_mod_item items + | Ast.MOD_ITEM_fn fn -> trans_fn fn id + | _ -> Common.unimpl (Some id) + "LLVM module declaration for: %a" + Ast.sprintf_mod_item (name, mod_item) + in let exit_task_glue = diff --git a/src/boot/me/trans.ml b/src/boot/me/trans.ml index f2bb2287..b708bb26 100644 --- a/src/boot/me/trans.ml +++ b/src/boot/me/trans.ml @@ -163,7 +163,6 @@ let trans_visitor abi.Abi.abi_emit_target_specific vregs_ok fnid in - Stack.push (Hashtbl.create 0) e.Il.emit_size_cache; Stack.push e emitters; in @@ -172,16 +171,20 @@ let trans_visitor let pop_emitter _ = ignore (Stack.pop emitters) in let emitter _ = Stack.top emitters in - let emitter_size_cache _ = Stack.top (emitter()).Il.emit_size_cache in - let push_emitter_size_cache _ = - Stack.push - (Hashtbl.copy (emitter_size_cache())) - (emitter()).Il.emit_size_cache + let emitter_size_cache _ = (emitter()).Il.emit_size_cache in + let flush_emitter_size_cache _ = + Hashtbl.clear (emitter_size_cache()) in - let pop_emitter_size_cache _ = - ignore (Stack.pop (emitter()).Il.emit_size_cache) + + let emit q = + begin + match q with + Il.Jmp _ -> flush_emitter_size_cache(); + | _ -> () + end; + Il.emit (emitter()) q in - let emit q = Il.emit (emitter()) q in + let next_vreg _ = Il.next_vreg (emitter()) in let next_vreg_cell t = Il.next_vreg_cell (emitter()) t in let next_spill_cell t = @@ -190,12 +193,17 @@ let trans_visitor let spill_ta = (spill_mem, Il.ScalarTy t) in Il.Mem spill_ta in - let mark _ : quad_idx = (emitter()).Il.emit_pc in + let mark _ : quad_idx = + flush_emitter_size_cache (); + (emitter()).Il.emit_pc + in let patch_existing (jmp:quad_idx) (targ:quad_idx) : unit = - Il.patch_jump (emitter()) jmp targ + Il.patch_jump (emitter()) jmp targ; + flush_emitter_size_cache (); in let patch (i:quad_idx) : unit = Il.patch_jump (emitter()) i (mark()); + flush_emitter_size_cache (); (* Insert a dead quad to ensure there's an otherwise-unused * jump-target here. *) @@ -583,7 +591,13 @@ let trans_visitor (string_of_size size))); let sub_sz = calculate_sz ty_params in match htab_search (emitter_size_cache()) size with - Some op -> op + Some op -> + iflog (fun _ -> annotate + (Printf.sprintf "cached size %s is %s" + (string_of_size size) + (oper_str op))); + op + | _ -> let res = match size with @@ -914,7 +928,8 @@ let trans_visitor let atop = trans_atom at in let unit_sz = ty_sz_in_current_frame ty in let idx = next_vreg_cell word_sty in - emit (Il.binary Il.UMUL idx atop unit_sz); + mov idx atop; + emit (Il.binary Il.UMUL idx (Il.Cell idx) unit_sz); let elt_mem = trans_bounds_check (deref cell) (Il.Cell idx) in (Il.Mem (elt_mem, referent_type abi ty), ty) in @@ -1923,8 +1938,8 @@ let trans_visitor : quad_idx list = emit (Il.cmp (Il.Cell (Il.Reg (force_to_reg lhs))) rhs); let jmp = mark() in - emit (Il.jmp cjmp Il.CodeNone); - [ jmp ] + emit (Il.jmp cjmp Il.CodeNone); + [ jmp ] and trans_compare ?ty_params:(ty_params=get_ty_params_of_current_frame()) @@ -1943,7 +1958,6 @@ let trans_visitor | _ -> trans_compare_simple cjmp lhs rhs and trans_cond (invert:bool) (expr:Ast.expr) : quad_idx list = - let anno _ = iflog begin @@ -2075,15 +2089,14 @@ let trans_visitor trans_atom a and trans_block (block:Ast.block) : unit = + flush_emitter_size_cache(); trace_str cx.ctxt_sess.Session.sess_trace_block "entering block"; - push_emitter_size_cache (); emit (Il.Enter (Hashtbl.find cx.ctxt_block_fixups block.id)); Array.iter trans_stmt block.node; trace_str cx.ctxt_sess.Session.sess_trace_block "exiting block"; emit Il.Leave; - pop_emitter_size_cache (); trace_str cx.ctxt_sess.Session.sess_trace_block "exited block"; @@ -4395,11 +4408,11 @@ let trans_visitor let back_jmp = trans_compare_simple Il.JB (Il.Cell dptr) (Il.Cell dlim) in - List.iter - (fun j -> patch_existing j back_jmp_targ) back_jmp; - let v = next_vreg_cell word_sty in - mov v (Il.Cell src_fill); - add_to dst_fill (Il.Cell v); + List.iter + (fun j -> patch_existing j back_jmp_targ) back_jmp; + let v = next_vreg_cell word_sty in + mov v (Il.Cell src_fill); + add_to dst_fill (Il.Cell v); | t -> begin bug () "unsupported vector-append type %a" Ast.sprintf_ty t diff --git a/src/boot/me/type.ml b/src/boot/me/type.ml index 787855f0..23210ea1 100644 --- a/src/boot/me/type.ml +++ b/src/boot/me/type.ml @@ -380,19 +380,20 @@ let check_stmt (cx:Semant.ctxt) : (fn_ctx -> Ast.stmt -> unit) = sprintf_itype () | `Type (Ast.TY_vec ty_vec), Ast.COMP_atom atom -> - demand Ast.TY_int (check_atom atom); + demand_integer (check_atom atom); LTYPE_mono ty_vec | `Type (Ast.TY_vec _), _ -> - Common.err None "the vector type '%a' must be indexed via an int" + Common.err None + "the vector type '%a' must be indexed by an integral type" sprintf_itype () | `Type Ast.TY_str, Ast.COMP_atom atom -> - demand Ast.TY_int (check_atom atom); + demand_integer (check_atom atom); LTYPE_mono (Ast.TY_mach Common.TY_u8) | `Type Ast.TY_str, _ -> - Common.err None "strings must be indexed via an int" + Common.err None "strings must be indexed by an integral type" | `Type (Ast.TY_box ty_box), Ast.COMP_deref -> LTYPE_mono ty_box |