jit_regalloc.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840
  1. /*
  2. * Copyright (C) 2021 Intel Corporation. All rights reserved.
  3. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. */
  5. #include "jit_utils.h"
  6. #include "jit_compiler.h"
  7. #if BH_DEBUG != 0
  8. #define VREG_DEF_SANITIZER
  9. #endif
  10. /**
  11. * A uint16 stack for storing distances of occurrences of virtual
  12. * registers.
  13. */
  14. typedef struct UintStack {
  15. /* Capacity of the stack. */
  16. uint32 capacity;
  17. /* Top index of the stack. */
  18. uint32 top;
  19. /* Elements of the vector. */
  20. uint32 elem[1];
  21. } UintStack;
  22. static bool
  23. uint_stack_push(UintStack **stack, unsigned val)
  24. {
  25. unsigned capacity = *stack ? (*stack)->capacity : 0;
  26. unsigned top = *stack ? (*stack)->top : 0;
  27. bh_assert(top <= capacity);
  28. if (top == capacity) {
  29. const unsigned elem_size = sizeof((*stack)->elem[0]);
  30. unsigned new_capacity = capacity ? capacity + capacity / 2 : 4;
  31. UintStack *new_stack =
  32. jit_malloc(offsetof(UintStack, elem) + elem_size * new_capacity);
  33. if (!new_stack)
  34. return false;
  35. new_stack->capacity = new_capacity;
  36. new_stack->top = top;
  37. if (*stack)
  38. memcpy(new_stack->elem, (*stack)->elem, elem_size * top);
  39. jit_free(*stack);
  40. *stack = new_stack;
  41. }
  42. (*stack)->elem[(*stack)->top++] = val;
  43. return true;
  44. }
  45. static int
  46. uint_stack_top(UintStack *stack)
  47. {
  48. return stack->elem[stack->top - 1];
  49. }
  50. static void
  51. uint_stack_delete(UintStack **stack)
  52. {
  53. jit_free(*stack);
  54. *stack = NULL;
  55. }
  56. static void
  57. uint_stack_pop(UintStack **stack)
  58. {
  59. bh_assert((*stack)->top > 0);
  60. /**
  61. * TODO: the fact of empty distances stack means there is no instruction
  62. * using current JitReg anymore. so shall we release the HardReg and clean
  63. * VirtualReg information?
  64. */
  65. if (--(*stack)->top == 0)
  66. uint_stack_delete(stack);
  67. }
  68. /**
  69. * Information of a virtual register.
  70. */
  71. typedef struct VirtualReg {
  72. /* The hard register allocated to this virtual register. */
  73. JitReg hreg;
  74. /* The spill slot allocated to this virtual register. */
  75. JitReg slot;
  76. /* The hard register allocated to global virtual registers. It is 0
  77. for local registers, whose lifetime is within one basic block. */
  78. JitReg global_hreg;
  79. /* Distances from the beginning of basic block of all occurrences of the
  80. virtual register in the basic block. */
  81. UintStack *distances;
  82. } VirtualReg;
  83. /**
  84. * Information of a hard register.
  85. */
  86. typedef struct HardReg {
  87. /* The virtual register this hard register is allocated to. */
  88. JitReg vreg;
  89. } HardReg;
  90. /**
  91. * Information of a spill slot.
  92. */
  93. typedef struct SpillSlot {
  94. /* The virtual register this spill slot is allocated to. */
  95. JitReg vreg;
  96. } SpillSlot;
  97. typedef struct RegallocContext {
  98. /* The compiler context. */
  99. JitCompContext *cc;
  100. /* Information of virtual registers. The register allocation must
  101. not increase the virtual register number during the allocation
  102. process. */
  103. VirtualReg *vregs[JIT_REG_KIND_L32];
  104. /* Information of hard registers. */
  105. HardReg *hregs[JIT_REG_KIND_L32];
  106. /* Number of elements in the spill_slots array. */
  107. uint32 spill_slot_num;
  108. /* Information of spill slots. */
  109. SpillSlot *spill_slots;
  110. /* The last define-released hard register. */
  111. JitReg last_def_released_hreg;
  112. } RegallocContext;
  113. /**
  114. * Get the VirtualReg structure of the given virtual register.
  115. *
  116. * @param rc the regalloc context
  117. * @param vreg the virtual register
  118. *
  119. * @return the VirtualReg structure of the given virtual register
  120. */
  121. static VirtualReg *
  122. rc_get_vr(RegallocContext *rc, JitReg vreg)
  123. {
  124. unsigned kind = jit_reg_kind(vreg);
  125. unsigned no = jit_reg_no(vreg);
  126. bh_assert(jit_reg_is_variable(vreg));
  127. return &rc->vregs[kind][no];
  128. }
  129. /**
  130. * Get the HardReg structure of the given hard register.
  131. *
  132. * @param rc the regalloc context
  133. * @param hreg the hard register
  134. *
  135. * @return the HardReg structure of the given hard register
  136. */
  137. static HardReg *
  138. rc_get_hr(RegallocContext *rc, JitReg hreg)
  139. {
  140. unsigned kind = jit_reg_kind(hreg);
  141. unsigned no = jit_reg_no(hreg);
  142. bh_assert(jit_reg_is_variable(hreg) && jit_cc_is_hreg(rc->cc, hreg));
  143. return &rc->hregs[kind][no];
  144. }
  145. /**
  146. * Get the SpillSlot structure of the given slot.
  147. *
  148. * @param rc the regalloc context
  149. * @param slot the constant register representing the slot index
  150. *
  151. * @return the SpillSlot of the given slot
  152. */
  153. static SpillSlot *
  154. rc_get_spill_slot(RegallocContext *rc, JitReg slot)
  155. {
  156. unsigned index = jit_cc_get_const_I32(rc->cc, slot);
  157. bh_assert(index < rc->spill_slot_num);
  158. return &rc->spill_slots[index];
  159. }
  160. /**
  161. * Get the stride in the spill slots of the register.
  162. *
  163. * @param reg a virtual register
  164. *
  165. * @return stride in the spill slots
  166. */
  167. static unsigned
  168. get_reg_stride(JitReg reg)
  169. {
  170. static const uint8 strides[] = { 0, 1, 2, 1, 2, 2, 4, 8, 0 };
  171. return strides[jit_reg_kind(reg)];
  172. }
  173. /**
  174. * Allocate a spill slot for the given virtual register.
  175. *
  176. * @param rc the regalloc context
  177. * @param vreg the virtual register
  178. *
  179. * @return the spill slot encoded in a consant register
  180. */
  181. static JitReg
  182. rc_alloc_spill_slot(RegallocContext *rc, JitReg vreg)
  183. {
  184. const unsigned stride = get_reg_stride(vreg);
  185. unsigned mask, new_num, i, j;
  186. SpillSlot *slots;
  187. bh_assert(stride > 0);
  188. for (i = 0; i < rc->spill_slot_num; i += stride)
  189. for (j = i;; j++) {
  190. if (j == i + stride)
  191. /* Found a free slot for vreg. */
  192. goto found;
  193. if (rc->spill_slots[j].vreg)
  194. break;
  195. }
  196. /* No free slot, increase the slot number. */
  197. mask = stride - 1;
  198. /* Align the slot index. */
  199. i = (rc->spill_slot_num + mask) & ~mask;
  200. new_num = i == 0 ? 32 : i + i / 2;
  201. if (!(slots = jit_calloc(sizeof(*slots) * new_num)))
  202. return 0;
  203. if (rc->spill_slots)
  204. memcpy(slots, rc->spill_slots, sizeof(*slots) * rc->spill_slot_num);
  205. jit_free(rc->spill_slots);
  206. rc->spill_slots = slots;
  207. rc->spill_slot_num = new_num;
  208. found:
  209. /* Now, i is the first slot for vreg. */
  210. if ((i + stride) * 4 > rc->cc->spill_cache_size)
  211. /* No frame space for the spill area. */
  212. return 0;
  213. /* Allocate the slot(s) to vreg. */
  214. for (j = i; j < i + stride; j++)
  215. rc->spill_slots[j].vreg = vreg;
  216. return jit_cc_new_const_I32(rc->cc, i);
  217. }
  218. /**
  219. * Free a spill slot.
  220. *
  221. * @param rc the regalloc context
  222. * @param slot_reg the constant register representing the slot index
  223. */
  224. static void
  225. rc_free_spill_slot(RegallocContext *rc, JitReg slot_reg)
  226. {
  227. if (slot_reg) {
  228. SpillSlot *slot = rc_get_spill_slot(rc, slot_reg);
  229. const JitReg vreg = slot->vreg;
  230. const unsigned stride = get_reg_stride(vreg);
  231. unsigned i;
  232. for (i = 0; i < stride; i++)
  233. slot[i].vreg = 0;
  234. }
  235. }
  236. static void
  237. rc_destroy(RegallocContext *rc)
  238. {
  239. unsigned i, j;
  240. for (i = JIT_REG_KIND_VOID; i < JIT_REG_KIND_L32; i++) {
  241. const unsigned vreg_num = jit_cc_reg_num(rc->cc, i);
  242. if (rc->vregs[i])
  243. for (j = 0; j < vreg_num; j++)
  244. uint_stack_delete(&rc->vregs[i][j].distances);
  245. jit_free(rc->vregs[i]);
  246. jit_free(rc->hregs[i]);
  247. }
  248. jit_free(rc->spill_slots);
  249. }
  250. static bool
  251. rc_init(RegallocContext *rc, JitCompContext *cc)
  252. {
  253. unsigned i, j;
  254. memset(rc, 0, sizeof(*rc));
  255. rc->cc = cc;
  256. for (i = JIT_REG_KIND_VOID; i < JIT_REG_KIND_L32; i++) {
  257. const unsigned vreg_num = jit_cc_reg_num(cc, i);
  258. const unsigned hreg_num = jit_cc_hreg_num(cc, i);
  259. if (vreg_num > 0
  260. && !(rc->vregs[i] = jit_calloc(sizeof(VirtualReg) * vreg_num)))
  261. goto fail;
  262. if (hreg_num > 0
  263. && !(rc->hregs[i] = jit_calloc(sizeof(HardReg) * hreg_num)))
  264. goto fail;
  265. /* Hard registers can only be allocated to themselves. */
  266. for (j = 0; j < hreg_num; j++)
  267. rc->vregs[i][j].global_hreg = jit_reg_new(i, j);
  268. }
  269. return true;
  270. fail:
  271. rc_destroy(rc);
  272. return false;
  273. }
  274. /**
  275. * Check whether the given register is an allocation candidate, which
  276. * must be a variable register that is not fixed hard register.
  277. *
  278. * @param cc the compilation context
  279. * @param reg the register
  280. *
  281. * @return true if the register is an allocation candidate
  282. */
  283. static bool
  284. is_alloc_candidate(JitCompContext *cc, JitReg reg)
  285. {
  286. return (jit_reg_is_variable(reg)
  287. && (!jit_cc_is_hreg(cc, reg) || !jit_cc_is_hreg_fixed(cc, reg)));
  288. }
  289. #ifdef VREG_DEF_SANITIZER
  290. static void
  291. check_vreg_definition(RegallocContext *rc, JitInsn *insn)
  292. {
  293. JitRegVec regvec = jit_insn_opnd_regs(insn);
  294. JitReg *regp, reg_defined = 0;
  295. unsigned i, first_use = jit_insn_opnd_first_use(insn);
  296. /* check if there is the definition of an vr before its references */
  297. JIT_REG_VEC_FOREACH(regvec, i, regp)
  298. {
  299. VirtualReg *vr = NULL;
  300. if (!is_alloc_candidate(rc->cc, *regp))
  301. continue;
  302. /* a strong assumption that there is only one defined reg */
  303. if (i < first_use) {
  304. reg_defined = *regp;
  305. continue;
  306. }
  307. /**
  308. * both definition and references are in one instruction,
  309. * like MOV i3, i3
  310. */
  311. if (reg_defined == *regp)
  312. continue;
  313. vr = rc_get_vr(rc, *regp);
  314. bh_assert(vr->distances);
  315. }
  316. }
  317. #endif
  318. /**
  319. * Collect distances from the beginning of basic block of all occurrences of
  320. * each virtual register.
  321. *
  322. * @param rc the regalloc context
  323. * @param basic_block the basic block
  324. *
  325. * @return distance of the end instruction if succeeds, -1 otherwise
  326. */
  327. static int
  328. collect_distances(RegallocContext *rc, JitBasicBlock *basic_block)
  329. {
  330. JitInsn *insn;
  331. int distance = 1;
  332. JIT_FOREACH_INSN(basic_block, insn)
  333. {
  334. JitRegVec regvec = jit_insn_opnd_regs(insn);
  335. unsigned i;
  336. JitReg *regp;
  337. #ifdef VREG_DEF_SANITIZER
  338. check_vreg_definition(rc, insn);
  339. #endif
  340. /* NOTE: the distance may be pushed more than once if the
  341. virtual register occurs multiple times in the
  342. instruction. */
  343. JIT_REG_VEC_FOREACH(regvec, i, regp)
  344. if (is_alloc_candidate(rc->cc, *regp))
  345. if (!uint_stack_push(&(rc_get_vr(rc, *regp))->distances, distance))
  346. return -1;
  347. /* Integer overflow check, normally it won't happen, but
  348. we had better add the check here */
  349. if (distance >= INT32_MAX)
  350. return -1;
  351. distance++;
  352. }
  353. return distance;
  354. }
  355. static JitReg
  356. offset_of_spill_slot(JitCompContext *cc, JitReg slot)
  357. {
  358. return jit_cc_new_const_I32(cc, cc->spill_cache_offset
  359. + jit_cc_get_const_I32(cc, slot) * 4);
  360. }
  361. /**
  362. * Reload the virtual register from memory. Reload instruction will
  363. * be inserted after the given instruction.
  364. *
  365. * @param rc the regalloc context
  366. * @param vreg the virtual register to be reloaded
  367. * @param cur_insn the current instruction after which the reload
  368. * insertion will be inserted
  369. *
  370. * @return the reload instruction if succeeds, NULL otherwise
  371. */
  372. static JitInsn *
  373. reload_vreg(RegallocContext *rc, JitReg vreg, JitInsn *cur_insn)
  374. {
  375. VirtualReg *vr = rc_get_vr(rc, vreg);
  376. HardReg *hr = rc_get_hr(rc, vr->hreg);
  377. JitInsn *insn = NULL;
  378. if (vreg == rc->cc->exec_env_reg)
  379. /* Reload exec_env_reg with LDEXECENV. */
  380. insn = jit_cc_new_insn(rc->cc, LDEXECENV, vr->hreg);
  381. else
  382. /* Allocate spill slot if not yet and reload from there. */
  383. {
  384. JitReg fp_reg = rc->cc->fp_reg, offset;
  385. if (!vr->slot && !(vr->slot = rc_alloc_spill_slot(rc, vreg)))
  386. /* Cannot allocte spill slot (due to OOM or frame size limit). */
  387. return NULL;
  388. offset = offset_of_spill_slot(rc->cc, vr->slot);
  389. switch (jit_reg_kind(vreg)) {
  390. case JIT_REG_KIND_I32:
  391. insn = jit_cc_new_insn(rc->cc, LDI32, vr->hreg, fp_reg, offset);
  392. break;
  393. case JIT_REG_KIND_I64:
  394. insn = jit_cc_new_insn(rc->cc, LDI64, vr->hreg, fp_reg, offset);
  395. break;
  396. case JIT_REG_KIND_F32:
  397. insn = jit_cc_new_insn(rc->cc, LDF32, vr->hreg, fp_reg, offset);
  398. break;
  399. case JIT_REG_KIND_F64:
  400. insn = jit_cc_new_insn(rc->cc, LDF64, vr->hreg, fp_reg, offset);
  401. break;
  402. case JIT_REG_KIND_V64:
  403. insn = jit_cc_new_insn(rc->cc, LDV64, vr->hreg, fp_reg, offset);
  404. break;
  405. case JIT_REG_KIND_V128:
  406. insn =
  407. jit_cc_new_insn(rc->cc, LDV128, vr->hreg, fp_reg, offset);
  408. break;
  409. case JIT_REG_KIND_V256:
  410. insn =
  411. jit_cc_new_insn(rc->cc, LDV256, vr->hreg, fp_reg, offset);
  412. break;
  413. default:
  414. bh_assert(0);
  415. }
  416. }
  417. if (insn)
  418. jit_insn_insert_after(cur_insn, insn);
  419. bh_assert(hr->vreg == vreg);
  420. hr->vreg = vr->hreg = 0;
  421. return insn;
  422. }
  423. /**
  424. * Spill the virtual register (which cannot be exec_env_reg) to memory.
  425. * Spill instruction will be inserted after the given instruction.
  426. *
  427. * @param rc the regalloc context
  428. * @param vreg the virtual register to be reloaded
  429. * @param cur_insn the current instruction after which the reload
  430. * insertion will be inserted
  431. *
  432. * @return the spill instruction if succeeds, NULL otherwise
  433. */
  434. static JitInsn *
  435. spill_vreg(RegallocContext *rc, JitReg vreg, JitInsn *cur_insn)
  436. {
  437. VirtualReg *vr = rc_get_vr(rc, vreg);
  438. JitReg fp_reg = rc->cc->fp_reg, offset;
  439. JitInsn *insn;
  440. /* There is no chance to spill exec_env_reg. */
  441. bh_assert(vreg != rc->cc->exec_env_reg);
  442. bh_assert(vr->hreg && vr->slot);
  443. offset = offset_of_spill_slot(rc->cc, vr->slot);
  444. switch (jit_reg_kind(vreg)) {
  445. case JIT_REG_KIND_I32:
  446. insn = jit_cc_new_insn(rc->cc, STI32, vr->hreg, fp_reg, offset);
  447. break;
  448. case JIT_REG_KIND_I64:
  449. insn = jit_cc_new_insn(rc->cc, STI64, vr->hreg, fp_reg, offset);
  450. break;
  451. case JIT_REG_KIND_F32:
  452. insn = jit_cc_new_insn(rc->cc, STF32, vr->hreg, fp_reg, offset);
  453. break;
  454. case JIT_REG_KIND_F64:
  455. insn = jit_cc_new_insn(rc->cc, STF64, vr->hreg, fp_reg, offset);
  456. break;
  457. case JIT_REG_KIND_V64:
  458. insn = jit_cc_new_insn(rc->cc, STV64, vr->hreg, fp_reg, offset);
  459. break;
  460. case JIT_REG_KIND_V128:
  461. insn = jit_cc_new_insn(rc->cc, STV128, vr->hreg, fp_reg, offset);
  462. break;
  463. case JIT_REG_KIND_V256:
  464. insn = jit_cc_new_insn(rc->cc, STV256, vr->hreg, fp_reg, offset);
  465. break;
  466. default:
  467. bh_assert(0);
  468. return NULL;
  469. }
  470. if (insn)
  471. jit_insn_insert_after(cur_insn, insn);
  472. return insn;
  473. }
  474. /**
  475. * Allocate a hard register for the virtual register. Necessary
  476. * reloade instruction will be inserted after the given instruction.
  477. *
  478. * @param rc the regalloc context
  479. * @param vreg the virtual register
  480. * @param insn the instruction after which the reload insertion will
  481. * be inserted
  482. * @param distance the distance of the current instruction
  483. *
  484. * @return the hard register allocated if succeeds, 0 otherwise
  485. */
  486. static JitReg
  487. allocate_hreg(RegallocContext *rc, JitReg vreg, JitInsn *insn, int distance)
  488. {
  489. const int kind = jit_reg_kind(vreg);
  490. const HardReg *hregs = rc->hregs[kind];
  491. const unsigned hreg_num = jit_cc_hreg_num(rc->cc, kind);
  492. JitReg hreg, vreg_to_reload = 0;
  493. int min_distance = distance, vr_distance;
  494. VirtualReg *vr = rc_get_vr(rc, vreg);
  495. unsigned i;
  496. if (hreg_num == 0)
  497. /* Unsupported hard register kind. */
  498. {
  499. jit_set_last_error(rc->cc, "unsupported hard register kind");
  500. return 0;
  501. }
  502. if (vr->global_hreg)
  503. /* It has globally allocated register, we can only use it. */
  504. {
  505. if ((vreg_to_reload = (rc_get_hr(rc, vr->global_hreg))->vreg))
  506. if (!reload_vreg(rc, vreg_to_reload, insn))
  507. return 0;
  508. return vr->global_hreg;
  509. }
  510. /* Use the last define-released register if its kind is correct and
  511. it's free so as to optimize for two-operand instructions. */
  512. if (jit_reg_kind(rc->last_def_released_hreg) == kind
  513. && (rc_get_hr(rc, rc->last_def_released_hreg))->vreg == 0)
  514. return rc->last_def_released_hreg;
  515. /* No hint given, just try to pick any free register. */
  516. for (i = 0; i < hreg_num; i++) {
  517. hreg = jit_reg_new(kind, i);
  518. if (jit_cc_is_hreg_fixed(rc->cc, hreg))
  519. continue;
  520. if (hregs[i].vreg == 0)
  521. /* Found a free one, return it. */
  522. return hreg;
  523. }
  524. /* No free registers, need to spill and reload one. */
  525. for (i = 0; i < hreg_num; i++) {
  526. if (jit_cc_is_hreg_fixed(rc->cc, jit_reg_new(kind, i)))
  527. continue;
  528. vr = rc_get_vr(rc, hregs[i].vreg);
  529. /* TODO: since the hregs[i] is in use, its distances should be valid */
  530. vr_distance = vr->distances ? uint_stack_top(vr->distances) : 0;
  531. if (vr_distance < min_distance) {
  532. min_distance = vr_distance;
  533. vreg_to_reload = hregs[i].vreg;
  534. hreg = jit_reg_new(kind, i);
  535. }
  536. }
  537. bh_assert(min_distance < distance);
  538. if (!reload_vreg(rc, vreg_to_reload, insn))
  539. return 0;
  540. return hreg;
  541. }
  542. /**
  543. * Allocate a hard register for the virtual register if not allocated
  544. * yet. Necessary spill and reloade instructions will be inserted
  545. * before/after and after the given instruction. This operation will
  546. * convert the virtual register's state from 1 or 3 to 2.
  547. *
  548. * @param rc the regalloc context
  549. * @param vreg the virtual register
  550. * @param insn the instruction after which the spill and reload
  551. * insertions will be inserted
  552. * @param distance the distance of the current instruction
  553. *
  554. * @return the hard register allocated to the virtual register if
  555. * succeeds, 0 otherwise
  556. */
  557. static JitReg
  558. allocate_for_vreg(RegallocContext *rc, JitReg vreg, JitInsn *insn, int distance)
  559. {
  560. VirtualReg *vr = rc_get_vr(rc, vreg);
  561. if (vr->hreg)
  562. /* It has had a hard register, reuse it. */
  563. return vr->hreg;
  564. /* Not allocated yet. */
  565. if ((vr->hreg = allocate_hreg(rc, vreg, insn, distance)))
  566. (rc_get_hr(rc, vr->hreg))->vreg = vreg;
  567. return vr->hreg;
  568. }
  569. /**
  570. * Clobber live registers.
  571. *
  572. * @param rc the regalloc context
  573. * @param is_native whether it's native ABI or JITed ABI
  574. * @param insn the instruction after which the reload insertion will
  575. * be inserted
  576. *
  577. * @return true if succeeds, false otherwise
  578. */
  579. static bool
  580. clobber_live_regs(RegallocContext *rc, bool is_native, JitInsn *insn)
  581. {
  582. unsigned i, j;
  583. for (i = JIT_REG_KIND_VOID; i < JIT_REG_KIND_L32; i++) {
  584. const unsigned hreg_num = jit_cc_hreg_num(rc->cc, i);
  585. for (j = 0; j < hreg_num; j++) {
  586. JitReg hreg = jit_reg_new(i, j);
  587. bool caller_saved =
  588. (is_native ? jit_cc_is_hreg_caller_saved_native(rc->cc, hreg)
  589. : jit_cc_is_hreg_caller_saved_jitted(rc->cc, hreg));
  590. if (caller_saved && rc->hregs[i][j].vreg)
  591. if (!reload_vreg(rc, rc->hregs[i][j].vreg, insn))
  592. return false;
  593. }
  594. }
  595. return true;
  596. }
  597. /**
  598. * Do local register allocation for the given basic block
  599. *
  600. * @param rc the regalloc context
  601. * @param basic_block the basic block
  602. * @param distance the distance of the last instruction of the basic block
  603. *
  604. * @return true if succeeds, false otherwise
  605. */
  606. static bool
  607. allocate_for_basic_block(RegallocContext *rc, JitBasicBlock *basic_block,
  608. int distance)
  609. {
  610. JitInsn *insn;
  611. JIT_FOREACH_INSN_REVERSE(basic_block, insn)
  612. {
  613. JitRegVec regvec = jit_insn_opnd_regs(insn);
  614. unsigned first_use = jit_insn_opnd_first_use(insn);
  615. unsigned i;
  616. JitReg *regp;
  617. distance--;
  618. JIT_REG_VEC_FOREACH_DEF(regvec, i, regp, first_use)
  619. if (is_alloc_candidate(rc->cc, *regp)) {
  620. const JitReg vreg = *regp;
  621. VirtualReg *vr = rc_get_vr(rc, vreg);
  622. if (!(*regp = allocate_for_vreg(rc, vreg, insn, distance)))
  623. return false;
  624. /* Spill the register if required. */
  625. if (vr->slot && !spill_vreg(rc, vreg, insn))
  626. return false;
  627. bh_assert(uint_stack_top(vr->distances) == distance);
  628. uint_stack_pop(&vr->distances);
  629. /* Record the define-released hard register. */
  630. rc->last_def_released_hreg = vr->hreg;
  631. /* Release the hreg and spill slot. */
  632. rc_free_spill_slot(rc, vr->slot);
  633. (rc_get_hr(rc, vr->hreg))->vreg = 0;
  634. vr->hreg = vr->slot = 0;
  635. }
  636. if (insn->opcode == JIT_OP_CALLBC) {
  637. if (!clobber_live_regs(rc, false, insn))
  638. return false;
  639. /* The exec_env_reg is implicitly used by the callee. */
  640. if (!allocate_for_vreg(rc, rc->cc->exec_env_reg, insn, distance))
  641. return false;
  642. }
  643. else if (insn->opcode == JIT_OP_CALLNATIVE) {
  644. if (!clobber_live_regs(rc, true, insn))
  645. return false;
  646. }
  647. JIT_REG_VEC_FOREACH_USE(regvec, i, regp, first_use)
  648. if (is_alloc_candidate(rc->cc, *regp)) {
  649. if (!allocate_for_vreg(rc, *regp, insn, distance))
  650. return false;
  651. }
  652. JIT_REG_VEC_FOREACH_USE(regvec, i, regp, first_use)
  653. if (is_alloc_candidate(rc->cc, *regp)) {
  654. VirtualReg *vr = rc_get_vr(rc, *regp);
  655. bh_assert(uint_stack_top(vr->distances) == distance);
  656. uint_stack_pop(&vr->distances);
  657. /* be sure that the hreg exists and hasn't been spilled out */
  658. bh_assert(vr->hreg != 0);
  659. *regp = vr->hreg;
  660. }
  661. }
  662. return true;
  663. }
  664. bool
  665. jit_pass_regalloc(JitCompContext *cc)
  666. {
  667. RegallocContext rc = { 0 };
  668. unsigned label_index, end_label_index;
  669. JitBasicBlock *basic_block;
  670. VirtualReg *self_vr;
  671. bool retval = false;
  672. if (!rc_init(&rc, cc))
  673. return false;
  674. /* NOTE: don't allocate new virtual registers during allocation
  675. because the rc->vregs array is fixed size. */
  676. /* TODO: allocate hard registers for global virtual registers here.
  677. Currently, exec_env_reg is the only global virtual register. */
  678. self_vr = rc_get_vr(&rc, cc->exec_env_reg);
  679. JIT_FOREACH_BLOCK_ENTRY_EXIT(cc, label_index, end_label_index, basic_block)
  680. {
  681. int distance;
  682. /* TODO: initialize hreg for live-out registers. */
  683. self_vr->hreg = self_vr->global_hreg;
  684. (rc_get_hr(&rc, cc->exec_env_reg))->vreg = cc->exec_env_reg;
  685. /**
  686. * TODO: the allocation of a basic block keeps using vregs[]
  687. * and hregs[] from previous basic block
  688. */
  689. if ((distance = collect_distances(&rc, basic_block)) < 0)
  690. goto cleanup_and_return;
  691. if (!allocate_for_basic_block(&rc, basic_block, distance))
  692. goto cleanup_and_return;
  693. /* TODO: generate necessary spills for live-in registers. */
  694. }
  695. retval = true;
  696. cleanup_and_return:
  697. rc_destroy(&rc);
  698. return retval;
  699. }