jit_ir.h 52 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882
  1. /*
  2. * Copyright (C) 2021 Intel Corporation. All rights reserved.
  3. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. */
  5. #ifndef _JIT_IR_H_
  6. #define _JIT_IR_H_
  7. #include "bh_platform.h"
  8. #include "../interpreter/wasm.h"
  9. #include "jit_utils.h"
  10. #ifdef __cplusplus
  11. extern "C" {
  12. #endif
  13. /**
  14. * Register (operand) representation of JIT IR.
  15. *
  16. * Encoding: [4-bit: kind, 28-bit register no.]
  17. *
  18. * Registers in JIT IR are classified into different kinds according
  19. * to types of values they can hold. The classification is based on
  20. * most processors' hardware register classifications, which include
  21. * various sets of integer, floating point and vector registers with
  22. * different sizes. These registers can be mapped onto corresponding
  23. * kinds of hardware registers by register allocator. Instructions
  24. * can only operate on allowed kinds of registers. For example, an
  25. * integer instruction cannot operate on floating point or vector
  26. * registers. Some encodings of these kinds of registers also
  27. * represent immediate constant values and indexes to constant tables
  28. * (see below). In that case, those registers are read-only. Writing
  29. * to them is illegal. Reading from an immediate constant value
  30. * register always returns the constant value encoded in the register
  31. * no. Reading from a constant table index register always returns
  32. * the constant value stored at the encoded index of the constant
  33. * table of the register's kind. Immediate constant values and values
  34. * indexed by constant table indexes can only be loaded into the
  35. * corresponding kinds of registers if they must be loaded into
  36. * registers. Besides these common kinds of registers, labels of
  37. * basic blocks are also treated as registers of a special kind, which
  38. * hold code addresses of basic block labels and are read-only. Each
  39. * basic block is assigned one unique label register. With this
  40. * unification, we can use the same set of load instructions to load
  41. * values either from addresses stored in normal registers or from
  42. * addresses of labels. Besides these register kinds, the void kind
  43. * is a special kind of registers to denote some error occurs when a
  44. * normal register is expected. Or it can be used as result operand
  45. * of call and invoke instructions to denote no return values. The
  46. * variable registers are classified into two sets: the hard registers
  47. * whose register numbers are less than the hard register numbers of
  48. * their kinds and the virtual registers whose register numbers are
  49. * greater than or equal to the hard register numbers. Before
  50. * register allocation is done, hard registers may appear in the IR
  51. * due to special usages of passes frontend (e.g. fp_reg and exec_env_reg)
  52. * or lower_cg. In the mean time (including during register
  53. * allocation), those hard registers are treated same as virtual
  54. * registers except that they may not be SSA and they can only be
  55. * allocated to the hard registers of themselves.
  56. *
  57. * Classification of registers:
  58. * + void register (kind == JIT_REG_KIND_VOID, no. must be 0)
  59. * + label registers (kind == JIT_REG_KIND_L32)
  60. * + value registers (kind == JIT_REG_KIND_I32/I64/F32/F64/V64/V128/V256)
  61. * | + constants (_JIT_REG_CONST_VAL_FLAG | _JIT_REG_CONST_IDX_FLAG)
  62. * | | + constant values (_JIT_REG_CONST_VAL_FLAG)
  63. * | | + constant indexes (_JIT_REG_CONST_IDX_FLAG)
  64. * | + variables (!(_JIT_REG_CONST_VAL_FLAG | _JIT_REG_CONST_IDX_FLAG))
  65. * | | + hard registers (no. < hard register number)
  66. * | | + virtual registers (no. >= hard register number)
  67. */
  68. typedef uint32 JitReg;
  69. /*
  70. * Mask and shift bits of register kind.
  71. */
  72. #define _JIT_REG_KIND_MASK 0xf0000000
  73. #define _JIT_REG_KIND_SHIFT 28
  74. /*
  75. * Mask of register no. which must be the least significant bits.
  76. */
  77. #define _JIT_REG_NO_MASK (~_JIT_REG_KIND_MASK)
  78. /*
  79. * Constant value flag (the most significant bit) of register
  80. * no. field of integer, floating point and vector registers. If this
  81. * flag is set in the register no., the rest bits of register
  82. * no. represent a signed (27-bit) integer constant value of the
  83. * corresponding type of the register and the register is read-only.
  84. */
  85. #define _JIT_REG_CONST_VAL_FLAG ((_JIT_REG_NO_MASK >> 1) + 1)
  86. /*
  87. * Constant index flag of non-constant-value (constant value flag is
  88. * not set in register no. field) integer, floating point and vector
  89. * registers. If this flag is set, the rest bits of the register
  90. * no. represent an index to the constant value table of the
  91. * corresponding type of the register and the register is read-only.
  92. */
  93. #define _JIT_REG_CONST_IDX_FLAG (_JIT_REG_CONST_VAL_FLAG >> 1)
  94. /**
  95. * Register kinds. Don't change the order of the defined values. The
  96. * L32 kind must be after all normal kinds (see _const_val and _reg_ann
  97. * of JitCompContext).
  98. */
  99. typedef enum JitRegKind {
  100. JIT_REG_KIND_VOID = 0x00, /* void type */
  101. JIT_REG_KIND_I32 = 0x01, /* 32-bit signed or unsigned integer */
  102. JIT_REG_KIND_I64 = 0x02, /* 64-bit signed or unsigned integer */
  103. JIT_REG_KIND_F32 = 0x03, /* 32-bit floating point */
  104. JIT_REG_KIND_F64 = 0x04, /* 64-bit floating point */
  105. JIT_REG_KIND_V64 = 0x05, /* 64-bit vector */
  106. JIT_REG_KIND_V128 = 0x06, /* 128-bit vector */
  107. JIT_REG_KIND_V256 = 0x07, /* 256-bit vector */
  108. JIT_REG_KIND_L32 = 0x08, /* 32-bit label address */
  109. JIT_REG_KIND_NUM /* number of register kinds */
  110. } JitRegKind;
  111. #if UINTPTR_MAX == UINT64_MAX
  112. #define JIT_REG_KIND_PTR JIT_REG_KIND_I64
  113. #else
  114. #define JIT_REG_KIND_PTR JIT_REG_KIND_I32
  115. #endif
  116. /**
  117. * Construct a new JIT IR register from the kind and no.
  118. *
  119. * @param reg_kind register kind
  120. * @param reg_no register no.
  121. *
  122. * @return the new register with the given kind and no.
  123. */
  124. static inline JitReg
  125. jit_reg_new(unsigned reg_kind, unsigned reg_no)
  126. {
  127. return (JitReg)((reg_kind << _JIT_REG_KIND_SHIFT) | reg_no);
  128. }
  129. /**
  130. * Get the register kind of the given register.
  131. *
  132. * @param r a JIT IR register
  133. *
  134. * @return the register kind of register r
  135. */
  136. static inline int
  137. jit_reg_kind(JitReg r)
  138. {
  139. return (r & _JIT_REG_KIND_MASK) >> _JIT_REG_KIND_SHIFT;
  140. }
  141. /**
  142. * Get the register no. of the given JIT IR register.
  143. *
  144. * @param r a JIT IR register
  145. *
  146. * @return the register no. of register r
  147. */
  148. static inline int
  149. jit_reg_no(JitReg r)
  150. {
  151. return r & _JIT_REG_NO_MASK;
  152. }
  153. /**
  154. * Check whether the given register is a normal value register.
  155. *
  156. * @param r a JIT IR register
  157. *
  158. * @return true iff the register is a normal value register
  159. */
  160. static inline bool
  161. jit_reg_is_value(JitReg r)
  162. {
  163. unsigned kind = jit_reg_kind(r);
  164. return kind > JIT_REG_KIND_VOID && kind < JIT_REG_KIND_L32;
  165. }
  166. /**
  167. * Check whether the given register is a constant value.
  168. *
  169. * @param r a JIT IR register
  170. *
  171. * @return true iff register r is a constant value
  172. */
  173. static inline bool
  174. jit_reg_is_const_val(JitReg r)
  175. {
  176. return jit_reg_is_value(r) && (r & _JIT_REG_CONST_VAL_FLAG);
  177. }
  178. /**
  179. * Check whether the given register is a constant table index.
  180. *
  181. * @param r a JIT IR register
  182. *
  183. * @return true iff register r is a constant table index
  184. */
  185. static inline bool
  186. jit_reg_is_const_idx(JitReg r)
  187. {
  188. return (jit_reg_is_value(r) && !jit_reg_is_const_val(r)
  189. && (r & _JIT_REG_CONST_IDX_FLAG));
  190. }
  191. /**
  192. * Check whether the given register is a constant.
  193. *
  194. * @param r a JIT IR register
  195. *
  196. * @return true iff register r is a constant
  197. */
  198. static inline bool
  199. jit_reg_is_const(JitReg r)
  200. {
  201. return (jit_reg_is_value(r)
  202. && (r & (_JIT_REG_CONST_VAL_FLAG | _JIT_REG_CONST_IDX_FLAG)));
  203. }
  204. /**
  205. * Check whether the given register is a normal variable register.
  206. *
  207. * @param r a JIT IR register
  208. *
  209. * @return true iff the register is a normal variable register
  210. */
  211. static inline bool
  212. jit_reg_is_variable(JitReg r)
  213. {
  214. return (jit_reg_is_value(r)
  215. && !(r & (_JIT_REG_CONST_VAL_FLAG | _JIT_REG_CONST_IDX_FLAG)));
  216. }
  217. /**
  218. * Test whether the register is the given kind.
  219. *
  220. * @param KIND register kind name
  221. * @param R register
  222. *
  223. * @return true if the register is the given kind
  224. */
  225. #define jit_reg_is_kind(KIND, R) (jit_reg_kind(R) == JIT_REG_KIND_##KIND)
  226. /**
  227. * Construct a zero IR register with given the kind.
  228. *
  229. * @param kind the kind of the value
  230. *
  231. * @return a constant register of zero
  232. */
  233. static inline JitReg
  234. jit_reg_new_zero(unsigned kind)
  235. {
  236. bh_assert(kind != JIT_REG_KIND_VOID && kind < JIT_REG_KIND_L32);
  237. return jit_reg_new(kind, _JIT_REG_CONST_VAL_FLAG);
  238. }
  239. /**
  240. * Test whether the register is a zero constant value.
  241. *
  242. * @param reg an IR register
  243. *
  244. * @return true iff the register is a constant zero
  245. */
  246. static inline JitReg
  247. jit_reg_is_zero(JitReg reg)
  248. {
  249. return (jit_reg_is_value(reg)
  250. && jit_reg_no(reg) == _JIT_REG_CONST_VAL_FLAG);
  251. }
  252. /**
  253. * Operand of instructions with fixed-number register operand(s).
  254. */
  255. typedef JitReg JitOpndReg;
  256. /**
  257. * Operand of instructions with variable-number register operand(s).
  258. */
  259. typedef struct JitOpndVReg {
  260. uint32 _reg_num;
  261. JitReg _reg[1];
  262. } JitOpndVReg;
  263. /**
  264. * Operand of lookupswitch instruction.
  265. */
  266. typedef struct JitOpndLookupSwitch {
  267. /* NOTE: distance between JitReg operands must be the same (see
  268. jit_insn_opnd_regs). */
  269. JitReg value; /* the value to be compared */
  270. uint32 match_pairs_num; /* match pairs number */
  271. /* NOTE: offset between adjacent targets must be sizeof
  272. (match_pairs[0]) (see implementation of jit_basic_block_succs),
  273. so the default_target field must be here. */
  274. JitReg default_target; /* default target BB */
  275. struct {
  276. int32 value; /* match value of the match pair */
  277. JitReg target; /* target BB of the match pair */
  278. } match_pairs[1]; /* match pairs of the instruction */
  279. } JitOpndLookupSwitch;
  280. /**
  281. * Instruction of JIT IR.
  282. */
  283. typedef struct JitInsn {
  284. /* Pointers to the previous and next instructions. */
  285. struct JitInsn *prev;
  286. struct JitInsn *next;
  287. /* Opcode of the instruction. */
  288. uint16 opcode;
  289. /* Reserved field that may be used by optimizations locally.
  290. * bit_0(Least Significant Bit) is atomic flag for load/store */
  291. uint8 flags_u8;
  292. /* The unique ID of the instruction. */
  293. uint16 uid;
  294. /* Operands for different kinds of instructions. */
  295. union {
  296. /* For instructions with fixed-number register operand(s). */
  297. JitOpndReg _opnd_Reg[1];
  298. /* For instructions with variable-number register operand(s). */
  299. JitOpndVReg _opnd_VReg;
  300. /* For lookupswitch instruction. */
  301. JitOpndLookupSwitch _opnd_LookupSwitch;
  302. } _opnd;
  303. } JitInsn;
  304. /**
  305. * Opcodes of IR instructions.
  306. */
  307. typedef enum JitOpcode {
  308. #define INSN(NAME, OPND_KIND, OPND_NUM, FIRST_USE) JIT_OP_##NAME,
  309. #include "jit_ir.def"
  310. #undef INSN
  311. JIT_OP_OPCODE_NUMBER
  312. } JitOpcode;
  313. /*
  314. * Helper functions for creating new instructions. Don't call them
  315. * directly. Use jit_insn_new_NAME, such as jit_insn_new_MOV instead.
  316. */
  317. JitInsn *
  318. _jit_insn_new_Reg_0(JitOpcode opc);
  319. JitInsn *
  320. _jit_insn_new_Reg_1(JitOpcode opc, JitReg r0);
  321. JitInsn *
  322. _jit_insn_new_Reg_2(JitOpcode opc, JitReg r0, JitReg r1);
  323. JitInsn *
  324. _jit_insn_new_Reg_3(JitOpcode opc, JitReg r0, JitReg r1, JitReg r2);
  325. JitInsn *
  326. _jit_insn_new_Reg_4(JitOpcode opc, JitReg r0, JitReg r1, JitReg r2, JitReg r3);
  327. JitInsn *
  328. _jit_insn_new_Reg_5(JitOpcode opc, JitReg r0, JitReg r1, JitReg r2, JitReg r3,
  329. JitReg r4);
  330. JitInsn *
  331. _jit_insn_new_VReg_1(JitOpcode opc, JitReg r0, int n);
  332. JitInsn *
  333. _jit_insn_new_VReg_2(JitOpcode opc, JitReg r0, JitReg r1, int n);
  334. JitInsn *
  335. _jit_insn_new_LookupSwitch_1(JitOpcode opc, JitReg value, uint32 num);
  336. /*
  337. * Instruction creation functions jit_insn_new_NAME, where NAME is the
  338. * name of the instruction defined in jit_ir.def.
  339. */
  340. #define ARG_DECL_Reg_0
  341. #define ARG_LIST_Reg_0
  342. #define ARG_DECL_Reg_1 JitReg r0
  343. #define ARG_LIST_Reg_1 , r0
  344. #define ARG_DECL_Reg_2 JitReg r0, JitReg r1
  345. #define ARG_LIST_Reg_2 , r0, r1
  346. #define ARG_DECL_Reg_3 JitReg r0, JitReg r1, JitReg r2
  347. #define ARG_LIST_Reg_3 , r0, r1, r2
  348. #define ARG_DECL_Reg_4 JitReg r0, JitReg r1, JitReg r2, JitReg r3
  349. #define ARG_LIST_Reg_4 , r0, r1, r2, r3
  350. #define ARG_DECL_Reg_5 JitReg r0, JitReg r1, JitReg r2, JitReg r3, JitReg r4
  351. #define ARG_LIST_Reg_5 , r0, r1, r2, r3, r4
  352. #define ARG_DECL_VReg_1 JitReg r0, int n
  353. #define ARG_LIST_VReg_1 , r0, n
  354. #define ARG_DECL_VReg_2 JitReg r0, JitReg r1, int n
  355. #define ARG_LIST_VReg_2 , r0, r1, n
  356. #define ARG_DECL_LookupSwitch_1 JitReg value, uint32 num
  357. #define ARG_LIST_LookupSwitch_1 , value, num
  358. #define INSN(NAME, OPND_KIND, OPND_NUM, FIRST_USE) \
  359. static inline JitInsn *jit_insn_new_##NAME( \
  360. ARG_DECL_##OPND_KIND##_##OPND_NUM) \
  361. { \
  362. return _jit_insn_new_##OPND_KIND##_##OPND_NUM( \
  363. JIT_OP_##NAME ARG_LIST_##OPND_KIND##_##OPND_NUM); \
  364. }
  365. #include "jit_ir.def"
  366. #undef INSN
  367. #undef ARG_DECL_Reg_0
  368. #undef ARG_LIST_Reg_0
  369. #undef ARG_DECL_Reg_1
  370. #undef ARG_LIST_Reg_1
  371. #undef ARG_DECL_Reg_2
  372. #undef ARG_LIST_Reg_2
  373. #undef ARG_DECL_Reg_3
  374. #undef ARG_LIST_Reg_3
  375. #undef ARG_DECL_Reg_4
  376. #undef ARG_LIST_Reg_4
  377. #undef ARG_DECL_Reg_5
  378. #undef ARG_LIST_Reg_5
  379. #undef ARG_DECL_VReg_1
  380. #undef ARG_LIST_VReg_1
  381. #undef ARG_DECL_VReg_2
  382. #undef ARG_LIST_VReg_2
  383. #undef ARG_DECL_LookupSwitch_1
  384. #undef ARG_LIST_LookupSwitch_1
  385. /**
  386. * Delete an instruction
  387. *
  388. * @param insn an instruction to be deleted
  389. */
  390. static inline void
  391. jit_insn_delete(JitInsn *insn)
  392. {
  393. jit_free(insn);
  394. }
  395. /*
  396. * Runtime type check functions that check whether accessing the n-th
  397. * operand is legal. They are only used for in self-verification
  398. * mode.
  399. *
  400. * @param insn any JIT IR instruction
  401. * @param n index of the operand to access
  402. *
  403. * @return true if the access is legal
  404. */
  405. bool
  406. _jit_insn_check_opnd_access_Reg(const JitInsn *insn, unsigned n);
  407. bool
  408. _jit_insn_check_opnd_access_VReg(const JitInsn *insn, unsigned n);
  409. bool
  410. _jit_insn_check_opnd_access_LookupSwitch(const JitInsn *insn);
  411. /**
  412. * Get the pointer to the n-th register operand of the given
  413. * instruction. The instruction format must be Reg.
  414. *
  415. * @param insn a Reg format instruction
  416. * @param n index of the operand to get
  417. *
  418. * @return pointer to the n-th operand
  419. */
  420. static inline JitReg *
  421. jit_insn_opnd(JitInsn *insn, int n)
  422. {
  423. bh_assert(_jit_insn_check_opnd_access_Reg(insn, n));
  424. return &insn->_opnd._opnd_Reg[n];
  425. }
  426. /**
  427. * Get the pointer to the n-th register operand of the given
  428. * instruction. The instruction format must be VReg.
  429. *
  430. * @param insn a VReg format instruction
  431. * @param n index of the operand to get
  432. *
  433. * @return pointer to the n-th operand
  434. */
  435. static inline JitReg *
  436. jit_insn_opndv(JitInsn *insn, int n)
  437. {
  438. bh_assert(_jit_insn_check_opnd_access_VReg(insn, n));
  439. return &insn->_opnd._opnd_VReg._reg[n];
  440. }
  441. /**
  442. * Get the operand number of the given instruction. The instruction
  443. * format must be VReg.
  444. *
  445. * @param insn a VReg format instruction
  446. *
  447. * @return operand number of the instruction
  448. */
  449. static inline unsigned
  450. jit_insn_opndv_num(const JitInsn *insn)
  451. {
  452. bh_assert(_jit_insn_check_opnd_access_VReg(insn, 0));
  453. return insn->_opnd._opnd_VReg._reg_num;
  454. }
  455. /**
  456. * Get the pointer to the LookupSwitch operand of the given
  457. * instruction. The instruction format must be LookupSwitch.
  458. *
  459. * @param insn a LookupSwitch format instruction
  460. *
  461. * @return pointer to the operand
  462. */
  463. static inline JitOpndLookupSwitch *
  464. jit_insn_opndls(JitInsn *insn)
  465. {
  466. bh_assert(_jit_insn_check_opnd_access_LookupSwitch(insn));
  467. return &insn->_opnd._opnd_LookupSwitch;
  468. }
  469. /**
  470. * Insert instruction @p insn2 before instruction @p insn1.
  471. *
  472. * @param insn1 any instruction
  473. * @param insn2 any instruction
  474. */
  475. void
  476. jit_insn_insert_before(JitInsn *insn1, JitInsn *insn2);
  477. /**
  478. * Insert instruction @p insn2 after instruction @p insn1.
  479. *
  480. * @param insn1 any instruction
  481. * @param insn2 any instruction
  482. */
  483. void
  484. jit_insn_insert_after(JitInsn *insn1, JitInsn *insn2);
  485. /**
  486. * Unlink the instruction @p insn from the containing list.
  487. *
  488. * @param insn an instruction
  489. */
  490. void
  491. jit_insn_unlink(JitInsn *insn);
  492. /**
  493. * Get the hash value of the comparable instruction (pure functions
  494. * and exception check instructions).
  495. *
  496. * @param insn an instruction
  497. *
  498. * @return hash value of the instruction
  499. */
  500. unsigned
  501. jit_insn_hash(JitInsn *insn);
  502. /**
  503. * Compare whether the two comparable instructions are the same.
  504. *
  505. * @param insn1 the first instruction
  506. * @param insn2 the second instruction
  507. *
  508. * @return true if the two instructions are the same
  509. */
  510. bool
  511. jit_insn_equal(JitInsn *insn1, JitInsn *insn2);
  512. /**
  513. * Register vector for accessing predecessors and successors of a
  514. * basic block.
  515. */
  516. typedef struct JitRegVec {
  517. JitReg *_base; /* points to the first register */
  518. int32 _stride; /* stride to the next register */
  519. uint32 num; /* number of registers */
  520. } JitRegVec;
  521. /**
  522. * Get the address of the i-th register in the register vector.
  523. *
  524. * @param vec a register vector
  525. * @param i index to the register vector
  526. *
  527. * @return the address of the i-th register in the vector
  528. */
  529. static inline JitReg *
  530. jit_reg_vec_at(const JitRegVec *vec, unsigned i)
  531. {
  532. bh_assert(i < vec->num);
  533. return vec->_base + vec->_stride * i;
  534. }
  535. /**
  536. * Visit each element in a register vector.
  537. *
  538. * @param V (JitRegVec) the register vector
  539. * @param I (unsigned) index variable in the vector
  540. * @param R (JitReg *) resiger pointer variable
  541. */
  542. #define JIT_REG_VEC_FOREACH(V, I, R) \
  543. for ((I) = 0, (R) = (V)._base; (I) < (V).num; (I)++, (R) += (V)._stride)
  544. /**
  545. * Visit each register defined by an instruction.
  546. *
  547. * @param V (JitRegVec) register vector of the instruction
  548. * @param I (unsigned) index variable in the vector
  549. * @param R (JitReg *) resiger pointer variable
  550. * @param F index of the first used register
  551. */
  552. #define JIT_REG_VEC_FOREACH_DEF(V, I, R, F) \
  553. for ((I) = 0, (R) = (V)._base; (I) < (F); (I)++, (R) += (V)._stride)
  554. /**
  555. * Visit each register used by an instruction.
  556. *
  557. * @param V (JitRegVec) register vector of the instruction
  558. * @param I (unsigned) index variable in the vector
  559. * @param R (JitReg *) resiger pointer variable
  560. * @param F index of the first used register
  561. */
  562. #define JIT_REG_VEC_FOREACH_USE(V, I, R, F) \
  563. for ((I) = (F), (R) = (V)._base + (F) * (V)._stride; (I) < (V).num; \
  564. (I)++, (R) += (V)._stride)
  565. /**
  566. * Get a generic register vector that contains all register operands.
  567. * The registers defined by the instruction, if any, appear before the
  568. * registers used by the instruction.
  569. *
  570. * @param insn an instruction
  571. *
  572. * @return a register vector containing register operands
  573. */
  574. JitRegVec
  575. jit_insn_opnd_regs(JitInsn *insn);
  576. /**
  577. * Get the index of the first use register in the register vector
  578. * returned by jit_insn_opnd_regs.
  579. *
  580. * @param insn an instruction
  581. *
  582. * @return the index of the first use register in the register vector
  583. */
  584. unsigned
  585. jit_insn_opnd_first_use(JitInsn *insn);
  586. /**
  587. * Basic Block of JIT IR. It is a basic block only if the IR is not in
  588. * non-BB form. The block is represented by a special phi node, whose
  589. * result and arguments are label registers. The result label is the
  590. * containing block's label. The arguments are labels of predecessors
  591. * of the block. Successor labels are stored in the last instruction,
  592. * which must be a control flow instruction. Instructions of a block
  593. * are linked in a circular linked list with the block phi node as the
  594. * end of the list. The next and prev field of the block phi node
  595. * point to the first and last instructions of the block.
  596. */
  597. typedef JitInsn JitBasicBlock;
  598. /**
  599. * Create a new basic block instance.
  600. *
  601. * @param label the label of the new basic block
  602. * @param n number of predecessors
  603. *
  604. * @return the created new basic block instance
  605. */
  606. JitBasicBlock *
  607. jit_basic_block_new(JitReg label, int n);
  608. /**
  609. * Delete a basic block instance and all instructions init.
  610. *
  611. * @param block the basic block to be deleted
  612. */
  613. void
  614. jit_basic_block_delete(JitBasicBlock *block);
  615. /**
  616. * Get the label of the basic block.
  617. *
  618. * @param block a basic block instance
  619. *
  620. * @return the label of the basic block
  621. */
  622. static inline JitReg
  623. jit_basic_block_label(JitBasicBlock *block)
  624. {
  625. return *(jit_insn_opndv(block, 0));
  626. }
  627. /**
  628. * Get the first instruction of the basic block.
  629. *
  630. * @param block a basic block instance
  631. *
  632. * @return the first instruction of the basic block
  633. */
  634. static inline JitInsn *
  635. jit_basic_block_first_insn(JitBasicBlock *block)
  636. {
  637. return block->next;
  638. }
  639. /**
  640. * Get the last instruction of the basic block.
  641. *
  642. * @param block a basic block instance
  643. *
  644. * @return the last instruction of the basic block
  645. */
  646. static inline JitInsn *
  647. jit_basic_block_last_insn(JitBasicBlock *block)
  648. {
  649. return block->prev;
  650. }
  651. /**
  652. * Get the end of instruction list of the basic block (which is always
  653. * the block itself).
  654. *
  655. * @param block a basic block instance
  656. *
  657. * @return the end of instruction list of the basic block
  658. */
  659. static inline JitInsn *
  660. jit_basic_block_end_insn(JitBasicBlock *block)
  661. {
  662. return block;
  663. }
  664. /**
  665. * Visit each instruction in the block from the first to the last. In
  666. * the code block, the instruction pointer @p I must be a valid
  667. * pointer to an instruction in the block. That means if the
  668. * instruction may be deleted, @p I must point to the previous or next
  669. * valid instruction before the next iteration.
  670. *
  671. * @param B (JitBasicBlock *) the block
  672. * @param I (JitInsn *) instruction visited
  673. */
  674. #define JIT_FOREACH_INSN(B, I) \
  675. for (I = jit_basic_block_first_insn(B); I != jit_basic_block_end_insn(B); \
  676. I = I->next)
  677. /**
  678. * Visit each instruction in the block from the last to the first. In
  679. * the code block, the instruction pointer @p I must be a valid
  680. * pointer to an instruction in the block. That means if the
  681. * instruction may be deleted, @p I must point to the previous or next
  682. * valid instruction before the next iteration.
  683. *
  684. * @param B (JitBasicBlock *) the block
  685. * @param I (JitInsn *) instruction visited
  686. */
  687. #define JIT_FOREACH_INSN_REVERSE(B, I) \
  688. for (I = jit_basic_block_last_insn(B); I != jit_basic_block_end_insn(B); \
  689. I = I->prev)
  690. /**
  691. * Prepend an instruction in the front of the block. The position is
  692. * just after the block phi node (the block instance itself).
  693. *
  694. * @param block a block
  695. * @param insn an instruction to be prepended
  696. */
  697. static inline void
  698. jit_basic_block_prepend_insn(JitBasicBlock *block, JitInsn *insn)
  699. {
  700. jit_insn_insert_after(block, insn);
  701. }
  702. /**
  703. * Append an instruction to the end of the basic block.
  704. *
  705. * @param block a basic block
  706. * @param insn an instruction to be appended
  707. */
  708. static inline void
  709. jit_basic_block_append_insn(JitBasicBlock *block, JitInsn *insn)
  710. {
  711. jit_insn_insert_before(block, insn);
  712. }
  713. /**
  714. * Get the register vector of predecessors of a basic block.
  715. *
  716. * @param block a JIT IR block
  717. *
  718. * @return register vector of the predecessors
  719. */
  720. JitRegVec
  721. jit_basic_block_preds(JitBasicBlock *block);
  722. /**
  723. * Get the register vector of successors of a basic block.
  724. *
  725. * @param block a JIT IR basic block
  726. *
  727. * @return register vector of the successors
  728. */
  729. JitRegVec
  730. jit_basic_block_succs(JitBasicBlock *block);
  731. /**
  732. * Hard register information of one kind.
  733. */
  734. typedef struct JitHardRegInfo {
  735. struct {
  736. /* Hard register number of this kind. */
  737. uint32 num;
  738. /* Whether each register is fixed. */
  739. const uint8 *fixed;
  740. /* Whether each register is caller-saved in the native ABI. */
  741. const uint8 *caller_saved_native;
  742. /* Whether each register is caller-saved in the JITed ABI. */
  743. const uint8 *caller_saved_jitted;
  744. } info[JIT_REG_KIND_L32];
  745. /* The indexes of hard registers of frame pointer, exec_env and cmp. */
  746. uint32 fp_hreg_index;
  747. uint32 exec_env_hreg_index;
  748. uint32 cmp_hreg_index;
  749. } JitHardRegInfo;
  750. struct JitBlock;
  751. struct JitCompContext;
  752. struct JitValueSlot;
  753. /**
  754. * Value in the WASM operation stack, each stack element
  755. * is a Jit register
  756. */
  757. typedef struct JitValue {
  758. struct JitValue *next;
  759. struct JitValue *prev;
  760. struct JitValueSlot *value;
  761. /* VALUE_TYPE_I32/I64/F32/F64/VOID */
  762. uint8 type;
  763. } JitValue;
  764. /**
  765. * Value stack, represents stack elements in a WASM block
  766. */
  767. typedef struct JitValueStack {
  768. JitValue *value_list_head;
  769. JitValue *value_list_end;
  770. } JitValueStack;
  771. /* Record information of a value slot of local variable or stack
  772. during translation. */
  773. typedef struct JitValueSlot {
  774. /* The virtual register that holds the value of the slot if the
  775. value of the slot is in register. */
  776. JitReg reg;
  777. /* The dirty bit of the value slot. It's set if the value in
  778. register is newer than the value in memory. */
  779. uint32 dirty : 1;
  780. /* Whether the new value in register is a reference, which is valid
  781. only when the dirty bit is set. */
  782. uint32 ref : 1;
  783. /* Committed reference flag. 0: unknown, 1: not-reference, 2:
  784. reference. */
  785. uint32 committed_ref : 2;
  786. } JitValueSlot;
  787. typedef struct JitMemRegs {
  788. /* The following registers should be re-loaded after
  789. memory.grow, callbc and callnative */
  790. JitReg memory_inst;
  791. JitReg cur_page_count;
  792. JitReg memory_data;
  793. JitReg memory_data_end;
  794. JitReg mem_bound_check_1byte;
  795. JitReg mem_bound_check_2bytes;
  796. JitReg mem_bound_check_4bytes;
  797. JitReg mem_bound_check_8bytes;
  798. JitReg mem_bound_check_16bytes;
  799. } JitMemRegs;
  800. typedef struct JitTableRegs {
  801. JitReg table_elems;
  802. /* Should be re-loaded after table.grow,
  803. callbc and callnative */
  804. JitReg table_cur_size;
  805. } JitTableRegs;
  806. /* Frame information for translation */
  807. typedef struct JitFrame {
  808. /* The current wasm module */
  809. WASMModule *cur_wasm_module;
  810. /* The current wasm function */
  811. WASMFunction *cur_wasm_func;
  812. /* The current wasm function index */
  813. uint32 cur_wasm_func_idx;
  814. /* The current compilation context */
  815. struct JitCompContext *cc;
  816. /* Max local slot number. */
  817. uint32 max_locals;
  818. /* Max operand stack slot number. */
  819. uint32 max_stacks;
  820. /* Instruction pointer */
  821. uint8 *ip;
  822. /* Stack top pointer */
  823. JitValueSlot *sp;
  824. /* Committed instruction pointer */
  825. uint8 *committed_ip;
  826. /* Committed stack top pointer */
  827. JitValueSlot *committed_sp;
  828. /* WASM module instance */
  829. JitReg module_inst_reg;
  830. /* WASM module */
  831. JitReg module_reg;
  832. /* module_inst->import_func_ptrs */
  833. JitReg import_func_ptrs_reg;
  834. /* module_inst->fast_jit_func_ptrs */
  835. JitReg fast_jit_func_ptrs_reg;
  836. /* module_inst->func_type_indexes */
  837. JitReg func_type_indexes_reg;
  838. /* Boundary of auxiliary stack */
  839. JitReg aux_stack_bound_reg;
  840. /* Bottom of auxiliary stack */
  841. JitReg aux_stack_bottom_reg;
  842. /* Data of memory instances */
  843. JitMemRegs *memory_regs;
  844. /* Data of table instances */
  845. JitTableRegs *table_regs;
  846. /* Local variables */
  847. JitValueSlot lp[1];
  848. } JitFrame;
  849. typedef struct JitIncomingInsn {
  850. struct JitIncomingInsn *next;
  851. JitInsn *insn;
  852. uint32 opnd_idx;
  853. } JitIncomingInsn, *JitIncomingInsnList;
  854. typedef struct JitBlock {
  855. struct JitBlock *next;
  856. struct JitBlock *prev;
  857. /* The current Jit Block */
  858. struct JitCompContext *cc;
  859. /* LABEL_TYPE_BLOCK/LOOP/IF/FUNCTION */
  860. uint32 label_type;
  861. /* code of else opcode of this block, if it is a IF block */
  862. uint8 *wasm_code_else;
  863. /* code of end opcode of this block */
  864. uint8 *wasm_code_end;
  865. /* JIT label points to code begin */
  866. JitBasicBlock *basic_block_entry;
  867. /* JIT label points to code else */
  868. JitBasicBlock *basic_block_else;
  869. /* JIT label points to code end */
  870. JitBasicBlock *basic_block_end;
  871. /* Incoming INSN for basic_block_else */
  872. JitInsn *incoming_insn_for_else_bb;
  873. /* Incoming INSNs for basic_block_end */
  874. JitIncomingInsnList incoming_insns_for_end_bb;
  875. /* WASM operation stack */
  876. JitValueStack value_stack;
  877. /* Param count/types/PHIs of this block */
  878. uint32 param_count;
  879. uint8 *param_types;
  880. /* Result count/types/PHIs of this block */
  881. uint32 result_count;
  882. uint8 *result_types;
  883. /* The begin frame stack pointer of this block */
  884. JitValueSlot *frame_sp_begin;
  885. } JitBlock;
  886. /**
  887. * Block stack, represents WASM block stack elements
  888. */
  889. typedef struct JitBlockStack {
  890. JitBlock *block_list_head;
  891. JitBlock *block_list_end;
  892. } JitBlockStack;
  893. /**
  894. * The JIT compilation context for one compilation process of a
  895. * compilation unit.
  896. */
  897. typedef struct JitCompContext {
  898. /* Hard register information of each kind. */
  899. const JitHardRegInfo *hreg_info;
  900. /* No. of the pass to be applied. */
  901. uint8 cur_pass_no;
  902. /* The current wasm module */
  903. WASMModule *cur_wasm_module;
  904. /* The current wasm function */
  905. WASMFunction *cur_wasm_func;
  906. /* The current wasm function index */
  907. uint32 cur_wasm_func_idx;
  908. /* The block stack */
  909. JitBlockStack block_stack;
  910. bool mem_space_unchanged;
  911. /* Entry and exit labels of the compilation unit, whose numbers must
  912. be 0 and 1 respectively (see JIT_FOREACH_BLOCK). */
  913. JitReg entry_label;
  914. JitReg exit_label;
  915. JitBasicBlock **exce_basic_blocks;
  916. JitIncomingInsnList *incoming_insns_for_exec_bbs;
  917. /* The current basic block to generate instructions */
  918. JitBasicBlock *cur_basic_block;
  919. /* Registers of frame pointer, exec_env and CMP result. */
  920. JitReg fp_reg;
  921. JitReg exec_env_reg;
  922. JitReg cmp_reg;
  923. /* WASM module instance */
  924. JitReg module_inst_reg;
  925. /* WASM module */
  926. JitReg module_reg;
  927. /* module_inst->import_func_ptrs */
  928. JitReg import_func_ptrs_reg;
  929. /* module_inst->fast_jit_func_ptrs */
  930. JitReg fast_jit_func_ptrs_reg;
  931. /* module_inst->func_type_indexes */
  932. JitReg func_type_indexes_reg;
  933. /* Boundary of auxiliary stack */
  934. JitReg aux_stack_bound_reg;
  935. /* Bottom of auxiliary stack */
  936. JitReg aux_stack_bottom_reg;
  937. /* Data of memory instances */
  938. JitMemRegs *memory_regs;
  939. /* Data of table instances */
  940. JitTableRegs *table_regs;
  941. /* Current frame information for translation */
  942. JitFrame *jit_frame;
  943. /* The total frame size of current function */
  944. uint32 total_frame_size;
  945. /* The spill cache offset to the interp frame */
  946. uint32 spill_cache_offset;
  947. /* The spill cache size */
  948. uint32 spill_cache_size;
  949. /* The offset of jitted_return_address in the frame, which is set by
  950. the pass frontend and used by the pass codegen. */
  951. uint32 jitted_return_address_offset;
  952. /* Begin and end addresses of the jitted code produced by the pass
  953. codegen and consumed by the region registration after codegen and
  954. the pass dump. */
  955. void *jitted_addr_begin;
  956. void *jitted_addr_end;
  957. char last_error[128];
  958. /* Below fields are all private. Don't access them directly. */
  959. /* Reference count of the compilation context. */
  960. uint16 _reference_count;
  961. /* Constant values. */
  962. struct {
  963. /* Number of constant values of each kind. */
  964. uint32 _num[JIT_REG_KIND_L32];
  965. /* Capacity of register annotations of each kind. */
  966. uint32 _capacity[JIT_REG_KIND_L32];
  967. /* Constant values of each kind. */
  968. uint8 *_value[JIT_REG_KIND_L32];
  969. /* Next element on the list of values with the same hash code. */
  970. JitReg *_next[JIT_REG_KIND_L32];
  971. /* Size of the hash table. */
  972. uint32 _hash_table_size;
  973. /* Map values to JIT register. */
  974. JitReg *_hash_table;
  975. } _const_val;
  976. /* Annotations of labels, registers and instructions. */
  977. struct {
  978. /* Number of all ever created labels. */
  979. uint32 _label_num;
  980. /* Capacity of label annotations. */
  981. uint32 _label_capacity;
  982. /* Number of all ever created instructions. */
  983. uint32 _insn_num;
  984. /* Capacity of instruction annotations. */
  985. uint32 _insn_capacity;
  986. /* Number of ever created registers of each kind. */
  987. uint32 _reg_num[JIT_REG_KIND_L32];
  988. /* Capacity of register annotations of each kind. */
  989. uint32 _reg_capacity[JIT_REG_KIND_L32];
  990. /* Storage of annotations. */
  991. #define ANN_LABEL(TYPE, NAME) TYPE *_label_##NAME;
  992. #define ANN_INSN(TYPE, NAME) TYPE *_insn_##NAME;
  993. #define ANN_REG(TYPE, NAME) TYPE *_reg_##NAME[JIT_REG_KIND_L32];
  994. #include "jit_ir.def"
  995. #undef ANN_LABEL
  996. #undef ANN_INSN
  997. #undef ANN_REG
  998. /* Flags of annotations. */
  999. #define ANN_LABEL(TYPE, NAME) uint32 _label_##NAME##_enabled : 1;
  1000. #define ANN_INSN(TYPE, NAME) uint32 _insn_##NAME##_enabled : 1;
  1001. #define ANN_REG(TYPE, NAME) uint32 _reg_##NAME##_enabled : 1;
  1002. #include "jit_ir.def"
  1003. #undef ANN_LABEL
  1004. #undef ANN_INSN
  1005. #undef ANN_REG
  1006. } _ann;
  1007. /* Instruction hash table. */
  1008. struct {
  1009. /* Size of the hash table. */
  1010. uint32 _size;
  1011. /* The hash table. */
  1012. JitInsn **_table;
  1013. } _insn_hash_table;
  1014. /* indicate if the last comparison is about floating-point numbers or not
  1015. */
  1016. bool last_cmp_on_fp;
  1017. } JitCompContext;
  1018. /*
  1019. * Annotation accessing functions jit_annl_NAME, jit_anni_NAME and
  1020. * jit_annr_NAME.
  1021. */
  1022. #define ANN_LABEL(TYPE, NAME) \
  1023. static inline TYPE *jit_annl_##NAME(JitCompContext *cc, JitReg label) \
  1024. { \
  1025. unsigned idx = jit_reg_no(label); \
  1026. bh_assert(jit_reg_kind(label) == JIT_REG_KIND_L32); \
  1027. bh_assert(idx < cc->_ann._label_num); \
  1028. bh_assert(cc->_ann._label_##NAME##_enabled); \
  1029. return &cc->_ann._label_##NAME[idx]; \
  1030. }
  1031. #define ANN_INSN(TYPE, NAME) \
  1032. static inline TYPE *jit_anni_##NAME(JitCompContext *cc, JitInsn *insn) \
  1033. { \
  1034. unsigned uid = insn->uid; \
  1035. bh_assert(uid < cc->_ann._insn_num); \
  1036. bh_assert(cc->_ann._insn_##NAME##_enabled); \
  1037. return &cc->_ann._insn_##NAME[uid]; \
  1038. }
  1039. #define ANN_REG(TYPE, NAME) \
  1040. static inline TYPE *jit_annr_##NAME(JitCompContext *cc, JitReg reg) \
  1041. { \
  1042. unsigned kind = jit_reg_kind(reg); \
  1043. unsigned no = jit_reg_no(reg); \
  1044. bh_assert(kind < JIT_REG_KIND_L32); \
  1045. bh_assert(no < cc->_ann._reg_num[kind]); \
  1046. bh_assert(cc->_ann._reg_##NAME##_enabled); \
  1047. return &cc->_ann._reg_##NAME[kind][no]; \
  1048. }
  1049. #include "jit_ir.def"
  1050. #undef ANN_LABEL
  1051. #undef ANN_INSN
  1052. #undef ANN_REG
  1053. /*
  1054. * Annotation enabling functions jit_annl_enable_NAME,
  1055. * jit_anni_enable_NAME and jit_annr_enable_NAME, which allocate
  1056. * sufficient memory for the annotations.
  1057. */
  1058. #define ANN_LABEL(TYPE, NAME) bool jit_annl_enable_##NAME(JitCompContext *cc);
  1059. #define ANN_INSN(TYPE, NAME) bool jit_anni_enable_##NAME(JitCompContext *cc);
  1060. #define ANN_REG(TYPE, NAME) bool jit_annr_enable_##NAME(JitCompContext *cc);
  1061. #include "jit_ir.def"
  1062. #undef ANN_LABEL
  1063. #undef ANN_INSN
  1064. #undef ANN_REG
  1065. /*
  1066. * Annotation disabling functions jit_annl_disable_NAME,
  1067. * jit_anni_disable_NAME and jit_annr_disable_NAME, which release
  1068. * memory of the annotations. Before calling these functions,
  1069. * resources owned by the annotations must be explicitly released.
  1070. */
  1071. #define ANN_LABEL(TYPE, NAME) void jit_annl_disable_##NAME(JitCompContext *cc);
  1072. #define ANN_INSN(TYPE, NAME) void jit_anni_disable_##NAME(JitCompContext *cc);
  1073. #define ANN_REG(TYPE, NAME) void jit_annr_disable_##NAME(JitCompContext *cc);
  1074. #include "jit_ir.def"
  1075. #undef ANN_LABEL
  1076. #undef ANN_INSN
  1077. #undef ANN_REG
  1078. /*
  1079. * Functions jit_annl_is_enabled_NAME, jit_anni_is_enabled_NAME and
  1080. * jit_annr_is_enabled_NAME for checking whether an annotation is
  1081. * enabled.
  1082. */
  1083. #define ANN_LABEL(TYPE, NAME) \
  1084. static inline bool jit_annl_is_enabled_##NAME(JitCompContext *cc) \
  1085. { \
  1086. return !!cc->_ann._label_##NAME##_enabled; \
  1087. }
  1088. #define ANN_INSN(TYPE, NAME) \
  1089. static inline bool jit_anni_is_enabled_##NAME(JitCompContext *cc) \
  1090. { \
  1091. return !!cc->_ann._insn_##NAME##_enabled; \
  1092. }
  1093. #define ANN_REG(TYPE, NAME) \
  1094. static inline bool jit_annr_is_enabled_##NAME(JitCompContext *cc) \
  1095. { \
  1096. return !!cc->_ann._reg_##NAME##_enabled; \
  1097. }
  1098. #include "jit_ir.def"
  1099. #undef ANN_LABEL
  1100. #undef ANN_INSN
  1101. #undef ANN_REG
  1102. /**
  1103. * Initialize a compilation context.
  1104. *
  1105. * @param cc the compilation context
  1106. * @param htab_size the initial hash table size of constant pool
  1107. *
  1108. * @return cc if succeeds, NULL otherwise
  1109. */
  1110. JitCompContext *
  1111. jit_cc_init(JitCompContext *cc, unsigned htab_size);
  1112. /**
  1113. * Release all resources of a compilation context, which doesn't
  1114. * include the compilation context itself.
  1115. *
  1116. * @param cc the compilation context
  1117. */
  1118. void
  1119. jit_cc_destroy(JitCompContext *cc);
  1120. /**
  1121. * Increase the reference count of the compilation context.
  1122. *
  1123. * @param cc the compilation context
  1124. */
  1125. static inline void
  1126. jit_cc_inc_ref(JitCompContext *cc)
  1127. {
  1128. cc->_reference_count++;
  1129. }
  1130. /**
  1131. * Decrease the reference_count and destroy and free the compilation
  1132. * context if the reference_count is decreased to zero.
  1133. *
  1134. * @param cc the compilation context
  1135. */
  1136. void
  1137. jit_cc_delete(JitCompContext *cc);
  1138. char *
  1139. jit_get_last_error(JitCompContext *cc);
  1140. void
  1141. jit_set_last_error(JitCompContext *cc, const char *error);
  1142. void
  1143. jit_set_last_error_v(JitCompContext *cc, const char *format, ...);
  1144. /**
  1145. * Create a I32 constant value with relocatable into the compilation
  1146. * context. A constant value that has relocation info cannot be
  1147. * constant-folded as normal constants because its value depends on
  1148. * runtime context and may be different in different executions.
  1149. *
  1150. * @param cc compilation context
  1151. * @param val a I32 value
  1152. * @param rel relocation information
  1153. *
  1154. * @return a constant register containing the value
  1155. */
  1156. JitReg
  1157. jit_cc_new_const_I32_rel(JitCompContext *cc, int32 val, uint32 rel);
  1158. /**
  1159. * Create a I32 constant value without relocation info (0) into the
  1160. * compilation context.
  1161. *
  1162. * @param cc compilation context
  1163. * @param val a I32 value
  1164. *
  1165. * @return a constant register containing the value
  1166. */
  1167. static inline JitReg
  1168. jit_cc_new_const_I32(JitCompContext *cc, int32 val)
  1169. {
  1170. return jit_cc_new_const_I32_rel(cc, val, 0);
  1171. }
  1172. /**
  1173. * Create a I64 constant value into the compilation context.
  1174. *
  1175. * @param cc compilation context
  1176. * @param val a I64 value
  1177. *
  1178. * @return a constant register containing the value
  1179. */
  1180. JitReg
  1181. jit_cc_new_const_I64(JitCompContext *cc, int64 val);
  1182. #if UINTPTR_MAX == UINT64_MAX
  1183. #define jit_cc_new_const_PTR jit_cc_new_const_I64
  1184. #else
  1185. #define jit_cc_new_const_PTR jit_cc_new_const_I32
  1186. #endif
  1187. /**
  1188. * Create a F32 constant value into the compilation context.
  1189. *
  1190. * @param cc compilation context
  1191. * @param val a F32 value
  1192. *
  1193. * @return a constant register containing the value
  1194. */
  1195. JitReg
  1196. jit_cc_new_const_F32(JitCompContext *cc, float val);
  1197. /**
  1198. * Create a F64 constant value into the compilation context.
  1199. *
  1200. * @param cc compilation context
  1201. * @param val a F64 value
  1202. *
  1203. * @return a constant register containing the value
  1204. */
  1205. JitReg
  1206. jit_cc_new_const_F64(JitCompContext *cc, double val);
  1207. /**
  1208. * Get the relocation info of a I32 constant register.
  1209. *
  1210. * @param cc compilation context
  1211. * @param reg constant register
  1212. *
  1213. * @return the relocation info of the constant
  1214. */
  1215. uint32
  1216. jit_cc_get_const_I32_rel(JitCompContext *cc, JitReg reg);
  1217. /**
  1218. * Get the constant value of a I32 constant register.
  1219. *
  1220. * @param cc compilation context
  1221. * @param reg constant register
  1222. *
  1223. * @return the constant value
  1224. */
  1225. int32
  1226. jit_cc_get_const_I32(JitCompContext *cc, JitReg reg);
  1227. /**
  1228. * Get the constant value of a I64 constant register.
  1229. *
  1230. * @param cc compilation context
  1231. * @param reg constant register
  1232. *
  1233. * @return the constant value
  1234. */
  1235. int64
  1236. jit_cc_get_const_I64(JitCompContext *cc, JitReg reg);
  1237. /**
  1238. * Get the constant value of a F32 constant register.
  1239. *
  1240. * @param cc compilation context
  1241. * @param reg constant register
  1242. *
  1243. * @return the constant value
  1244. */
  1245. float
  1246. jit_cc_get_const_F32(JitCompContext *cc, JitReg reg);
  1247. /**
  1248. * Get the constant value of a F64 constant register.
  1249. *
  1250. * @param cc compilation context
  1251. * @param reg constant register
  1252. *
  1253. * @return the constant value
  1254. */
  1255. double
  1256. jit_cc_get_const_F64(JitCompContext *cc, JitReg reg);
  1257. /**
  1258. * Get the number of total created labels.
  1259. *
  1260. * @param cc the compilation context
  1261. *
  1262. * @return the number of total created labels
  1263. */
  1264. static inline unsigned
  1265. jit_cc_label_num(JitCompContext *cc)
  1266. {
  1267. return cc->_ann._label_num;
  1268. }
  1269. /**
  1270. * Get the number of total created instructions.
  1271. *
  1272. * @param cc the compilation context
  1273. *
  1274. * @return the number of total created instructions
  1275. */
  1276. static inline unsigned
  1277. jit_cc_insn_num(JitCompContext *cc)
  1278. {
  1279. return cc->_ann._insn_num;
  1280. }
  1281. /**
  1282. * Get the number of total created registers.
  1283. *
  1284. * @param cc the compilation context
  1285. * @param kind the register kind
  1286. *
  1287. * @return the number of total created registers
  1288. */
  1289. static inline unsigned
  1290. jit_cc_reg_num(JitCompContext *cc, unsigned kind)
  1291. {
  1292. bh_assert(kind < JIT_REG_KIND_L32);
  1293. return cc->_ann._reg_num[kind];
  1294. }
  1295. /**
  1296. * Create a new label in the compilation context.
  1297. *
  1298. * @param cc the compilation context
  1299. *
  1300. * @return a new label in the compilation context
  1301. */
  1302. JitReg
  1303. jit_cc_new_label(JitCompContext *cc);
  1304. /**
  1305. * Create a new block with a new label in the compilation context.
  1306. *
  1307. * @param cc the compilation context
  1308. * @param n number of predecessors
  1309. *
  1310. * @return a new block with a new label in the compilation context
  1311. */
  1312. JitBasicBlock *
  1313. jit_cc_new_basic_block(JitCompContext *cc, int n);
  1314. /**
  1315. * Resize the predecessor number of a block.
  1316. *
  1317. * @param cc the containing compilation context
  1318. * @param block block to be resized
  1319. * @param n new number of predecessors
  1320. *
  1321. * @return the new block if succeeds, NULL otherwise
  1322. */
  1323. JitBasicBlock *
  1324. jit_cc_resize_basic_block(JitCompContext *cc, JitBasicBlock *block, int n);
  1325. /**
  1326. * Initialize the instruction hash table to the given size and enable
  1327. * the instruction's _hash_link annotation.
  1328. *
  1329. * @param cc the containing compilation context
  1330. * @param n size of the hash table
  1331. *
  1332. * @return true if succeeds, false otherwise
  1333. */
  1334. bool
  1335. jit_cc_enable_insn_hash(JitCompContext *cc, unsigned n);
  1336. /**
  1337. * Destroy the instruction hash table and disable the instruction's
  1338. * _hash_link annotation.
  1339. *
  1340. * @param cc the containing compilation context
  1341. */
  1342. void
  1343. jit_cc_disable_insn_hash(JitCompContext *cc);
  1344. /**
  1345. * Reset the hash table entries.
  1346. *
  1347. * @param cc the containing compilation context
  1348. */
  1349. void
  1350. jit_cc_reset_insn_hash(JitCompContext *cc);
  1351. /**
  1352. * Allocate a new instruction ID in the compilation context and set it
  1353. * to the given instruction.
  1354. *
  1355. * @param cc the compilation context
  1356. * @param insn IR instruction
  1357. *
  1358. * @return the insn with uid being set
  1359. */
  1360. JitInsn *
  1361. jit_cc_set_insn_uid(JitCompContext *cc, JitInsn *insn);
  1362. /*
  1363. * Similar to jit_cc_set_insn_uid except that if setting uid failed,
  1364. * delete the insn. Only used by jit_cc_new_insn
  1365. */
  1366. JitInsn *
  1367. _jit_cc_set_insn_uid_for_new_insn(JitCompContext *cc, JitInsn *insn);
  1368. /**
  1369. * Create a new instruction in the compilation context.
  1370. *
  1371. * @param cc the compilationo context
  1372. * @param NAME instruction name
  1373. *
  1374. * @return a new instruction in the compilation context
  1375. */
  1376. #define jit_cc_new_insn(cc, NAME, ...) \
  1377. _jit_cc_set_insn_uid_for_new_insn(cc, jit_insn_new_##NAME(__VA_ARGS__))
  1378. /*
  1379. * Helper function for jit_cc_new_insn_norm.
  1380. */
  1381. JitInsn *
  1382. _jit_cc_new_insn_norm(JitCompContext *cc, JitReg *result, JitInsn *insn);
  1383. /**
  1384. * Create a new instruction in the compilation context and normalize
  1385. * the instruction (constant folding and simplification etc.). If the
  1386. * instruction hashing is enabled (anni__hash_link is enabled), try to
  1387. * find the existing equivalent insruction first before adding a new
  1388. * one to the compilation contest.
  1389. *
  1390. * @param cc the compilationo context
  1391. * @param result returned result of the instruction. If the value is
  1392. * non-zero, it is the result of the constant-folding or an existing
  1393. * equivalent instruction, in which case no instruction is added into
  1394. * the compilation context. Otherwise, a new normalized instruction
  1395. * has been added into the compilation context.
  1396. * @param NAME instruction name
  1397. *
  1398. * @return a new or existing instruction in the compilation context
  1399. */
  1400. #define jit_cc_new_insn_norm(cc, result, NAME, ...) \
  1401. _jit_cc_new_insn_norm(cc, result, jit_insn_new_##NAME(__VA_ARGS__))
  1402. /**
  1403. * Helper function for GEN_INSN
  1404. *
  1405. * @param cc compilation context
  1406. * @param block the current block
  1407. * @param insn the new instruction
  1408. *
  1409. * @return the new instruction if inserted, NULL otherwise
  1410. */
  1411. static inline JitInsn *
  1412. _gen_insn(JitCompContext *cc, JitInsn *insn)
  1413. {
  1414. if (insn)
  1415. jit_basic_block_append_insn(cc->cur_basic_block, insn);
  1416. else
  1417. jit_set_last_error(cc, "generate insn failed");
  1418. return insn;
  1419. }
  1420. /**
  1421. * Generate and append an instruction to the current block.
  1422. */
  1423. #define GEN_INSN(...) _gen_insn(cc, jit_cc_new_insn(cc, __VA_ARGS__))
  1424. /**
  1425. * Create a constant register without relocation info.
  1426. *
  1427. * @param Type type of the register
  1428. * @param val the constant value
  1429. *
  1430. * @return the constant register if succeeds, 0 otherwise
  1431. */
  1432. #define NEW_CONST(Type, val) jit_cc_new_const_##Type(cc, val)
  1433. /**
  1434. * Create a new virtual register in the compilation context.
  1435. *
  1436. * @param cc the compilation context
  1437. * @param kind kind of the register
  1438. *
  1439. * @return a new label in the compilation context
  1440. */
  1441. JitReg
  1442. jit_cc_new_reg(JitCompContext *cc, unsigned kind);
  1443. /*
  1444. * Create virtual registers with specific types in the compilation
  1445. * context. They are more convenient than the above one.
  1446. */
  1447. static inline JitReg
  1448. jit_cc_new_reg_I32(JitCompContext *cc)
  1449. {
  1450. return jit_cc_new_reg(cc, JIT_REG_KIND_I32);
  1451. }
  1452. static inline JitReg
  1453. jit_cc_new_reg_I64(JitCompContext *cc)
  1454. {
  1455. return jit_cc_new_reg(cc, JIT_REG_KIND_I64);
  1456. }
  1457. #if UINTPTR_MAX == UINT64_MAX
  1458. #define jit_cc_new_reg_ptr jit_cc_new_reg_I64
  1459. #else
  1460. #define jit_cc_new_reg_ptr jit_cc_new_reg_I32
  1461. #endif
  1462. static inline JitReg
  1463. jit_cc_new_reg_F32(JitCompContext *cc)
  1464. {
  1465. return jit_cc_new_reg(cc, JIT_REG_KIND_F32);
  1466. }
  1467. static inline JitReg
  1468. jit_cc_new_reg_F64(JitCompContext *cc)
  1469. {
  1470. return jit_cc_new_reg(cc, JIT_REG_KIND_F64);
  1471. }
  1472. static inline JitReg
  1473. jit_cc_new_reg_V64(JitCompContext *cc)
  1474. {
  1475. return jit_cc_new_reg(cc, JIT_REG_KIND_V64);
  1476. }
  1477. static inline JitReg
  1478. jit_cc_new_reg_V128(JitCompContext *cc)
  1479. {
  1480. return jit_cc_new_reg(cc, JIT_REG_KIND_V128);
  1481. }
  1482. static inline JitReg
  1483. jit_cc_new_reg_V256(JitCompContext *cc)
  1484. {
  1485. return jit_cc_new_reg(cc, JIT_REG_KIND_V256);
  1486. }
  1487. /**
  1488. * Get the hard register numbe of the given kind
  1489. *
  1490. * @param cc the compilation context
  1491. * @param kind the register kind
  1492. *
  1493. * @return number of hard registers of the given kind
  1494. */
  1495. static inline unsigned
  1496. jit_cc_hreg_num(JitCompContext *cc, unsigned kind)
  1497. {
  1498. bh_assert(kind < JIT_REG_KIND_L32);
  1499. return cc->hreg_info->info[kind].num;
  1500. }
  1501. /**
  1502. * Check whether a given register is a hard register.
  1503. *
  1504. * @param cc the compilation context
  1505. * @param reg the register which must be a variable
  1506. *
  1507. * @return true if the register is a hard register
  1508. */
  1509. static inline bool
  1510. jit_cc_is_hreg(JitCompContext *cc, JitReg reg)
  1511. {
  1512. unsigned kind = jit_reg_kind(reg);
  1513. unsigned no = jit_reg_no(reg);
  1514. bh_assert(jit_reg_is_variable(reg));
  1515. bh_assert(kind < JIT_REG_KIND_L32);
  1516. return no < cc->hreg_info->info[kind].num;
  1517. }
  1518. /**
  1519. * Check whether the given hard register is fixed.
  1520. *
  1521. * @param cc the compilation context
  1522. * @param reg the hard register
  1523. *
  1524. * @return true if the hard register is fixed
  1525. */
  1526. static inline bool
  1527. jit_cc_is_hreg_fixed(JitCompContext *cc, JitReg reg)
  1528. {
  1529. unsigned kind = jit_reg_kind(reg);
  1530. unsigned no = jit_reg_no(reg);
  1531. bh_assert(jit_cc_is_hreg(cc, reg));
  1532. bh_assert(kind < JIT_REG_KIND_L32);
  1533. return !!cc->hreg_info->info[kind].fixed[no];
  1534. }
  1535. /**
  1536. * Check whether the given hard register is caller-saved-native.
  1537. *
  1538. * @param cc the compilation context
  1539. * @param reg the hard register
  1540. *
  1541. * @return true if the hard register is caller-saved-native
  1542. */
  1543. static inline bool
  1544. jit_cc_is_hreg_caller_saved_native(JitCompContext *cc, JitReg reg)
  1545. {
  1546. unsigned kind = jit_reg_kind(reg);
  1547. unsigned no = jit_reg_no(reg);
  1548. bh_assert(jit_cc_is_hreg(cc, reg));
  1549. bh_assert(kind < JIT_REG_KIND_L32);
  1550. return !!cc->hreg_info->info[kind].caller_saved_native[no];
  1551. }
  1552. /**
  1553. * Check whether the given hard register is caller-saved-jitted.
  1554. *
  1555. * @param cc the compilation context
  1556. * @param reg the hard register
  1557. *
  1558. * @return true if the hard register is caller-saved-jitted
  1559. */
  1560. static inline bool
  1561. jit_cc_is_hreg_caller_saved_jitted(JitCompContext *cc, JitReg reg)
  1562. {
  1563. unsigned kind = jit_reg_kind(reg);
  1564. unsigned no = jit_reg_no(reg);
  1565. bh_assert(jit_cc_is_hreg(cc, reg));
  1566. bh_assert(kind < JIT_REG_KIND_L32);
  1567. return !!cc->hreg_info->info[kind].caller_saved_jitted[no];
  1568. }
  1569. /**
  1570. * Return the entry block of the compilation context.
  1571. *
  1572. * @param cc the compilation context
  1573. *
  1574. * @return the entry block of the compilation context
  1575. */
  1576. static inline JitBasicBlock *
  1577. jit_cc_entry_basic_block(JitCompContext *cc)
  1578. {
  1579. return *(jit_annl_basic_block(cc, cc->entry_label));
  1580. }
  1581. /**
  1582. * Return the exit block of the compilation context.
  1583. *
  1584. * @param cc the compilation context
  1585. *
  1586. * @return the exit block of the compilation context
  1587. */
  1588. static inline JitBasicBlock *
  1589. jit_cc_exit_basic_block(JitCompContext *cc)
  1590. {
  1591. return *(jit_annl_basic_block(cc, cc->exit_label));
  1592. }
  1593. void
  1594. jit_value_stack_push(JitValueStack *stack, JitValue *value);
  1595. JitValue *
  1596. jit_value_stack_pop(JitValueStack *stack);
  1597. void
  1598. jit_value_stack_destroy(JitValueStack *stack);
  1599. JitBlock *
  1600. jit_block_stack_top(JitBlockStack *stack);
  1601. void
  1602. jit_block_stack_push(JitBlockStack *stack, JitBlock *block);
  1603. JitBlock *
  1604. jit_block_stack_pop(JitBlockStack *stack);
  1605. void
  1606. jit_block_stack_destroy(JitBlockStack *stack);
  1607. bool
  1608. jit_block_add_incoming_insn(JitBlock *block, JitInsn *insn, uint32 opnd_idx);
  1609. void
  1610. jit_block_destroy(JitBlock *block);
  1611. bool
  1612. jit_cc_push_value(JitCompContext *cc, uint8 type, JitReg value);
  1613. bool
  1614. jit_cc_pop_value(JitCompContext *cc, uint8 type, JitReg *p_value);
  1615. bool
  1616. jit_lock_reg_in_insn(JitCompContext *cc, JitInsn *the_insn, JitReg reg_to_lock);
  1617. /**
  1618. * Update the control flow graph after successors of blocks are
  1619. * changed so that the predecessor vector of each block represents the
  1620. * updated status. The predecessors may not be required by all
  1621. * passes, so we don't need to keep them always being updated.
  1622. *
  1623. * @param cc the compilation context
  1624. *
  1625. * @return true if succeeds, false otherwise
  1626. */
  1627. bool
  1628. jit_cc_update_cfg(JitCompContext *cc);
  1629. /**
  1630. * Visit each normal block (which is not entry nor exit block) in a
  1631. * compilation context. New blocks can be added in the loop body, but
  1632. * they won't be visited. Blocks can also be removed safely (by
  1633. * setting the label's block annotation to NULL) in the loop body.
  1634. *
  1635. * @param CC (JitCompContext *) the compilation context
  1636. * @param I (unsigned) index variable of the block (label no)
  1637. * @param E (unsigned) end index variable of block (last index + 1)
  1638. * @param B (JitBasicBlock *) block pointer variable
  1639. */
  1640. #define JIT_FOREACH_BLOCK(CC, I, E, B) \
  1641. for ((I) = 2, (E) = (CC)->_ann._label_num; (I) < (E); (I)++) \
  1642. if (((B) = (CC)->_ann._label_basic_block[(I)]))
  1643. /**
  1644. * The version that includes entry and exit block.
  1645. */
  1646. #define JIT_FOREACH_BLOCK_ENTRY_EXIT(CC, I, E, B) \
  1647. for ((I) = 0, (E) = (CC)->_ann._label_num; (I) < (E); (I)++) \
  1648. if (((B) = (CC)->_ann._label_basic_block[(I)]))
  1649. /**
  1650. * Visit each normal block (which is not entry nor exit block) in a
  1651. * compilation context in reverse order. New blocks can be added in
  1652. * the loop body, but they won't be visited. Blocks can also be
  1653. * removed safely (by setting the label's block annotation to NULL) in
  1654. * the loop body.
  1655. *
  1656. * @param CC (JitCompContext *) the compilation context
  1657. * @param I (unsigned) index of the block (label no)
  1658. * @param B (JitBasicBlock *) block pointer
  1659. */
  1660. #define JIT_FOREACH_BLOCK_REVERSE(CC, I, B) \
  1661. for ((I) = (CC)->_ann._label_num; (I) > 2; (I)--) \
  1662. if (((B) = (CC)->_ann._label_basic_block[(I)-1]))
  1663. /**
  1664. * The version that includes entry and exit block.
  1665. */
  1666. #define JIT_FOREACH_BLOCK_REVERSE_ENTRY_EXIT(CC, I, B) \
  1667. for ((I) = (CC)->_ann._label_num; (I) > 0; (I)--) \
  1668. if (((B) = (CC)->_ann._label_basic_block[(I)-1]))
  1669. #ifdef __cplusplus
  1670. }
  1671. #endif
  1672. #endif /* end of _JIT_IR_H_ */