jit_regalloc.c 23 KB

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