From 1d738ef750858e16130bd610153173a34f27ac20 Mon Sep 17 00:00:00 2001 From: Nicolas Cannasse Date: Sat, 26 Aug 2023 13:17:43 +0200 Subject: [PATCH 1/2] added native carray access with hl 1.14 --- src/generators/genhl.ml | 26 ++++++++++++++++++++++---- src/generators/hlinterp.ml | 4 ++-- src/generators/hlopt.ml | 5 +++++ std/hl/CArray.hx | 7 ++++++- 4 files changed, 35 insertions(+), 7 deletions(-) diff --git a/src/generators/genhl.ml b/src/generators/genhl.ml index e8ffa87cdcd..122a50096a4 100644 --- a/src/generators/genhl.ml +++ b/src/generators/genhl.ml @@ -131,6 +131,7 @@ type access = | AInstanceProto of texpr * field index | AInstanceField of texpr * field index | AArray of reg * (ttype * ttype) * reg + | ACArray of reg * ttype * reg | AVirtualMethod of texpr * field index | ADynamic of texpr * string index | AEnum of tenum * field index @@ -1377,6 +1378,13 @@ and get_access ctx e = free ctx a; let t = to_type ctx t in AArray (a,(t,t),i) + | TInst ({ cl_path = ["hl"],"Abstract" },[TInst({ cl_kind = KExpr (EConst (String("hl_carray",_)),_) },_)]) -> + let a = eval_null_check ctx a in + hold ctx a; + let i = eval_to ctx i HI32 in + free ctx a; + let t = to_type ctx e.etype in + ACArray (a,t,i) | TAbstract (a,pl) -> loop (Abstract.get_underlying_type a pl) | _ -> @@ -1894,7 +1902,13 @@ and eval_expr ctx e = r | "$asize", [e] -> let r = alloc_tmp ctx HI32 in - op ctx (OArraySize (r, eval_to ctx e HArray)); + (match follow e.etype with + | TInst ({cl_path=["hl"],"Abstract"},[TInst({ cl_kind = KExpr (EConst (String("hl_carray",_)),_) },_)]) -> + let arr = eval_expr ctx e in + op ctx (ONullCheck arr); + op ctx (OArraySize (r, arr)) + | _ -> + op ctx (OArraySize (r, eval_to ctx e HArray))); r | "$aalloc", [esize] -> let et = (match follow e.etype with TAbstract ({ a_path = ["hl"],"NativeArray" },[t]) -> to_type ctx t | _ -> invalid()) in @@ -2208,7 +2222,7 @@ and eval_expr ctx e = ignore(make_fun ctx ("","") fid f None None); end; op ctx (OStaticClosure (r,fid)); - | ANone | ALocal _ | AArray _ | ACaptured _ -> + | ANone | ALocal _ | AArray _ | ACaptured _ | ACArray _ -> abort "Invalid access" e.epos); let to_t = to_type ctx e.etype in (match to_t with @@ -2452,7 +2466,7 @@ and eval_expr ctx e = let r = value() in op ctx (OSetEnumField (ctx.m.mcaptreg,index,r)); r - | AEnum _ | ANone | AInstanceFun _ | AInstanceProto _ | AStaticFun _ | AVirtualMethod _ -> + | AEnum _ | ANone | AInstanceFun _ | AInstanceProto _ | AStaticFun _ | AVirtualMethod _ | ACArray _ -> die "" __LOC__) | OpBoolOr -> let r = alloc_tmp ctx HBool in @@ -2727,6 +2741,10 @@ and eval_expr ctx e = (match get_access ctx e with | AArray (a,at,idx) -> array_read ctx a at idx e.epos + | ACArray (a,t,idx) -> + let tmp = alloc_tmp ctx t in + op ctx (OGetArray (tmp,a,idx)); + tmp | _ -> die "" __LOC__) | TMeta (_,e) -> @@ -3046,7 +3064,7 @@ and gen_assign_op ctx acc e1 f = free ctx robj; op ctx (ODynSet (robj,fid,r)); r - | ANone | ALocal _ | AStaticFun _ | AInstanceFun _ | AInstanceProto _ | AVirtualMethod _ | AEnum _ -> + | ANone | ALocal _ | AStaticFun _ | AInstanceFun _ | AInstanceProto _ | AVirtualMethod _ | AEnum _ | ACArray _ -> die "" __LOC__ and build_capture_vars ctx f = diff --git a/src/generators/hlinterp.ml b/src/generators/hlinterp.ml index f6fc7f32fd0..785fca09b6e 100644 --- a/src/generators/hlinterp.ml +++ b/src/generators/hlinterp.ml @@ -2436,7 +2436,7 @@ let check code macros = | ORethrow r -> reg r HDyn | OGetArray (v,a,i) -> - reg a HArray; + (match rtype a with HAbstract ("hl_carray",_) -> () | _ -> reg a HArray); reg i HI32; ignore(rtype v); | OGetUI8 (r,b,p) | OGetUI16(r,b,p) -> @@ -2466,7 +2466,7 @@ let check code macros = ignore(rtype a); ignore(rtype b); | OArraySize (r,a) -> - reg a HArray; + (match rtype a with HAbstract ("hl_carray",_) -> () | _ -> reg a HArray); reg r HI32 | OType (r,_) -> reg r HType diff --git a/src/generators/hlopt.ml b/src/generators/hlopt.ml index 2e5bd20c4c6..81059d76275 100644 --- a/src/generators/hlopt.ml +++ b/src/generators/hlopt.ml @@ -875,6 +875,11 @@ let _optimize (f:fundecl) = | OGetThis (r,fid) when (match f.regs.(r) with HStruct _ -> true | _ -> false) -> do_write r; if is_packed_field 0 fid then state.(r).rnullcheck <- true; + | OGetArray (r,arr,idx) -> + do_read arr; + do_read idx; + do_write r; + (match f.regs.(arr) with HAbstract _ -> state.(r).rnullcheck <- true | _ -> ()); | _ -> opcode_fx (fun r read -> if read then do_read r else do_write r diff --git a/std/hl/CArray.hx b/std/hl/CArray.hx index 850d86f5705..81c7329e82b 100644 --- a/std/hl/CArray.hx +++ b/std/hl/CArray.hx @@ -9,9 +9,14 @@ abstract CArray(Abstract<"hl_carray">) { public var length(get,never) : Int; - inline function get_length() return getLen(cast this); + #if (hl_ver >= version("1.14.0")) + inline function get_length() return untyped $asize(this); + @:arrayAccess inline function get( index : Int ) : T return untyped this[index]; + #else + inline function get_length() return getLen(cast this); @:arrayAccess inline function get( index : Int ) : T return getIndex(cast this, index); + #end public static function alloc( cl : Class, size : Int ) : CArray { return cast alloc_carray( (cast cl:BaseType).__type__ , size ); From 5127cb15551b4cc2070d31a21497f0fe53365297 Mon Sep 17 00:00:00 2001 From: Nicolas Cannasse Date: Sat, 26 Aug 2023 15:40:54 +0200 Subject: [PATCH 2/2] [hl] added $prefetch support --- src/generators/genhl.ml | 15 +++++++++++++++ src/generators/hl2c.ml | 9 +++++++++ src/generators/hlcode.ml | 3 +++ src/generators/hlinterp.ml | 4 +++- src/generators/hlopt.ml | 5 +++++ 5 files changed, 35 insertions(+), 1 deletion(-) diff --git a/src/generators/genhl.ml b/src/generators/genhl.ml index 122a50096a4..1ab0d0149fa 100644 --- a/src/generators/genhl.ml +++ b/src/generators/genhl.ml @@ -311,6 +311,12 @@ let unsigned_op e1 e2 = in is_unsigned e1 && is_unsigned e2 +let rec get_const e = + match e.eexpr with + | TConst c -> c + | TParenthesis e | TCast (e,_) -> get_const e + | _ -> abort "Should be a constant" e.epos + let set_curpos ctx p = ctx.m.mcurpos <- p @@ -2068,6 +2074,15 @@ and eval_expr ctx e = free ctx rfile; free ctx min; r + | "$prefetch", [value; mode] -> + let mode = (match get_const mode with + | TInt m -> Int32.to_int m + | _ -> abort "Constant mode required" e.epos + ) in + (match get_access ctx value with + | AInstanceField (f, index) -> op ctx (OPrefetch (eval_expr ctx f, index + 1, mode)) + | _ -> op ctx (OPrefetch (eval_expr ctx value, 0, mode))); + alloc_tmp ctx HVoid | _ -> abort ("Unknown native call " ^ s) e.epos) | TEnumIndex v -> diff --git a/src/generators/hl2c.ml b/src/generators/hl2c.ml index af03a261786..d5b94f0ddff 100644 --- a/src/generators/hl2c.ml +++ b/src/generators/hl2c.ml @@ -1087,6 +1087,15 @@ let generate_function ctx f = sexpr "%s = %s + %s" (reg r) (reg r2) (reg off) | ONop _ -> () + | OPrefetch (r,fid,mode) -> + let expr = (if fid = 0 then reg r else (match rtype r with + | HObj o | HStruct o -> + let name, t = resolve_field o (fid - 1) in + Printf.sprintf "%s->%s" (reg r) name + | _ -> + Globals.die "" __LOC__ + )) in + sexpr "__hl_prefetch_m%d(%s)" mode expr ) f.code; flush_options (Array.length f.code); unblock(); diff --git a/src/generators/hlcode.ml b/src/generators/hlcode.ml index 733a6b10e05..d40313f9c26 100644 --- a/src/generators/hlcode.ml +++ b/src/generators/hlcode.ml @@ -201,6 +201,7 @@ type opcode = | ORefData of reg * reg | ORefOffset of reg * reg * reg | ONop of string + | OPrefetch of reg * field index * int type fundecl = { fpath : string * string; @@ -572,6 +573,8 @@ let ostr fstr o = | ORefData (r,d) -> Printf.sprintf "refdata %d, %d" r d | ORefOffset (r,r2,off) -> Printf.sprintf "refoffset %d, %d, %d" r r2 off | ONop s -> if s = "" then "nop" else "nop " ^ s + | OPrefetch (r,f,mode) -> Printf.sprintf "prefetch %d[%d] %d" r f mode + let fundecl_name f = if snd f.fpath = "" then "fun$" ^ (string_of_int f.findex) else (fst f.fpath) ^ "." ^ (snd f.fpath) let dump pr code = diff --git a/src/generators/hlinterp.ml b/src/generators/hlinterp.ml index 785fca09b6e..e50714f7ee4 100644 --- a/src/generators/hlinterp.ml +++ b/src/generators/hlinterp.ml @@ -1154,7 +1154,7 @@ let interp ctx f args = (match get r2, get off with | VRef (RArray (a,pos),t), VInt i -> set r (VRef (RArray (a,pos + Int32.to_int i),t)) | _ -> Globals.die "" __LOC__) - | ONop _ -> + | ONop _ | OPrefetch _ -> () ); loop() @@ -2547,6 +2547,8 @@ let check code macros = reg off HI32; | ONop _ -> (); + | OPrefetch (r,f,_) -> + if f = 0 then ignore(rtype r) else ignore(tfield r (f - 1) false) ) f.code (* TODO : check that all path correctly initialize NULL values and reach a return *) in diff --git a/src/generators/hlopt.ml b/src/generators/hlopt.ml index 81059d76275..c11db0161aa 100644 --- a/src/generators/hlopt.ml +++ b/src/generators/hlopt.ml @@ -164,6 +164,8 @@ let opcode_fx frw op = write r; | ONop _ -> () + | OPrefetch (r,_,_) -> + read r let opcode_eq a b = match a, b with @@ -432,6 +434,9 @@ let opcode_map read write op = ORefOffset (write r,r2,off); | ONop _ -> op + | OPrefetch (r, fid, mode) -> + let r2 = read r in + OPrefetch (r2, fid, mode) (* build code graph *)