Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[hlopt] cache based on opcode array #11797

Open
wants to merge 7 commits into
base: development
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 3 additions & 100 deletions src/generators/hlopt.ml
Original file line number Diff line number Diff line change
Expand Up @@ -1051,121 +1051,24 @@ let _optimize (f:fundecl) =

let same_op op1 op2 =
match op1, op2 with
| OMov (a1,b1), OMov (a2, b2) -> a1 = a2 && b1 = b2
| OInt (r1,_), OInt (r2, _) -> r1 = r2
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at this and other lines here, I don't understand why OInt(1, 1) and OInt(1, 2) should be considered the same op.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's OInt reg * int index, what only matters in optimized code is the used register / control flow, and not the index in global int table (e.g. in two different run, the same int 55 can have index 10 or 35). They are "fixed" by code related to c_remap_indexes.

I should double check if the replacement is always good, I'm trying to also remap field index but there are some errors x(

Copy link
Contributor Author

@yuxiaomao yuxiaomao Oct 24, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same_op is confusing. I should probably rename the function but I don't have a good idea. Maybe same_op_except_index

| OFloat (r1,_), OFloat (r2,_) -> r1 = r2
| OBool (r1,b1), OBool (r2,b2) -> r1 = r2 && b1 = b2
| OBytes (r1,_), OBytes (r2,_) -> r1 = r2
| OString (r1,_), OString (r2,_) -> r1 = r2
| ONull r1, ONull r2 -> r1 = r2
| OAdd (r1,a1,b1), OAdd (r2,a2,b2)
| OSub (r1,a1,b1), OSub (r2,a2,b2)
| OMul (r1,a1,b1), OMul (r2,a2,b2)
| OSDiv (r1,a1,b1), OSDiv (r2,a2,b2)
| OUDiv (r1,a1,b1), OUDiv (r2,a2,b2)
| OSMod (r1,a1,b1), OSMod (r2,a2,b2)
| OUMod (r1,a1,b1), OUMod (r2,a2,b2)
| OShl (r1,a1,b1), OShl (r2,a2,b2)
| OSShr (r1,a1,b1), OSShr (r2,a2,b2)
| OUShr (r1,a1,b1), OUShr (r2,a2,b2)
| OAnd (r1,a1,b1), OAnd (r2,a2,b2)
| OOr (r1,a1,b1), OOr (r2,a2,b2)
| OXor (r1,a1,b1), OXor (r2,a2,b2)
-> r1 = r2 && a1 = a2 && b1 = b2
| ONeg (r1,v1), ONeg (r2,v2)
| ONot (r1,v1), ONot (r2,v2)
-> r1 = r2 && v1 = v2
| OIncr r1, OIncr r2
| ODecr r1, ODecr r2
-> r1 = r2
| OCall0 (r1,_), OCall0 (r2,_) -> r1 = r2
| OCall1 (r1,_,a1), OCall1 (r2,_,a2) -> r1 = r2 && a1 = a2
| OCall2 (r1,_,a1,b1), OCall2 (r2,_,a2,b2) -> r1 = r2 && a1 = a2 && b1 = b2
| OCall3 (r1,_,a1,b1,c1), OCall3 (r2,_,a2,b2,c2) -> r1 = r2 && a1 = a2 && b1 = b2 && c1 = c2
| OCall4 (r1,_,a1,b1,c1,d1), OCall4 (r2,_,a2,b2,c2,d2) -> r1 = r2 && a1 = a2 && b1 = b2 && c1 = c2 && d1 = d2
| OCallN (r1,_,rl1), OCallN (r2,_,rl2) -> r1 = r2 && rl1 = rl2
| OCallMethod (r1,f1,rl1), OCallMethod (r2,f2,rl2) -> r1 = r2 && f1 = f2 && rl1 = rl2
| OCallClosure (r1,f1,rl1), OCallClosure (r2,f2,rl2) -> r1 = r2 && f1 = f2 && rl1 = rl2
| OCallThis (r1,f1,rl1), OCallThis (r2,f2,rl2) -> r1 = r2 && f1 = f2 && rl1 = rl2
| OStaticClosure (r1,_), OStaticClosure (r2,_) -> r1 = r2
| OInstanceClosure (r1,_,v1), OInstanceClosure (r2,_,v2) -> r1 = r2 && v1 = v2
| OVirtualClosure (r1,o1,m1), OVirtualClosure (r2,o2,m2) -> r1 = r2 && o1 = o2 && m1 = m2
| OGetGlobal (r1,_), OGetGlobal (r2,_)
| OSetGlobal (_,r1), OSetGlobal (_,r2)
-> r1 = r2
| OField (r1,o1,i1), OField (r2,o2,i2)
| OSetField (o1,i1,r1), OSetField (o2,i2,r2)
-> r1 = r2 && o1 = o2 && i1 = i2
| OGetThis (r1,i1), OGetThis (r2,i2)
| OSetThis (i1,r1), OSetThis (i2,r2)
-> r1 = r2 && i1 = i2
| OGetGlobal (r1,_), OGetGlobal (r2,_) -> r1 = r2
| OSetGlobal (_,r1), OSetGlobal (_,r2) -> r1 = r2
| ODynGet (r1,o1,_), ODynGet (r2,o2,_) -> r1 = r2 && o1 = o2
| ODynSet (o1,_,v1), ODynSet (o2,_,v2) -> o1 = o2 && v1 = v2
| OJTrue (r1,d1), OJTrue (r2,d2)
| OJFalse (r1,d1), OJFalse (r2,d2)
| OJNull (r1,d1), OJNull (r2,d2)
| OJNotNull (r1,d1), OJNotNull (r2,d2)
-> r1 = r2 && d1 = d2
| OJSLt (a1,b1,i1), OJSLt (a2,b2,i2)
| OJSGte (a1,b1,i1), OJSGte (a2,b2,i2)
| OJSGt (a1,b1,i1), OJSGt (a2,b2,i2)
| OJSLte (a1,b1,i1), OJSLte (a2,b2,i2)
| OJULt (a1,b1,i1), OJULt (a2,b2,i2)
| OJUGte (a1,b1,i1), OJUGte (a2,b2,i2)
| OJNotLt (a1,b1,i1), OJNotLt (a2,b2,i2)
| OJNotGte (a1,b1,i1), OJNotGte (a2,b2,i2)
| OJEq (a1,b1,i1), OJEq (a2,b2,i2)
| OJNotEq (a1,b1,i1), OJNotEq (a2,b2,i2)
-> a1 = a2 && b1 = b2 && i1 = i2
| OJAlways d1, OJAlways d2 -> d1 = d2
| OToDyn (r1,a1), OToDyn (r2,a2)
| OToSFloat (r1,a1), OToSFloat (r2,a2)
| OToUFloat (r1,a1), OToUFloat (r2,a2)
| OToInt (r1,a1), OToInt (r2,a2)
-> r1 = r2 && a1 = a2
| OSafeCast (r1,v1), OSafeCast (r2,v2)
| OUnsafeCast (r1,v1), OUnsafeCast (r2,v2)
| OToVirtual (r1,v1), OToVirtual (r2,v2)
-> r1 = r2 && v1 = v2
| OLabel _, OLabel _ -> true
| ORet r1, ORet r2 -> r1 = r2
| OThrow r1, OThrow r2
| ORethrow r1, ORethrow r2
-> r1 = r2
| OSwitch (r1,idx1,eend1), OSwitch (r2,idx2,eend2) -> r1 = r2 && idx1 = idx2 && eend1 = eend2
| ONullCheck r1, ONullCheck r2 -> r1 = r2
| OTrap (r1,i1), OTrap (r2,i2) -> r1 = r2 && i1 = i2
| OEndTrap b1, OEndTrap b2 -> b1 = b2
| OGetUI8 (r1,a1,b1), OGetUI8 (r2,a2,b2)
| OGetUI16 (r1,a1,b1), OGetUI16 (r2,a2,b2)
| OGetMem (r1,a1,b1), OGetMem (r2,a2,b2)
| OGetArray (r1,a1,b1), OGetArray (r2,a2,b2)
| OSetUI8 (r1,a1,b1), OSetUI8 (r2,a2,b2)
| OSetUI16 (r1,a1,b1), OSetUI16 (r2,a2,b2)
| OSetMem (r1,a1,b1), OSetMem (r2,a2,b2)
| OSetArray (r1,a1,b1), OSetArray (r2,a2,b2)
-> r1 = r2 && a1 = a2 && b1 = b2
| ONew r1, ONew r2 -> r1 = r2
| OArraySize (r1,a1), OArraySize (r2,a2) -> r1 = r2 && a1 = a2
| OType (r1,_), OType (r2,_) -> r1 = r2
| OGetType (r1,v1), OGetType (r2,v2)
| OGetTID (r1,v1), OGetTID (r2,v2)
| ORef (r1,v1), ORef (r2,v2)
| OUnref (v1,r1), OUnref (v2,r2)
| OSetref (r1,v1), OSetref (r2,v2)
-> r1 = r2 && v1 = v2
| OMakeEnum (r1,e1,pl1), OMakeEnum (r2,e2,pl2) -> r1 = r2 && e1 = e2 && pl1 = pl2
| OEnumAlloc (r1,e1), OEnumAlloc (r2,e2) -> r1 = r2 && e1 = e2
| OEnumIndex (r1,e1), OEnumIndex (r2,e2) -> r1 = r2 && e1 = e2
| OEnumField (r1,e1,i1,n1), OEnumField (r2,e2,i2,n2) -> r1 = r2 && e1 = e2 && i1 = i2 && n1 = n2
| OSetEnumField (e1,i1,r1), OSetEnumField (e2,i2,r2) -> r1 = r2 && e1 = e2 && i1 = i2
| OAssert _, OAssert _ -> true
| ORefData (r1,d1), ORefData (r2,d2) -> r1 = r2 && d1 = d2
| ORefOffset (r1,a1,off1), ORefOffset (r2,a2,off2) -> r1 = r2 && a1 = a2 && off1 = off2
| ONop s1, ONop s2 -> s1 = s2
| OPrefetch (r1,f1,mode1), OPrefetch (r2,f2,mode2) -> r1 = r2 && f1 = f2 && mode1 = mode2
| OAsm (mode1, value1, reg1), OAsm (mode2, value2, reg2) -> mode1 = mode2 && value1 = value2 && reg1 = reg2
| _ -> false
| _ -> op1 = op2

type cache_elt = {
c_old_code : opcode array;
Expand Down
Loading