ssa.cpp 70 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564
  1. struct ssaModule;
  2. struct ssaValue;
  3. struct ssaValueArgs;
  4. struct ssaDefer;
  5. struct ssaBlock;
  6. struct ssaProc;
  7. struct ssaEdge;
  8. struct ssaRegister;
  9. struct ssaTargetList;
  10. String ssa_mangle_name(ssaModule *m, String path, Entity *e);
  11. #include "ssa_op.cpp"
  12. #define SSA_DEFAULT_VALUE_ARG_CAPACITY 8
  13. struct ssaValueArgs {
  14. ssaValue ** e;
  15. isize count;
  16. isize capacity;
  17. ssaValue * backing[SSA_DEFAULT_VALUE_ARG_CAPACITY];
  18. gbAllocator allocator;
  19. ssaValue *&operator[](isize i) {
  20. GB_ASSERT(0 <= i && i <= count);
  21. return e[i];
  22. }
  23. ssaValue * const &operator[](isize i) const {
  24. GB_ASSERT(0 <= i && i <= count);
  25. return e[i];
  26. }
  27. };
  28. struct ssaValue {
  29. i32 id; // Unique identifier but the pointer could be used too
  30. ssaOp op; // Operation that computes this value
  31. Type * type;
  32. ssaBlock * block; // Containing basic block
  33. i32 uses;
  34. ssaValueArgs args;
  35. ExactValue exact_value; // Used for constants
  36. String comment_string;
  37. };
  38. enum ssaBlockKind {
  39. ssaBlock_Invalid,
  40. // NOTE(bill): These are the generic block types and for more specific
  41. // architectures, these could become conditions blocks like amd64 LT or EQ
  42. ssaBlock_Entry, // Entry point
  43. ssaBlock_Plain,
  44. ssaBlock_Defer, // Similar to a plain block but generated by a `defer` statement
  45. ssaBlock_If,
  46. ssaBlock_Ret,
  47. ssaBlock_RetJmp, // Stores return value and jumps to Ret block
  48. ssaBlock_Exit,
  49. ssaBlock_Count,
  50. };
  51. enum ssaBranchPrediction {
  52. ssaBranch_Unknown = 0,
  53. ssaBranch_Likely = +1,
  54. ssaBranch_Unlikely = -1,
  55. };
  56. enum ssaDeferKind {
  57. ssaDefer_Node,
  58. ssaDefer_Instr,
  59. };
  60. struct ssaDefer {
  61. ssaDeferKind kind;
  62. i32 scope_level;
  63. ssaBlock * block;
  64. union {
  65. AstNode * stmt;
  66. ssaValue * instr;
  67. };
  68. };
  69. enum ssaDeferExitKind {
  70. ssaDeferExit_Default,
  71. ssaDeferExit_Return,
  72. ssaDeferExit_Branch,
  73. };
  74. // ssaEdge represents a control flow graph (CFG) edge
  75. struct ssaEdge {
  76. // Succs array: Block To
  77. // Preds array: Block From
  78. ssaBlock *block;
  79. // Index of reverse edge
  80. isize index;
  81. };
  82. struct ssaBlock {
  83. i32 id; // Unique identifier but the pointer could be used too
  84. ssaBlockKind kind;
  85. ssaProc * proc; // Containing procedure
  86. String name; // Optional
  87. i32 scope_level;
  88. // Likely branch direction
  89. ssaBranchPrediction likeliness;
  90. // Determines how a block exits
  91. // It depends on the type of block:
  92. // - BlockIf will be a boolean value
  93. // - BlockExit will be a memory control value
  94. ssaValue *control;
  95. Array<ssaValue *> values;
  96. Array<ssaEdge> preds;
  97. Array<ssaEdge> succs;
  98. };
  99. struct ssaTargetList {
  100. ssaTargetList *prev;
  101. ssaBlock * break_;
  102. ssaBlock * continue_;
  103. ssaBlock * fallthrough_;
  104. };
  105. struct ssaProc {
  106. ssaModule * module; // Parent module
  107. gbAllocator allocator; // Same allocator as the parent module
  108. String name; // Mangled name
  109. Entity * entity;
  110. DeclInfo * decl_info;
  111. Array<ssaBlock *> blocks;
  112. ssaBlock * entry; // Entry block
  113. ssaBlock * exit; // Exit block
  114. ssaBlock * curr_block;
  115. ssaTargetList * target_list;
  116. i32 block_id;
  117. i32 value_id;
  118. Map<ssaValue *> values; // Key: Entity *
  119. Array<ssaDefer> defer_stmts;
  120. i32 scope_level;
  121. };
  122. struct ssaRegister {
  123. i32 id;
  124. i32 size;
  125. };
  126. struct ssaModule {
  127. CheckerInfo * info;
  128. gbAllocator allocator;
  129. gbArena arena;
  130. gbAllocator tmp_allocator;
  131. gbArena tmp_arena;
  132. PtrSet<Entity *> min_dep_map;
  133. Map<ssaValue *> values; // Key: Entity *
  134. // List of registers for the specific architecture
  135. Array<ssaRegister> registers;
  136. ssaProc *proc; // current procedure
  137. Entity *entry_point_entity;
  138. u32 stmt_state_flags;
  139. Array<ssaProc *> procs;
  140. Array<ssaValue *> procs_to_generate;
  141. };
  142. enum ssaAddrKind {
  143. ssaAddr_Default,
  144. ssaAddr_Map,
  145. };
  146. struct ssaAddr {
  147. ssaValue * addr;
  148. ssaAddrKind kind;
  149. };
  150. void ssa_push_target_list(ssaProc *p, ssaBlock *break_, ssaBlock *continue_, ssaBlock *fallthrough_) {
  151. ssaTargetList *tl = gb_alloc_item(p->allocator, ssaTargetList);
  152. tl->prev = p->target_list;
  153. tl->break_ = break_;
  154. tl->continue_ = continue_;
  155. tl->fallthrough_ = fallthrough_;
  156. p->target_list = tl;
  157. }
  158. void ssa_pop_target_list(ssaProc *p) {
  159. p->target_list = p->target_list->prev;
  160. }
  161. ssaBlock *ssa_new_block(ssaProc *p, ssaBlockKind kind, char *name) {
  162. ssaBlock *b = gb_alloc_item(p->allocator, ssaBlock);
  163. b->id = p->block_id++;
  164. b->kind = kind;
  165. b->proc = p;
  166. p->scope_level = p->scope_level;
  167. if (name != nullptr || name[0] != 0) {
  168. b->name = make_string_c(name);
  169. }
  170. array_init(&b->values, heap_allocator());
  171. array_init(&b->preds, heap_allocator());
  172. array_init(&b->succs, heap_allocator());
  173. array_add(&p->blocks, b);
  174. return b;
  175. }
  176. void ssa_clear_block(ssaProc *p, ssaBlock *b) {
  177. GB_ASSERT(b->proc != nullptr);
  178. array_clear(&b->values);
  179. array_clear(&b->preds);
  180. array_clear(&b->succs);
  181. b->proc = nullptr;
  182. b->kind = ssaBlock_Plain;
  183. }
  184. void ssa_start_block(ssaProc *p, ssaBlock *b) {
  185. GB_ASSERT(p->curr_block == nullptr);
  186. p->curr_block = b;
  187. }
  188. ssaBlock *ssa_end_block(ssaProc *p) {
  189. ssaBlock *b = p->curr_block;
  190. if (b == nullptr) {
  191. return nullptr;
  192. }
  193. p->curr_block = nullptr;
  194. return b;
  195. }
  196. void ssa_add_edge_to(ssaBlock *b, ssaBlock *c) {
  197. if (b == nullptr) {
  198. return;
  199. }
  200. GB_ASSERT(c != nullptr);
  201. isize i = b->succs.count;
  202. isize j = b->preds.count;
  203. ssaEdge s = {c, j};
  204. ssaEdge p = {b, i};
  205. array_add(&b->succs, s);
  206. array_add(&c->preds, p);
  207. }
  208. void ssa_set_control(ssaBlock *b, ssaValue *v) {
  209. if (b->control != nullptr) {
  210. b->control->uses--;
  211. }
  212. b->control = v;
  213. if (v != nullptr) {
  214. v->uses++;
  215. }
  216. }
  217. void ssa_emit_jump(ssaProc *p, ssaBlock *edge) {
  218. ssa_add_edge_to(ssa_end_block(p), edge);
  219. }
  220. void ssa_init_value_args(ssaValueArgs *va, gbAllocator a) {
  221. va->e = va->backing;
  222. va->count = 0;
  223. va->capacity = gb_count_of(va->backing);
  224. va->allocator = a;
  225. }
  226. void ssa_add_arg(ssaValueArgs *va, ssaValue *arg) {
  227. if (va->count >= va->capacity) {
  228. isize capacity = 2*va->capacity;
  229. if (va->e == va->backing) { // Replace the backing with an allocated version instead
  230. ssaValue **new_args = gb_alloc_array(va->allocator, ssaValue *, capacity);
  231. gb_memcopy_array(new_args, va->e, va->count);
  232. va->e = new_args;
  233. } else {
  234. isize old_cap_size = va->capacity * gb_size_of(ssaValue *);
  235. isize new_cap_size = capacity * gb_size_of(ssaValue *);
  236. *(cast(void **)&va->e) = gb_resize(va->allocator, va->e, old_cap_size, new_cap_size);
  237. }
  238. va->capacity = capacity;
  239. }
  240. va->e[va->count++] = arg; arg->uses++;
  241. }
  242. ssaValue *ssa_new_value(ssaProc *p, ssaOp op, Type *t, ssaBlock *b) {
  243. GB_ASSERT(b != nullptr);
  244. ssaValue *v = gb_alloc_item(p->allocator, ssaValue);
  245. v->id = p->value_id++;
  246. v->op = op;
  247. v->type = t;
  248. v->block = b;
  249. ssa_init_value_args(&v->args, p->allocator);
  250. array_add(&b->values, v);
  251. return v;
  252. }
  253. ssaValue *ssa_new_value0(ssaProc *p, ssaOp op, Type *t) {
  254. ssaValue *v = ssa_new_value(p, op, t, p->curr_block);
  255. return v;
  256. }
  257. ssaValue *ssa_new_value0v(ssaProc *p, ssaOp op, Type *t, ExactValue exact_value) {
  258. ssaValue *v = ssa_new_value0(p, op, t);
  259. v->exact_value = exact_value;
  260. return v;
  261. }
  262. ssaValue *ssa_new_value1(ssaProc *p, ssaOp op, Type *t, ssaValue *arg) {
  263. ssaValue *v = ssa_new_value(p, op, t, p->curr_block);
  264. ssa_add_arg(&v->args, arg);
  265. return v;
  266. }
  267. ssaValue *ssa_new_value1v(ssaProc *p, ssaOp op, Type *t, ExactValue exact_value, ssaValue *arg) {
  268. ssaValue *v = ssa_new_value1(p, op, t, arg);
  269. v->exact_value = exact_value;
  270. return v;
  271. }
  272. ssaValue *ssa_new_value1i(ssaProc *p, ssaOp op, Type *t, i64 i, ssaValue *arg) {
  273. return ssa_new_value1v(p, op, t, exact_value_i64(i), arg);
  274. }
  275. ssaValue *ssa_new_value2(ssaProc *p, ssaOp op, Type *t, ssaValue *arg0, ssaValue *arg1) {
  276. ssaValue *v = ssa_new_value(p, op, t, p->curr_block);
  277. ssa_add_arg(&v->args, arg0);
  278. ssa_add_arg(&v->args, arg1);
  279. return v;
  280. }
  281. ssaValue *ssa_new_value2v(ssaProc *p, ssaOp op, Type *t, ExactValue exact_value, ssaValue *arg0, ssaValue *arg1) {
  282. ssaValue *v = ssa_new_value2(p, op, t, arg0, arg1);
  283. v->exact_value = exact_value;
  284. return v;
  285. }
  286. ssaValue *ssa_new_value3(ssaProc *p, ssaOp op, Type *t, ssaValue *arg0, ssaValue *arg1, ssaValue *arg2) {
  287. ssaValue *v = ssa_new_value(p, op, t, p->curr_block);
  288. ssa_add_arg(&v->args, arg0);
  289. ssa_add_arg(&v->args, arg1);
  290. ssa_add_arg(&v->args, arg2);
  291. return v;
  292. }
  293. ssaValue *ssa_new_value3v(ssaProc *p, ssaOp op, Type *t, ExactValue exact_value, ssaValue *arg0, ssaValue *arg1, ssaValue *arg2) {
  294. ssaValue *v = ssa_new_value3(p, op, t, arg0, arg1, arg2);
  295. v->exact_value = exact_value;
  296. return v;
  297. }
  298. ssaValue *ssa_new_value4(ssaProc *p, ssaOp op, Type *t, ssaValue *arg0, ssaValue *arg1, ssaValue *arg2, ssaValue *arg3) {
  299. ssaValue *v = ssa_new_value(p, op, t, p->curr_block);
  300. ssa_add_arg(&v->args, arg0);
  301. ssa_add_arg(&v->args, arg1);
  302. ssa_add_arg(&v->args, arg2);
  303. ssa_add_arg(&v->args, arg3);
  304. return v;
  305. }
  306. ssaValue *ssa_const_val(ssaProc *p, ssaOp op, Type *t, ExactValue exact_value) {
  307. return ssa_new_value0v(p, op, t, exact_value);
  308. }
  309. ssaValue *ssa_const_bool (ssaProc *p, Type *t, bool c) { return ssa_const_val(p, ssaOp_ConstBool, t, exact_value_bool(c)); }
  310. ssaValue *ssa_const_i8 (ssaProc *p, Type *t, i8 c) { return ssa_const_val(p, ssaOp_Const8, t, exact_value_i64(cast(i64)c)); }
  311. ssaValue *ssa_const_i16 (ssaProc *p, Type *t, i16 c) { return ssa_const_val(p, ssaOp_Const16, t, exact_value_i64(cast(i64)c)); }
  312. ssaValue *ssa_const_i32 (ssaProc *p, Type *t, i32 c) { return ssa_const_val(p, ssaOp_Const32, t, exact_value_i64(cast(i64)c)); }
  313. ssaValue *ssa_const_i64 (ssaProc *p, Type *t, i64 c) { return ssa_const_val(p, ssaOp_Const64, t, exact_value_i64(cast(i64)c)); }
  314. ssaValue *ssa_const_f32 (ssaProc *p, Type *t, f32 c) { return ssa_const_val(p, ssaOp_Const32F, t, exact_value_float(c)); }
  315. ssaValue *ssa_const_f64 (ssaProc *p, Type *t, f64 c) { return ssa_const_val(p, ssaOp_Const64F, t, exact_value_float(c)); }
  316. ssaValue *ssa_const_string (ssaProc *p, Type *t, String c) { return ssa_const_val(p, ssaOp_ConstString, t, exact_value_string(c)); }
  317. ssaValue *ssa_const_empty_string(ssaProc *p, Type *t) { return ssa_const_val(p, ssaOp_ConstString, t, empty_exact_value); }
  318. ssaValue *ssa_const_slice (ssaProc *p, Type *t, ExactValue v) { return ssa_const_val(p, ssaOp_ConstSlice, t, v); }
  319. ssaValue *ssa_const_nil (ssaProc *p, Type *t) { return ssa_const_val(p, ssaOp_ConstNil, t, empty_exact_value); }
  320. ssaValue *ssa_const_int(ssaProc *p, Type *t, i64 c) {
  321. switch (8*type_size_of(p->allocator, t)) {
  322. case 8: return ssa_const_i8 (p, t, cast(i8)c);
  323. case 16: return ssa_const_i16(p, t, cast(i16)c);
  324. case 32: return ssa_const_i32(p, t, cast(i32)c);
  325. case 64: return ssa_const_i64(p, t, cast(i64)c);
  326. }
  327. GB_PANIC("Unknown int size");
  328. return nullptr;
  329. }
  330. ssaAddr ssa_build_addr (ssaProc *p, AstNode *expr);
  331. ssaValue *ssa_build_expr (ssaProc *p, AstNode *expr);
  332. void ssa_build_stmt (ssaProc *p, AstNode *node);
  333. void ssa_build_stmt_list(ssaProc *p, Array<AstNode *> nodes);
  334. ssaValue *ssa_emit_deep_field_ptr_index(ssaProc *p, ssaValue *e, Selection sel);
  335. void ssa_reset_value_args(ssaValue *v) {
  336. for_array(i, v->args) {
  337. v->args[i]->uses--;
  338. }
  339. v->args.count = 0;
  340. }
  341. void ssa_reset(ssaValue *v, ssaOp op) {
  342. v->op = op;
  343. v->exact_value = empty_exact_value;
  344. ssa_reset_value_args(v);
  345. }
  346. ssaValue *ssa_get_last_value(ssaBlock *b) {
  347. if (b == nullptr) {
  348. return nullptr;
  349. }
  350. isize len = b->values.count;
  351. if (len <= 0) {
  352. return 0;
  353. }
  354. ssaValue *v = b->values[len-1];
  355. return v;
  356. }
  357. void ssa_emit_comment(ssaProc *p, String s) {
  358. // ssa_new_value0v(p, ssaOp_Comment, nullptr, exact_value_string(s));
  359. }
  360. void ssa_build_defer_stmt(ssaProc *p, ssaDefer d) {
  361. // ssaValue *last_instr = ssa_get_last_value(p->curr_block);
  362. ssaBlock *b = ssa_new_block(p, ssaBlock_Plain, "defer");
  363. ssa_emit_jump(p, b);
  364. ssa_start_block(p, b);
  365. ssa_emit_comment(p, str_lit("defer"));
  366. if (d.kind == ssaDefer_Node) {
  367. ssa_build_stmt(p, d.stmt);
  368. } else if (d.kind == ssaDefer_Instr) {
  369. // NOTE(bill): Need to make a new copy
  370. ssaValue *v = cast(ssaValue *)gb_alloc_copy(p->allocator, d.instr, gb_size_of(ssaValue));
  371. array_add(&p->curr_block->values, v);
  372. }
  373. }
  374. void ssa_emit_defer_stmts(ssaProc *p, ssaDeferExitKind kind, ssaBlock *b) {
  375. isize count = p->defer_stmts.count;
  376. for (isize i = count-1; i >= 0; i--) {
  377. ssaDefer d = p->defer_stmts[i];
  378. if (kind == ssaDeferExit_Default) {
  379. gb_printf_err("scope_level %d %d\n", p->scope_level, d.scope_level);
  380. if (p->scope_level == d.scope_level &&
  381. d.scope_level > 1) {
  382. ssa_build_defer_stmt(p, d);
  383. array_pop(&p->defer_stmts);
  384. continue;
  385. } else {
  386. break;
  387. }
  388. } else if (kind == ssaDeferExit_Return) {
  389. ssa_build_defer_stmt(p, d);
  390. } else if (kind == ssaDeferExit_Branch) {
  391. GB_ASSERT(b != nullptr);
  392. i32 lower_limit = b->scope_level+1;
  393. if (lower_limit < d.scope_level) {
  394. ssa_build_defer_stmt(p, d);
  395. }
  396. }
  397. }
  398. }
  399. ssaDefer ssa_add_defer_node(ssaProc *p, i32 scope_level, AstNode *stmt) {
  400. ssaDefer d = {ssaDefer_Node};
  401. d.scope_level = scope_level;
  402. d.block = p->curr_block;
  403. d.stmt = stmt;
  404. array_add(&p->defer_stmts, d);
  405. return d;
  406. }
  407. void ssa_open_scope(ssaProc *p) {
  408. p->scope_level++;
  409. }
  410. void ssa_close_scope(ssaProc *p, ssaDeferExitKind kind, ssaBlock *b) {
  411. ssa_emit_defer_stmts(p, kind, b);
  412. GB_ASSERT(p->scope_level > 0);
  413. p->scope_level--;
  414. }
  415. ssaValue *ssa_emit_load(ssaProc *p, ssaValue *v) {
  416. GB_ASSERT(is_type_pointer(v->type));
  417. return ssa_new_value1(p, ssaOp_Load, type_deref(v->type), v);
  418. }
  419. ssaValue *ssa_emit_store(ssaProc *p, ssaValue *dst, ssaValue *v) {
  420. GB_ASSERT(is_type_pointer(dst->type));
  421. #if 1
  422. // NOTE(bill): Sanity check
  423. Type *a = core_type(type_deref(dst->type));
  424. Type *b = core_type(v->type);
  425. if (!is_type_untyped(b)) {
  426. GB_ASSERT_MSG(are_types_identical(a, b), "%s %s", type_to_string(a), type_to_string(b));
  427. }
  428. #endif
  429. return ssa_new_value2(p, ssaOp_Store, dst->type, dst, v);
  430. }
  431. bool ssa_is_op_const(ssaOp op) {
  432. switch (op) {
  433. case ssaOp_ConstBool:
  434. case ssaOp_ConstString:
  435. case ssaOp_ConstSlice:
  436. case ssaOp_ConstNil:
  437. case ssaOp_Const8:
  438. case ssaOp_Const16:
  439. case ssaOp_Const32:
  440. case ssaOp_Const64:
  441. case ssaOp_Const32F:
  442. case ssaOp_Const64F:
  443. return true;
  444. }
  445. return false;
  446. }
  447. bool ssa_is_blank_ident(AstNode *node) {
  448. if (node->kind == AstNode_Ident) {
  449. ast_node(i, Ident, node);
  450. return is_blank_ident(i->token.string);
  451. }
  452. return false;
  453. }
  454. ssaAddr ssa_addr(ssaValue *v) {
  455. if (v != nullptr) {
  456. GB_ASSERT(is_type_pointer(v->type));
  457. }
  458. ssaAddr addr = {0};
  459. addr.addr = v;
  460. return addr;
  461. }
  462. Type *ssa_addr_type(ssaAddr addr) {
  463. if (addr.addr == nullptr) {
  464. return nullptr;
  465. }
  466. if (addr.kind == ssaAddr_Map) {
  467. GB_PANIC("TODO: ssa_addr_type");
  468. return nullptr;
  469. }
  470. Type *t = addr.addr->type;
  471. GB_ASSERT(is_type_pointer(t));
  472. return type_deref(t);
  473. }
  474. ssaProc *ssa_new_proc(ssaModule *m, String name, Entity *entity, DeclInfo *decl_info) {
  475. ssaProc *p = gb_alloc_item(m->allocator, ssaProc);
  476. p->module = m;
  477. p->allocator = m->allocator;
  478. p->name = name;
  479. p->entity = entity;
  480. p->decl_info = decl_info;
  481. array_init(&p->blocks, heap_allocator());
  482. array_init(&p->defer_stmts, heap_allocator());
  483. map_init(&p->values, heap_allocator());
  484. return p;
  485. }
  486. ssaAddr ssa_add_local(ssaProc *p, Entity *e, AstNode *expr) {
  487. Type *t = make_type_pointer(p->allocator, e->type);
  488. ssaBlock *cb = p->curr_block;
  489. p->curr_block = p->entry;
  490. ssaValue *local = ssa_new_value0(p, ssaOp_Local, t);
  491. p->curr_block = cb;
  492. map_set(&p->values, hash_pointer(e), local);
  493. map_set(&p->module->values, hash_pointer(e), local);
  494. local->comment_string = e->token.string;
  495. ssa_new_value1(p, ssaOp_Zero, t, local);
  496. return ssa_addr(local);
  497. }
  498. ssaAddr ssa_add_local_for_ident(ssaProc *p, AstNode *name) {
  499. Entity **found = map_get(&p->module->info->definitions, hash_pointer(name));
  500. if (found) {
  501. Entity *e = *found;
  502. return ssa_add_local(p, e, name);
  503. }
  504. return ssa_addr(nullptr);
  505. }
  506. ssaAddr ssa_add_local_generated(ssaProc *p, Type *t) {
  507. GB_ASSERT(t != nullptr);
  508. Scope *scope = nullptr;
  509. if (p->curr_block) {
  510. // scope = p->curr_block->scope;
  511. }
  512. Entity *e = make_entity_variable(p->allocator, scope, empty_token, t, false);
  513. return ssa_add_local(p, e, nullptr);
  514. }
  515. #define SSA_MAX_STRUCT_FIELD_COUNT 4
  516. bool can_ssa_type(Type *t) {
  517. i64 s = type_size_of(heap_allocator(), t);
  518. if (s > 4*build_context.word_size) {
  519. return false;
  520. }
  521. t = core_type(t);
  522. switch (t->kind) {
  523. case Type_Array:
  524. return t->Array.count == 0;
  525. case Type_Vector:
  526. return s < 2*build_context.word_size;
  527. case Type_DynamicArray:
  528. return false;
  529. case Type_Map:
  530. return false;
  531. case Type_Tuple:
  532. if (t->Tuple.variables.count > SSA_MAX_STRUCT_FIELD_COUNT) {
  533. return false;
  534. }
  535. for_array(i, t->Tuple.variables) {
  536. if (!can_ssa_type(t->Tuple.variables[i]->type)) {
  537. return false;
  538. }
  539. }
  540. return true;
  541. case Type_Union:
  542. return false;
  543. case Type_Struct:
  544. if (!t->Struct.is_raw_union) {
  545. if (t->Struct.fields.count > SSA_MAX_STRUCT_FIELD_COUNT) {
  546. return false;
  547. }
  548. for_array(i, t->Struct.fields) {
  549. if (!can_ssa_type(t->Struct.fields[i]->type)) {
  550. return false;
  551. }
  552. }
  553. }
  554. return true;
  555. }
  556. return true;
  557. }
  558. void ssa_addr_store(ssaProc *p, ssaAddr addr, ssaValue *value) {
  559. if (addr.addr == nullptr) {
  560. return;
  561. }
  562. if (addr.kind == ssaAddr_Map) {
  563. GB_PANIC("TODO(bill): ssa_addr_store");
  564. return;
  565. }
  566. ssa_emit_store(p, addr.addr, value);
  567. }
  568. ssaValue *ssa_addr_load(ssaProc *p, ssaAddr addr) {
  569. if (addr.addr == nullptr) {
  570. return nullptr;
  571. }
  572. if (addr.kind == ssaAddr_Map) {
  573. GB_PANIC("here\n");
  574. return nullptr;
  575. }
  576. Type *t = addr.addr->type;
  577. Type *bt = base_type(t);
  578. if (bt->kind == Type_Proc) {
  579. return addr.addr;
  580. }
  581. return ssa_emit_load(p, addr.addr);
  582. }
  583. ssaValue *ssa_get_using_variable(ssaProc *p, Entity *e) {
  584. GB_ASSERT(e->kind == Entity_Variable && e->flags & EntityFlag_Using);
  585. String name = e->token.string;
  586. Entity *parent = e->using_parent;
  587. Selection sel = lookup_field(p->allocator, parent->type, name, false);
  588. GB_ASSERT(sel.entity != nullptr);
  589. ssaValue **pv = map_get(&p->module->values, hash_pointer(parent));
  590. ssaValue *v = nullptr;
  591. if (pv != nullptr) {
  592. v = *pv;
  593. } else {
  594. v = ssa_build_addr(p, e->using_expr).addr;
  595. }
  596. GB_ASSERT(v != nullptr);
  597. GB_ASSERT(type_deref(v->type) == parent->type);
  598. return ssa_emit_deep_field_ptr_index(p, v, sel);
  599. }
  600. ssaAddr ssa_build_addr_from_entity(ssaProc *p, Entity *e, AstNode *expr) {
  601. GB_ASSERT(e != nullptr);
  602. ssaValue *v = nullptr;
  603. ssaValue **found = map_get(&p->module->values, hash_pointer(e));
  604. if (found) {
  605. v = *found;
  606. } else if (e->kind == Entity_Variable && e->flags & EntityFlag_Using) {
  607. // NOTE(bill): Calculate the using variable every time
  608. v = ssa_get_using_variable(p, e);
  609. }
  610. if (v == nullptr) {
  611. GB_PANIC("Unknown value: %.*s, entity: %p %.*s\n", LIT(e->token.string), e, LIT(entity_strings[e->kind]));
  612. }
  613. return ssa_addr(v);
  614. }
  615. ssaValue *ssa_emit_conv(ssaProc *p, ssaValue *v, Type *t) {
  616. Type *src_type = v->type;
  617. if (are_types_identical(t, src_type)) {
  618. return v;
  619. }
  620. Type *src = core_type(src_type);
  621. Type *dst = core_type(t);
  622. if (is_type_untyped_nil(src)) {
  623. return ssa_const_nil(p, t);
  624. }
  625. // Pointer <-> Pointer
  626. if (is_type_pointer(src) && is_type_pointer(dst)) {
  627. return ssa_new_value1(p, ssaOp_Copy, dst, v);
  628. }
  629. // proc <-> proc
  630. if (is_type_proc(src) && is_type_proc(dst)) {
  631. return ssa_new_value1(p, ssaOp_Copy, dst, v);
  632. }
  633. // pointer -> proc
  634. if (is_type_pointer(src) && is_type_proc(dst)) {
  635. return ssa_new_value1(p, ssaOp_Copy, dst, v);
  636. }
  637. // proc -> pointer
  638. if (is_type_proc(src) && is_type_pointer(dst)) {
  639. return ssa_new_value1(p, ssaOp_Copy, dst, v);
  640. }
  641. gb_printf_err("ssa_emit_conv: src -> dst\n");
  642. gb_printf_err("Not Identical %s != %s\n", type_to_string(src_type), type_to_string(t));
  643. gb_printf_err("Not Identical %s != %s\n", type_to_string(src), type_to_string(dst));
  644. GB_PANIC("Invalid type conversion: `%s` to `%s`", type_to_string(src_type), type_to_string(t));
  645. return nullptr;
  646. }
  647. // NOTE(bill): Returns nullptr if not possible
  648. ssaValue *ssa_address_from_load_or_generate_local(ssaProc *p, ssaValue *v) {
  649. if (v->op == ssaOp_Load) {
  650. return v->args[0];
  651. }
  652. ssaAddr addr = ssa_add_local_generated(p, v->type);
  653. ssa_new_value2(p, ssaOp_Store, addr.addr->type, addr.addr, v);
  654. return addr.addr;
  655. }
  656. ssaValue *ssa_emit_array_index(ssaProc *p, ssaValue *v, ssaValue *index) {
  657. GB_ASSERT(v != nullptr);
  658. GB_ASSERT(is_type_pointer(v->type));
  659. Type *t = base_type(type_deref(v->type));
  660. GB_ASSERT_MSG(is_type_array(t) || is_type_vector(t), "%s", type_to_string(t));
  661. Type *elem_ptr = nullptr;
  662. if (is_type_array(t)) {
  663. elem_ptr = make_type_pointer(p->allocator, t->Array.elem);
  664. } else if (is_type_vector(t)) {
  665. elem_ptr = make_type_pointer(p->allocator, t->Vector.elem);
  666. }
  667. return ssa_new_value2(p, ssaOp_ArrayIndex, elem_ptr, v, index);
  668. }
  669. ssaValue *ssa_emit_ptr_index(ssaProc *p, ssaValue *s, i64 index) {
  670. gbAllocator a = p->allocator;
  671. Type *t = base_type(type_deref(s->type));
  672. Type *result_type = nullptr;
  673. if (is_type_struct(t)) {
  674. GB_ASSERT(t->Struct.fields.count > 0);
  675. result_type = make_type_pointer(a, t->Struct.fields[index]->type);
  676. } else if (is_type_tuple(t)) {
  677. GB_ASSERT(t->Tuple.variables.count > 0);
  678. GB_ASSERT(gb_is_between(index, 0, t->Tuple.variables.count-1));
  679. result_type = make_type_pointer(a, t->Tuple.variables[index]->type);
  680. } else if (is_type_slice(t)) {
  681. switch (index) {
  682. case 0: result_type = make_type_pointer(a, make_type_pointer(a, t->Slice.elem)); break;
  683. case 1: result_type = make_type_pointer(a, t_int); break;
  684. case 2: result_type = make_type_pointer(a, t_int); break;
  685. }
  686. } else if (is_type_string(t)) {
  687. switch (index) {
  688. case 0: result_type = make_type_pointer(a, t_u8_ptr); break;
  689. case 1: result_type = make_type_pointer(a, t_int); break;
  690. }
  691. } else if (is_type_any(t)) {
  692. switch (index) {
  693. case 0: result_type = make_type_pointer(a, t_type_info_ptr); break;
  694. case 1: result_type = make_type_pointer(a, t_rawptr); break;
  695. }
  696. } else if (is_type_dynamic_array(t)) {
  697. switch (index) {
  698. case 0: result_type = make_type_pointer(a, make_type_pointer(a, t->DynamicArray.elem)); break;
  699. case 1: result_type = t_int_ptr; break;
  700. case 2: result_type = t_int_ptr; break;
  701. case 3: result_type = t_allocator_ptr; break;
  702. }
  703. } else if (is_type_map(t)) {
  704. Type *gst = t->Map.generated_struct_type;
  705. switch (index) {
  706. case 0: result_type = make_type_pointer(a, gst->Struct.fields[0]->type); break;
  707. case 1: result_type = make_type_pointer(a, gst->Struct.fields[1]->type); break;
  708. }
  709. }else {
  710. GB_PANIC("TODO(bill): ssa_emit_ptr_index type: %s, %d", type_to_string(s->type), index);
  711. }
  712. GB_ASSERT(result_type != nullptr);
  713. return ssa_new_value1i(p, ssaOp_PtrIndex, result_type, index, s);
  714. }
  715. ssaValue *ssa_emit_value_index(ssaProc *p, ssaValue *s, i64 index) {
  716. if (s->op == ssaOp_Load) {
  717. if (!can_ssa_type(s->type)) {
  718. ssaValue *e = ssa_emit_ptr_index(p, s->args[0], index);
  719. return ssa_emit_load(p, e);
  720. }
  721. }
  722. GB_ASSERT(can_ssa_type(s->type));
  723. gbAllocator a = p->allocator;
  724. Type *t = base_type(s->type);
  725. Type *result_type = nullptr;
  726. if (is_type_struct(t)) {
  727. GB_ASSERT(t->Struct.fields.count > 0);
  728. result_type = t->Struct.fields[index]->type;
  729. } else if (is_type_union(t)) {
  730. type_set_offsets(a, t);
  731. GB_ASSERT(t->Struct.fields.count > 0);
  732. result_type = t->Struct.fields[index]->type;
  733. } else if (is_type_tuple(t)) {
  734. GB_ASSERT(t->Tuple.variables.count > 0);
  735. result_type = t->Tuple.variables[index]->type;
  736. } else if (is_type_slice(t)) {
  737. switch (index) {
  738. case 0: result_type = make_type_pointer(a, t->Slice.elem); break;
  739. case 1: result_type = t_int; break;
  740. case 2: result_type = t_int; break;
  741. }
  742. } else if (is_type_string(t)) {
  743. switch (index) {
  744. case 0: result_type = t_u8_ptr; break;
  745. case 1: result_type = t_int; break;
  746. }
  747. } else if (is_type_any(t)) {
  748. switch (index) {
  749. case 0: result_type = t_type_info_ptr; break;
  750. case 1: result_type = t_rawptr; break;
  751. }
  752. } else if (is_type_dynamic_array(t)) {
  753. switch (index) {
  754. case 0: result_type = make_type_pointer(a, t->DynamicArray.elem); break;
  755. case 1: result_type = t_int; break;
  756. case 2: result_type = t_int; break;
  757. case 3: result_type = t_allocator; break;
  758. }
  759. } else if (is_type_map(t)) {
  760. Type *gst = t->Map.generated_struct_type;
  761. switch (index) {
  762. case 0: result_type = gst->Struct.fields[0]->type; break;
  763. case 1: result_type = gst->Struct.fields[1]->type; break;
  764. }
  765. } else {
  766. GB_PANIC("TODO(bill): struct_ev type: %s, %d", type_to_string(s->type), index);
  767. }
  768. GB_ASSERT(result_type != nullptr);
  769. return ssa_new_value1i(p, ssaOp_ValueIndex, result_type, index, s);
  770. }
  771. ssaValue *ssa_emit_deep_field_ptr_index(ssaProc *p, ssaValue *e, Selection sel) {
  772. GB_ASSERT(sel.index.count > 0);
  773. Type *type = type_deref(e->type);
  774. for_array(i, sel.index) {
  775. i32 index = cast(i32)sel.index[i];
  776. if (is_type_pointer(type)) {
  777. type = type_deref(type);
  778. e = ssa_emit_load(p, e);
  779. }
  780. type = base_type(type);
  781. if (is_type_raw_union(type)) {
  782. type = type->Struct.fields[index]->type;
  783. e = ssa_emit_conv(p, e, make_type_pointer(p->allocator, type));
  784. } else if (type->kind == Type_Struct) {
  785. type = type->Struct.fields[index]->type;
  786. e = ssa_emit_ptr_index(p, e, index);
  787. } else if (type->kind == Type_Tuple) {
  788. type = type->Tuple.variables[index]->type;
  789. e = ssa_emit_ptr_index(p, e, index);
  790. }else if (type->kind == Type_Basic) {
  791. switch (type->Basic.kind) {
  792. case Basic_any: {
  793. if (index == 0) {
  794. type = t_type_info_ptr;
  795. } else if (index == 1) {
  796. type = t_rawptr;
  797. }
  798. e = ssa_emit_ptr_index(p, e, index);
  799. } break;
  800. case Basic_string:
  801. e = ssa_emit_ptr_index(p, e, index);
  802. break;
  803. default:
  804. GB_PANIC("un-gep-able type");
  805. break;
  806. }
  807. } else if (type->kind == Type_Slice) {
  808. e = ssa_emit_ptr_index(p, e, index);
  809. } else if (type->kind == Type_DynamicArray) {
  810. e = ssa_emit_ptr_index(p, e, index);
  811. } else if (type->kind == Type_Vector) {
  812. e = ssa_emit_array_index(p, e, ssa_const_int(p, t_int, index));
  813. } else if (type->kind == Type_Array) {
  814. e = ssa_emit_array_index(p, e, ssa_const_int(p, t_int, index));
  815. } else if (type->kind == Type_Map) {
  816. e = ssa_emit_ptr_index(p, e, 1);
  817. switch (index) {
  818. case 0: e = ssa_emit_ptr_index(p, e, 1); break; // count
  819. case 1: e = ssa_emit_ptr_index(p, e, 2); break; // capacity
  820. case 2: e = ssa_emit_ptr_index(p, e, 3); break; // allocator
  821. }
  822. } else {
  823. GB_PANIC("un-gep-able type");
  824. }
  825. }
  826. return e;
  827. }
  828. ssaValue *ssa_emit_deep_field_value_index(ssaProc *p, ssaValue *e, Selection sel) {
  829. GB_ASSERT(sel.index.count > 0);
  830. Type *type = e->type;
  831. if (e->op == ssaOp_Load) {
  832. if (!can_ssa_type(e->type)) {
  833. ssaValue *ptr = ssa_emit_deep_field_ptr_index(p, e->args[0], sel);
  834. return ssa_emit_load(p, ptr);
  835. }
  836. }
  837. GB_ASSERT(can_ssa_type(e->type));
  838. for_array(i, sel.index) {
  839. i32 index = cast(i32)sel.index[i];
  840. if (is_type_pointer(type)) {
  841. e = ssa_emit_load(p, e);
  842. }
  843. type = base_type(type);
  844. if (is_type_raw_union(type)) {
  845. GB_PANIC("TODO(bill): IS THIS EVEN CORRECT?");
  846. type = type->Struct.fields[index]->type;
  847. e = ssa_emit_conv(p, e, type);
  848. } else if (type->kind == Type_Map) {
  849. e = ssa_emit_value_index(p, e, 1);
  850. switch (index) {
  851. case 0: e = ssa_emit_value_index(p, e, 1); break; // count
  852. case 1: e = ssa_emit_value_index(p, e, 2); break; // capacity
  853. case 2: e = ssa_emit_value_index(p, e, 3); break; // allocator
  854. }
  855. } else {
  856. e = ssa_emit_value_index(p, e, index);
  857. }
  858. }
  859. return e;
  860. }
  861. ssaAddr ssa_build_addr(ssaProc *p, AstNode *expr) {
  862. switch (expr->kind) {
  863. case_ast_node(i, Ident, expr);
  864. if (ssa_is_blank_ident(expr)) {
  865. ssaAddr val = {0};
  866. return val;
  867. }
  868. Entity *e = entity_of_ident(p->module->info, expr);
  869. return ssa_build_addr_from_entity(p, e, expr);
  870. case_end;
  871. case_ast_node(pe, ParenExpr, expr);
  872. return ssa_build_addr(p, unparen_expr(expr));
  873. case_end;
  874. case_ast_node(se, SelectorExpr, expr);
  875. ssa_emit_comment(p, str_lit("SelectorExpr"));
  876. AstNode *sel = unparen_expr(se->selector);
  877. if (sel->kind == AstNode_Ident) {
  878. String selector = sel->Ident.token.string;
  879. TypeAndValue tav = type_and_value_of_expr(p->module->info, se->expr);
  880. if (tav.mode == Addressing_Invalid) {
  881. // NOTE(bill): Imports
  882. Entity *imp = entity_of_ident(p->module->info, se->expr);
  883. if (imp != nullptr) {
  884. GB_ASSERT(imp->kind == Entity_ImportName);
  885. }
  886. return ssa_build_addr(p, se->selector);
  887. }
  888. Type *type = base_type(tav.type);
  889. if (tav.mode == Addressing_Type) { // Addressing_Type
  890. GB_PANIC("TODO: SelectorExpr Addressing_Type");
  891. // Selection sel = lookup_field(p->allocator, type, selector, true);
  892. // Entity *e = sel.entity;
  893. // GB_ASSERT(e->kind == Entity_Variable);
  894. // GB_ASSERT(e->flags & EntityFlag_TypeField);
  895. // String name = e->token.string;
  896. // if (name == "names") {
  897. // ssaValue *ti_ptr = ir_type_info(p, type);
  898. // ssaValue *names_ptr = nullptr;
  899. // if (is_type_enum(type)) {
  900. // ssaValue *enum_info = ssa_emit_conv(p, ti_ptr, t_type_info_enum_ptr);
  901. // names_ptr = ssa_emit_ptr_index(p, enum_info, 1);
  902. // } else if (type->kind == Type_Struct) {
  903. // ssaValue *struct_info = ssa_emit_conv(p, ti_ptr, t_type_info_struct_ptr);
  904. // names_ptr = ssa_emit_ptr_index(p, struct_info, 1);
  905. // }
  906. // return ssa_addr(names_ptr);
  907. // } else {
  908. // GB_PANIC("Unhandled TypeField %.*s", LIT(name));
  909. // }
  910. GB_PANIC("Unreachable");
  911. }
  912. Selection sel = lookup_field(p->allocator, type, selector, false);
  913. GB_ASSERT(sel.entity != nullptr);
  914. ssaValue *a = ssa_build_addr(p, se->expr).addr;
  915. a = ssa_emit_deep_field_ptr_index(p, a, sel);
  916. return ssa_addr(a);
  917. } else {
  918. Type *type = base_type(type_of_expr(p->module->info, se->expr));
  919. GB_ASSERT(is_type_integer(type));
  920. ExactValue val = type_and_value_of_expr(p->module->info, sel).value;
  921. i64 index = i128_to_i64(val.value_integer);
  922. Selection sel = lookup_field_from_index(p->allocator, type, index);
  923. GB_ASSERT(sel.entity != nullptr);
  924. ssaValue *a = ssa_build_addr(p, se->expr).addr;
  925. a = ssa_emit_deep_field_ptr_index(p, a, sel);
  926. return ssa_addr(a);
  927. }
  928. case_end;
  929. case_ast_node(ue, UnaryExpr, expr);
  930. switch (ue->op.kind) {
  931. case Token_Pointer: {
  932. return ssa_build_addr(p, ue->expr);
  933. }
  934. default:
  935. GB_PANIC("Invalid unary expression for ssa_build_addr");
  936. }
  937. case_end;
  938. case_ast_node(be, BinaryExpr, expr);
  939. GB_PANIC("Invalid binary expression for ssa_build_addr: %.*s\n", LIT(be->op.string));
  940. case_end;
  941. case_ast_node(ie, IndexExpr, expr);
  942. GB_PANIC("TODO(bill): ssa_build_addr IndexExpr");
  943. case_end;
  944. case_ast_node(se, SliceExpr, expr);
  945. GB_PANIC("TODO(bill): ssa_build_addr SliceExpr");
  946. case_end;
  947. case_ast_node(de, DerefExpr, expr);
  948. ssaValue *addr = ssa_build_expr(p, de->expr);
  949. return ssa_addr(addr);
  950. case_end;
  951. case_ast_node(ce, CallExpr, expr);
  952. ssaValue *e = ssa_build_expr(p, expr);
  953. ssaValue *v = ssa_address_from_load_or_generate_local(p, e);
  954. return ssa_addr(v);
  955. case_end;
  956. case_ast_node(cl, CompoundLit, expr);
  957. GB_PANIC("TODO(bill): ssa_build_addr CompoundLit");
  958. case_end;
  959. }
  960. TokenPos token_pos = ast_node_token(expr).pos;
  961. GB_PANIC("Unexpected address expression\n"
  962. "\tAstNode: %.*s @ "
  963. "%.*s(%td:%td)\n",
  964. LIT(ast_node_strings[expr->kind]),
  965. LIT(token_pos.file), token_pos.line, token_pos.column);
  966. return ssa_addr(nullptr);
  967. }
  968. Type *ssa_proper_type(Type *t) {
  969. t = default_type(core_type(t));
  970. if (t->kind == Type_Basic) {
  971. switch (t->Basic.kind) {
  972. case Basic_int:
  973. if (build_context.word_size == 8) {
  974. return t_i64;
  975. }
  976. return t_i32;
  977. case Basic_uint:
  978. if (build_context.word_size == 8) {
  979. return t_u64;
  980. }
  981. return t_u32;
  982. }
  983. }
  984. return t;
  985. }
  986. ssaOp ssa_determine_op(TokenKind op, Type *t) {
  987. t = ssa_proper_type(t);
  988. if (t->kind == Type_Basic) {
  989. switch (t->Basic.kind) {
  990. case Basic_bool:
  991. switch (op) {
  992. case Token_And: return ssaOp_And8;
  993. case Token_Or: return ssaOp_Or8;
  994. case Token_Xor: return ssaOp_Xor8;
  995. case Token_AndNot: return ssaOp_AndNot8;
  996. }
  997. break;
  998. case Basic_i8:
  999. switch (op) {
  1000. case Token_Add: return ssaOp_Add8;
  1001. case Token_Sub: return ssaOp_Sub8;
  1002. case Token_Mul: return ssaOp_Mul8;
  1003. case Token_Quo: return ssaOp_Div8;
  1004. case Token_Mod: return ssaOp_Mod8;
  1005. case Token_And: return ssaOp_And8;
  1006. case Token_Or: return ssaOp_Or8;
  1007. case Token_Xor: return ssaOp_Xor8;
  1008. case Token_AndNot: return ssaOp_AndNot8;
  1009. case Token_Lt: return ssaOp_Lt8;
  1010. case Token_LtEq: return ssaOp_Le8;
  1011. case Token_Gt: return ssaOp_Gt8;
  1012. case Token_GtEq: return ssaOp_Ge8;
  1013. case Token_CmpEq: return ssaOp_Eq8;
  1014. case Token_NotEq: return ssaOp_Ne8;
  1015. }
  1016. break;
  1017. case Basic_u8:
  1018. switch (op) {
  1019. case Token_Add: return ssaOp_Add8;
  1020. case Token_Sub: return ssaOp_Sub8;
  1021. case Token_Mul: return ssaOp_Mul8;
  1022. case Token_Quo: return ssaOp_Div8U;
  1023. case Token_Mod: return ssaOp_Mod8U;
  1024. case Token_And: return ssaOp_And8;
  1025. case Token_Or: return ssaOp_Or8;
  1026. case Token_Xor: return ssaOp_Xor8;
  1027. case Token_AndNot: return ssaOp_AndNot8;
  1028. case Token_Lt: return ssaOp_Lt8;
  1029. case Token_LtEq: return ssaOp_Le8;
  1030. case Token_Gt: return ssaOp_Gt8;
  1031. case Token_GtEq: return ssaOp_Ge8;
  1032. case Token_CmpEq: return ssaOp_Eq8;
  1033. case Token_NotEq: return ssaOp_Ne8;
  1034. }
  1035. break;
  1036. case Basic_i16:
  1037. switch (op) {
  1038. case Token_Add: return ssaOp_Add16;
  1039. case Token_Sub: return ssaOp_Sub16;
  1040. case Token_Mul: return ssaOp_Mul16;
  1041. case Token_Quo: return ssaOp_Div16;
  1042. case Token_Mod: return ssaOp_Mod16;
  1043. case Token_And: return ssaOp_And16;
  1044. case Token_Or: return ssaOp_Or16;
  1045. case Token_Xor: return ssaOp_Xor16;
  1046. case Token_AndNot: return ssaOp_AndNot16;
  1047. case Token_Lt: return ssaOp_Lt16;
  1048. case Token_LtEq: return ssaOp_Le16;
  1049. case Token_Gt: return ssaOp_Gt16;
  1050. case Token_GtEq: return ssaOp_Ge16;
  1051. case Token_CmpEq: return ssaOp_Eq16;
  1052. case Token_NotEq: return ssaOp_Ne16;
  1053. }
  1054. break;
  1055. case Basic_u16:
  1056. switch (op) {
  1057. case Token_Add: return ssaOp_Add16;
  1058. case Token_Sub: return ssaOp_Sub16;
  1059. case Token_Mul: return ssaOp_Mul16;
  1060. case Token_Quo: return ssaOp_Div16U;
  1061. case Token_Mod: return ssaOp_Mod16U;
  1062. case Token_And: return ssaOp_And16;
  1063. case Token_Or: return ssaOp_Or16;
  1064. case Token_Xor: return ssaOp_Xor16;
  1065. case Token_AndNot: return ssaOp_AndNot16;
  1066. case Token_Lt: return ssaOp_Lt16;
  1067. case Token_LtEq: return ssaOp_Le16;
  1068. case Token_Gt: return ssaOp_Gt16;
  1069. case Token_GtEq: return ssaOp_Ge16;
  1070. case Token_CmpEq: return ssaOp_Eq16;
  1071. case Token_NotEq: return ssaOp_Ne16;
  1072. }
  1073. break;
  1074. case Basic_i32:
  1075. switch (op) {
  1076. case Token_Add: return ssaOp_Add32;
  1077. case Token_Sub: return ssaOp_Sub32;
  1078. case Token_Mul: return ssaOp_Mul32;
  1079. case Token_Quo: return ssaOp_Div32;
  1080. case Token_Mod: return ssaOp_Mod32;
  1081. case Token_And: return ssaOp_And32;
  1082. case Token_Or: return ssaOp_Or32;
  1083. case Token_Xor: return ssaOp_Xor32;
  1084. case Token_AndNot: return ssaOp_AndNot32;
  1085. case Token_Lt: return ssaOp_Lt32;
  1086. case Token_LtEq: return ssaOp_Le32;
  1087. case Token_Gt: return ssaOp_Gt32;
  1088. case Token_GtEq: return ssaOp_Ge32;
  1089. case Token_CmpEq: return ssaOp_Eq32;
  1090. case Token_NotEq: return ssaOp_Ne32;
  1091. }
  1092. break;
  1093. case Basic_u32:
  1094. switch (op) {
  1095. case Token_Add: return ssaOp_Add32;
  1096. case Token_Sub: return ssaOp_Sub32;
  1097. case Token_Mul: return ssaOp_Mul32;
  1098. case Token_Quo: return ssaOp_Div32U;
  1099. case Token_Mod: return ssaOp_Mod32U;
  1100. case Token_And: return ssaOp_And32;
  1101. case Token_Or: return ssaOp_Or32;
  1102. case Token_Xor: return ssaOp_Xor32;
  1103. case Token_AndNot: return ssaOp_AndNot32;
  1104. case Token_Lt: return ssaOp_Lt32;
  1105. case Token_LtEq: return ssaOp_Le32;
  1106. case Token_Gt: return ssaOp_Gt32;
  1107. case Token_GtEq: return ssaOp_Ge32;
  1108. case Token_CmpEq: return ssaOp_Eq32;
  1109. case Token_NotEq: return ssaOp_Ne32;
  1110. }
  1111. break;
  1112. case Basic_i64:
  1113. switch (op) {
  1114. case Token_Add: return ssaOp_Add64;
  1115. case Token_Sub: return ssaOp_Sub64;
  1116. case Token_Mul: return ssaOp_Mul64;
  1117. case Token_Quo: return ssaOp_Div64;
  1118. case Token_Mod: return ssaOp_Mod64;
  1119. case Token_And: return ssaOp_And64;
  1120. case Token_Or: return ssaOp_Or64;
  1121. case Token_Xor: return ssaOp_Xor64;
  1122. case Token_AndNot: return ssaOp_AndNot64;
  1123. case Token_Lt: return ssaOp_Lt64;
  1124. case Token_LtEq: return ssaOp_Le64;
  1125. case Token_Gt: return ssaOp_Gt64;
  1126. case Token_GtEq: return ssaOp_Ge64;
  1127. case Token_CmpEq: return ssaOp_Eq64;
  1128. case Token_NotEq: return ssaOp_Ne64;
  1129. }
  1130. break;
  1131. case Basic_u64:
  1132. switch (op) {
  1133. case Token_Add: return ssaOp_Add64;
  1134. case Token_Sub: return ssaOp_Sub64;
  1135. case Token_Mul: return ssaOp_Mul64;
  1136. case Token_Quo: return ssaOp_Div64U;
  1137. case Token_Mod: return ssaOp_Mod64U;
  1138. case Token_And: return ssaOp_And64;
  1139. case Token_Or: return ssaOp_Or64;
  1140. case Token_Xor: return ssaOp_Xor64;
  1141. case Token_AndNot: return ssaOp_AndNot64;
  1142. case Token_Lt: return ssaOp_Lt64;
  1143. case Token_LtEq: return ssaOp_Le64;
  1144. case Token_Gt: return ssaOp_Gt64;
  1145. case Token_GtEq: return ssaOp_Ge64;
  1146. case Token_CmpEq: return ssaOp_Eq64;
  1147. case Token_NotEq: return ssaOp_Ne64;
  1148. }
  1149. break;
  1150. case Basic_f32:
  1151. switch (op) {
  1152. case Token_Add: return ssaOp_Add32F;
  1153. case Token_Sub: return ssaOp_Sub32F;
  1154. case Token_Mul: return ssaOp_Mul32F;
  1155. case Token_Quo: return ssaOp_Div32F;
  1156. case Token_Lt: return ssaOp_Lt32F;
  1157. case Token_LtEq: return ssaOp_Le32F;
  1158. case Token_Gt: return ssaOp_Gt32F;
  1159. case Token_GtEq: return ssaOp_Ge32F;
  1160. case Token_CmpEq: return ssaOp_Eq32F;
  1161. case Token_NotEq: return ssaOp_Ne32F;
  1162. }
  1163. break;
  1164. case Basic_f64:
  1165. switch (op) {
  1166. case Token_Add: return ssaOp_Add64F;
  1167. case Token_Sub: return ssaOp_Sub64F;
  1168. case Token_Mul: return ssaOp_Mul64F;
  1169. case Token_Quo: return ssaOp_Div64F;
  1170. case Token_Lt: return ssaOp_Lt64F;
  1171. case Token_LtEq: return ssaOp_Le64F;
  1172. case Token_Gt: return ssaOp_Gt64F;
  1173. case Token_GtEq: return ssaOp_Ge64F;
  1174. case Token_CmpEq: return ssaOp_Eq64F;
  1175. case Token_NotEq: return ssaOp_Ne64F;
  1176. }
  1177. break;
  1178. }
  1179. }
  1180. GB_PANIC("Invalid Op for type");
  1181. return ssaOp_Invalid;
  1182. }
  1183. ssaValue *ssa_emit_comp(ssaProc *p, TokenKind op, ssaValue *x, ssaValue *y) {
  1184. GB_ASSERT(x != nullptr && y != nullptr);
  1185. Type *a = core_type(x->type);
  1186. Type *b = core_type(y->type);
  1187. if (are_types_identical(a, b)) {
  1188. // NOTE(bill): No need for a conversion
  1189. } else if (ssa_is_op_const(x->op)) {
  1190. x = ssa_emit_conv(p, x, y->type);
  1191. } else if (ssa_is_op_const(y->op)) {
  1192. y = ssa_emit_conv(p, y, x->type);
  1193. }
  1194. Type *result = t_bool;
  1195. if (is_type_vector(a)) {
  1196. result = make_type_vector(p->allocator, t_bool, a->Vector.count);
  1197. }
  1198. if (is_type_vector(a)) {
  1199. ssa_emit_comment(p, str_lit("vector.comp.begin"));
  1200. Type *tl = base_type(a);
  1201. ssaValue *lhs = ssa_address_from_load_or_generate_local(p, x);
  1202. ssaValue *rhs = ssa_address_from_load_or_generate_local(p, y);
  1203. GB_ASSERT(is_type_vector(result));
  1204. Type *elem_type = base_type(result)->Vector.elem;
  1205. ssaAddr addr = ssa_add_local_generated(p, result);
  1206. for (i32 i = 0; i < tl->Vector.count; i++) {
  1207. ssaValue *index = ssa_const_int(p, t_int, i);
  1208. ssaValue *x = ssa_emit_load(p, ssa_emit_array_index(p, lhs, index));
  1209. ssaValue *y = ssa_emit_load(p, ssa_emit_array_index(p, rhs, index));
  1210. ssaValue *z = ssa_emit_comp(p, op, x, y);
  1211. ssa_emit_store(p, ssa_emit_array_index(p, addr.addr, index), z);
  1212. }
  1213. ssa_emit_comment(p, str_lit("vector.comp.end"));
  1214. return ssa_addr_load(p, addr);
  1215. }
  1216. return ssa_new_value2(p, ssa_determine_op(op, x->type), x->type, x, y);
  1217. }
  1218. ssaValue *ssa_emit_unary_arith(ssaProc *p, TokenKind op, ssaValue *x, Type *type) {
  1219. if (is_type_vector(x->type)) {
  1220. ssa_emit_comment(p, str_lit("vector.arith.begin"));
  1221. // IMPORTANT TODO(bill): This is very wasteful with regards to stack memory
  1222. Type *tl = base_type(x->type);
  1223. ssaValue *val = ssa_address_from_load_or_generate_local(p, x);
  1224. GB_ASSERT(is_type_vector(type));
  1225. Type *elem_type = base_type(type)->Vector.elem;
  1226. ssaAddr res = ssa_add_local_generated(p, type);
  1227. for (i64 i = 0; i < tl->Vector.count; i++) {
  1228. ssaValue *index = ssa_const_int(p, t_int, i);
  1229. ssaValue *e = ssa_emit_load(p, ssa_emit_array_index(p, val, index));
  1230. ssaValue *z = ssa_emit_unary_arith(p, op, e, elem_type);
  1231. ssa_emit_store(p, ssa_emit_array_index(p, res.addr, index), z);
  1232. }
  1233. ssa_emit_comment(p, str_lit("vector.arith.end"));
  1234. return ssa_addr_load(p, res);
  1235. }
  1236. switch (op) {
  1237. case Token_Pointer: {
  1238. GB_PANIC("Token_Pointer should be handled elsewhere");
  1239. } break;
  1240. case Token_Add:
  1241. return x;
  1242. case Token_Not: // Boolean not
  1243. return ssa_new_value1(p, ssaOp_NotB, type, x);
  1244. case Token_Xor: { // Bitwise not
  1245. isize bits = 8*type_size_of(p->allocator, x->type);
  1246. switch (bits) {
  1247. case 8: return ssa_new_value1(p, ssaOp_Not8, type, x);
  1248. case 16: return ssa_new_value1(p, ssaOp_Not16, type, x);
  1249. case 32: return ssa_new_value1(p, ssaOp_Not32, type, x);
  1250. case 64: return ssa_new_value1(p, ssaOp_Not64, type, x);
  1251. }
  1252. GB_PANIC("unknown integer size");
  1253. } break;
  1254. case Token_Sub: { // 0-x
  1255. isize bits = 8*type_size_of(p->allocator, x->type);
  1256. if (is_type_integer(x->type)) {
  1257. switch (bits) {
  1258. case 8: return ssa_new_value1(p, ssaOp_Neg8, type, x);
  1259. case 16: return ssa_new_value1(p, ssaOp_Neg16, type, x);
  1260. case 32: return ssa_new_value1(p, ssaOp_Neg32, type, x);
  1261. case 64: return ssa_new_value1(p, ssaOp_Neg64, type, x);
  1262. }
  1263. } else if (is_type_float(x->type)) {
  1264. switch (bits) {
  1265. case 32: return ssa_new_value1(p, ssaOp_Neg32F, type, x);
  1266. case 64: return ssa_new_value1(p, ssaOp_Neg64F, type, x);
  1267. }
  1268. }
  1269. GB_PANIC("unknown type for -x");
  1270. } break;
  1271. }
  1272. return nullptr;
  1273. }
  1274. ssaValue *ssa_emit_arith(ssaProc *p, TokenKind op, ssaValue *x, ssaValue *y, Type *type) {
  1275. if (is_type_vector(x->type)) {
  1276. GB_PANIC("TODO(bill): ssa_emit_arith vector");
  1277. } else if (is_type_complex(x->type)) {
  1278. GB_PANIC("TODO(bill): ssa_emit_arith complex");
  1279. }
  1280. if (op == Token_Add) {
  1281. if (is_type_pointer(x->type)) {
  1282. GB_PANIC("TODO(bill): Ptr arith");
  1283. ssaValue *ptr = ssa_emit_conv(p, x, type);
  1284. ssaValue *offset = y;
  1285. // return ssa_emit_ptr_offset(p, ptr, offset);
  1286. } else if (is_type_pointer(y->type)) {
  1287. GB_PANIC("TODO(bill): Ptr arith");
  1288. ssaValue *ptr = ssa_emit_conv(p, y, type);
  1289. ssaValue *offset = x;
  1290. // return ssa_emit_ptr_offset(p, ptr, offset);
  1291. }
  1292. } else if (op == Token_Sub) {
  1293. if (is_type_pointer(x->type) && is_type_integer(y->type)) {
  1294. GB_PANIC("TODO(bill): Ptr arith");
  1295. // ptr - int
  1296. ssaValue *ptr = ssa_emit_conv(p, x, type);
  1297. ssaValue *offset = y;
  1298. // return ssa_emit_ptr_offset(p, ptr, offset);
  1299. } else if (is_type_pointer(x->type) && is_type_pointer(y->type)) {
  1300. GB_ASSERT(is_type_integer(type));
  1301. Type *ptr_type = base_type(x->type);
  1302. GB_ASSERT(!is_type_rawptr(ptr_type));
  1303. ssaValue *elem_size = ssa_const_int(p, t_int, type_size_of(p->allocator, ptr_type->Pointer.elem));
  1304. ssaValue *a = ssa_emit_conv(p, x, type);
  1305. ssaValue *b = ssa_emit_conv(p, y, type);
  1306. ssaValue *diff = ssa_emit_arith(p, op, a, b, type);
  1307. return ssa_emit_arith(p, Token_Quo, diff, elem_size, type);
  1308. }
  1309. }
  1310. switch (op) {
  1311. case Token_Add:
  1312. case Token_Sub:
  1313. case Token_Mul:
  1314. case Token_Quo:
  1315. case Token_Mod:
  1316. case Token_And:
  1317. case Token_Or:
  1318. case Token_Xor:
  1319. case Token_AndNot:
  1320. GB_ASSERT(x != nullptr && y != nullptr);
  1321. return ssa_new_value2(p, ssa_determine_op(op, x->type), type, x, y);
  1322. }
  1323. return nullptr;
  1324. }
  1325. ssaValue *ssa_build_cond(ssaProc *p, AstNode *cond, ssaBlock *yes, ssaBlock *no) {
  1326. switch (cond->kind) {
  1327. case_ast_node(pe, ParenExpr, cond);
  1328. return ssa_build_cond(p, pe->expr, yes, no);
  1329. case_end;
  1330. case_ast_node(ue, UnaryExpr, cond);
  1331. if (ue->op.kind == Token_Not) {
  1332. return ssa_build_cond(p, ue->expr, no, yes);
  1333. }
  1334. case_end;
  1335. case_ast_node(be, BinaryExpr, cond);
  1336. if (be->op.kind == Token_CmpAnd) {
  1337. ssaBlock *block = ssa_new_block(p, ssaBlock_Plain, "cmd.and");
  1338. ssa_build_cond(p, be->left, block, no);
  1339. ssa_start_block(p, block);
  1340. return ssa_build_cond(p, be->right, yes, no);
  1341. } else if (be->op.kind == Token_CmpOr) {
  1342. ssaBlock *block = ssa_new_block(p, ssaBlock_Plain, "cmp.or");
  1343. ssa_build_cond(p, be->left, yes, block);
  1344. ssa_start_block(p, block);
  1345. return ssa_build_cond(p, be->right, yes, no);
  1346. }
  1347. case_end;
  1348. }
  1349. ssaValue *c = ssa_build_expr(p, cond);
  1350. ssaBlock *b = ssa_end_block(p);
  1351. b->kind = ssaBlock_If;
  1352. ssa_set_control(b, c);
  1353. ssa_add_edge_to(b, yes);
  1354. ssa_add_edge_to(b, no);
  1355. return c;
  1356. }
  1357. ssaValue *ssa_emit_logical_binary_expr(ssaProc *p, AstNode *expr) {
  1358. ast_node(be, BinaryExpr, expr);
  1359. ssaBlock *rhs = ssa_new_block(p, ssaBlock_Plain, "logical.cmp.rhs");
  1360. ssaBlock *done = ssa_new_block(p, ssaBlock_Plain, "logical.cmp.done");
  1361. GB_ASSERT(p->curr_block != nullptr);
  1362. Type *type = default_type(type_of_expr(p->module->info, expr));
  1363. bool short_circuit_value = false;
  1364. if (be->op.kind == Token_CmpAnd) {
  1365. ssa_build_cond(p, be->left, rhs, done);
  1366. short_circuit_value = false;
  1367. } else if (be->op.kind == Token_CmpOr) {
  1368. ssa_build_cond(p, be->left, done, rhs);
  1369. short_circuit_value = true;
  1370. }
  1371. if (rhs->preds.count == 0) {
  1372. ssa_start_block(p, done);
  1373. return ssa_const_bool(p, type, short_circuit_value);
  1374. }
  1375. if (done->preds.count == 0) {
  1376. ssa_start_block(p, rhs);
  1377. return ssa_build_expr(p, be->right);
  1378. }
  1379. ssa_start_block(p, rhs);
  1380. ssaValue *short_circuit = ssa_const_bool(p, type, short_circuit_value);
  1381. ssaValueArgs edges = {0};
  1382. ssa_init_value_args(&edges, p->allocator);
  1383. for_array(i, done->preds) {
  1384. ssa_add_arg(&edges, short_circuit);
  1385. }
  1386. ssa_add_arg(&edges, ssa_build_expr(p, be->right));
  1387. ssa_emit_jump(p, done);
  1388. ssa_start_block(p, done);
  1389. ssaValue *phi = ssa_new_value0(p, ssaOp_Phi, type);
  1390. phi->args = edges;
  1391. return phi;
  1392. }
  1393. ssaValue *ssa_build_expr(ssaProc *p, AstNode *expr) {
  1394. expr = unparen_expr(expr);
  1395. TypeAndValue tv = type_and_value_of_expr(p->module->info, expr);
  1396. GB_ASSERT(tv.mode != Addressing_Invalid);
  1397. if (tv.value.kind != ExactValue_Invalid) {
  1398. Type *t = core_type(tv.type);
  1399. if (is_type_boolean(t)) {
  1400. return ssa_const_bool(p, tv.type, tv.value.value_bool);
  1401. } else if (is_type_string(t)) {
  1402. GB_ASSERT(tv.value.kind == ExactValue_String);
  1403. return ssa_const_string(p, tv.type, tv.value.value_string);
  1404. } else if(is_type_slice(t)) {
  1405. return ssa_const_slice(p, tv.type, tv.value);
  1406. } else if (is_type_integer(t)) {
  1407. GB_ASSERT(tv.value.kind == ExactValue_Integer);
  1408. i64 s = 8*type_size_of(p->allocator, t);
  1409. switch (s) {
  1410. case 8: return ssa_const_i8 (p, tv.type, cast (i8)i128_to_i64(tv.value.value_integer));
  1411. case 16: return ssa_const_i16(p, tv.type, cast(i16)i128_to_i64(tv.value.value_integer));
  1412. case 32: return ssa_const_i32(p, tv.type, cast(i32)i128_to_i64(tv.value.value_integer));
  1413. case 64: return ssa_const_i64(p, tv.type, cast(i64)i128_to_i64(tv.value.value_integer));
  1414. default: GB_PANIC("Unknown integer size");
  1415. }
  1416. } else if (is_type_float(t)) {
  1417. GB_ASSERT(tv.value.kind == ExactValue_Float);
  1418. i64 s = 8*type_size_of(p->allocator, t);
  1419. switch (s) {
  1420. case 32: return ssa_const_f32(p, tv.type, cast(f32)tv.value.value_float);
  1421. case 64: return ssa_const_f64(p, tv.type, cast(f64)tv.value.value_float);
  1422. default: GB_PANIC("Unknown float size");
  1423. }
  1424. }
  1425. // IMPORTANT TODO(bill): Do constant str/array literals correctly
  1426. return ssa_const_nil(p, tv.type);
  1427. }
  1428. if (tv.mode == Addressing_Variable) {
  1429. return ssa_addr_load(p, ssa_build_addr(p, expr));
  1430. }
  1431. switch (expr->kind) {
  1432. case_ast_node(bl, BasicLit, expr);
  1433. GB_PANIC("Non-constant basic literal");
  1434. case_end;
  1435. case_ast_node(bd, BasicDirective, expr);
  1436. TokenPos pos = bd->token.pos;
  1437. GB_PANIC("Non-constant basic literal %.*s(%td:%td) - %.*s", LIT(pos.file), pos.line, pos.column, LIT(bd->name));
  1438. case_end;
  1439. case_ast_node(i, Ident, expr);
  1440. Entity *e = *map_get(&p->module->info->uses, hash_pointer(expr));
  1441. if (e->kind == Entity_Builtin) {
  1442. Token token = ast_node_token(expr);
  1443. GB_PANIC("TODO(bill): ssa_build_expr Entity_Builtin `%.*s`\n"
  1444. "\t at %.*s(%td:%td)", LIT(builtin_procs[e->Builtin.id].name),
  1445. LIT(token.pos.file), token.pos.line, token.pos.column);
  1446. return nullptr;
  1447. } else if (e->kind == Entity_Nil) {
  1448. GB_PANIC("TODO(bill): nil");
  1449. return nullptr;
  1450. }
  1451. ssaValue **found = map_get(&p->module->values, hash_pointer(e));
  1452. if (found) {
  1453. ssaValue *v = *found;
  1454. if (v->op == ssaOp_Proc) {
  1455. return v;
  1456. }
  1457. ssaAddr addr = ssa_build_addr(p, expr);
  1458. return ssa_addr_load(p, addr);
  1459. }
  1460. case_end;
  1461. case_ast_node(ue, UnaryExpr, expr);
  1462. if (ue->op.kind == Token_Pointer) {
  1463. return ssa_build_addr(p, ue->expr).addr;
  1464. }
  1465. ssaValue *x = ssa_build_expr(p, ue->expr);
  1466. return ssa_emit_unary_arith(p, ue->op.kind, x, tv.type);
  1467. case_end;
  1468. case_ast_node(be, BinaryExpr, expr);
  1469. Type *type = default_type(tv.type);
  1470. switch (be->op.kind) {
  1471. case Token_Add:
  1472. case Token_Sub:
  1473. case Token_Mul:
  1474. case Token_Quo:
  1475. case Token_Mod:
  1476. case Token_And:
  1477. case Token_Or:
  1478. case Token_Xor:
  1479. case Token_AndNot: {
  1480. ssaValue *x = ssa_build_expr(p, be->left);
  1481. ssaValue *y = ssa_build_expr(p, be->right);
  1482. return ssa_emit_arith(p, be->op.kind, x, y, type);
  1483. }
  1484. case Token_Shl:
  1485. case Token_Shr: {
  1486. GB_PANIC("TODO: shifts");
  1487. return nullptr;
  1488. }
  1489. case Token_CmpEq:
  1490. case Token_NotEq:
  1491. case Token_Lt:
  1492. case Token_LtEq:
  1493. case Token_Gt:
  1494. case Token_GtEq: {
  1495. ssaValue *x = ssa_build_expr(p, be->left);
  1496. ssaValue *y = ssa_build_expr(p, be->right);
  1497. return ssa_emit_comp(p, be->op.kind, x, y);
  1498. } break;
  1499. case Token_CmpAnd:
  1500. case Token_CmpOr:
  1501. return ssa_emit_logical_binary_expr(p, expr);
  1502. default:
  1503. GB_PANIC("Invalid binary expression");
  1504. break;
  1505. }
  1506. case_end;
  1507. case_ast_node(de, DerefExpr, expr);
  1508. return ssa_addr_load(p, ssa_build_addr(p, expr));
  1509. case_end;
  1510. case_ast_node(se, SelectorExpr, expr);
  1511. return ssa_addr_load(p, ssa_build_addr(p, expr));
  1512. case_end;
  1513. case_ast_node(te, TernaryExpr, expr);
  1514. ssa_emit_comment(p, str_lit("TernaryExpr"));
  1515. ssaValue *yes = nullptr;
  1516. ssaValue *no = nullptr;
  1517. GB_ASSERT(te->y != nullptr);
  1518. ssaBlock *then = ssa_new_block(p, ssaBlock_Plain, "if.then");
  1519. ssaBlock *done = ssa_new_block(p, ssaBlock_Plain, "if.done"); // NOTE(bill): Append later
  1520. ssaBlock *else_ = ssa_new_block(p, ssaBlock_Plain, "if.else");
  1521. ssaBlock *v = nullptr;
  1522. ssa_build_cond(p, te->cond, then, else_);
  1523. ssa_start_block(p, then);
  1524. // ssa_open_scope(p);
  1525. yes = ssa_build_expr(p, te->x);
  1526. // ssa_close_scope(p, ssaDeferExit_Default, nullptr);
  1527. ssa_emit_jump(p, done);
  1528. ssa_start_block(p, else_);
  1529. // ssa_open_scope(p);
  1530. no = ssa_build_expr(p, te->y);
  1531. // ssa_close_scope(p, ssaDeferExit_Default, nullptr);
  1532. ssa_emit_jump(p, done);
  1533. ssa_start_block(p, done);
  1534. return ssa_new_value2(p, ssaOp_Phi, tv.type, yes, no);
  1535. case_end;
  1536. case_ast_node(pl, ProcLit, expr);
  1537. GB_PANIC("TODO(bill): ssa_build_expr ProcLit");
  1538. #if 0
  1539. // NOTE(bill): Generate a new name
  1540. // parent$count
  1541. isize name_len = proc->name.len + 1 + 8 + 1;
  1542. u8 *name_text = gb_alloc_array(proc->module->allocator, u8, name_len);
  1543. name_len = gb_snprintf(cast(char *)name_text, name_len, "%.*s$%d", LIT(proc->name), cast(i32)proc->children.count);
  1544. String name = make_string(name_text, name_len-1);
  1545. Type *type = type_of_expr(proc->module->info, expr);
  1546. irValue *value = ir_value_procedure(proc->module->allocator,
  1547. proc->module, nullptr, type, pl->type, pl->body, name);
  1548. value->Proc.tags = pl->tags;
  1549. value->Proc.parent = proc;
  1550. array_add(&proc->children, &value->Proc);
  1551. array_add(&proc->module->procs_to_generate, value);
  1552. return value;
  1553. #endif
  1554. case_end;
  1555. case_ast_node(cl, CompoundLit, expr);
  1556. return ssa_addr_load(p, ssa_build_addr(p, expr));
  1557. case_end;
  1558. case_ast_node(ce, CallExpr, expr);
  1559. if (map_get(&p->module->info->types, hash_pointer(ce->proc))->mode == Addressing_Type) {
  1560. GB_ASSERT(ce->args.count == 1);
  1561. ssaValue *x = ssa_build_expr(p, ce->args[0]);
  1562. return ssa_emit_conv(p, x, tv.type);
  1563. }
  1564. AstNode *p = unparen_expr(ce->proc);
  1565. GB_PANIC("TODO(bill): ssa_build_expr CallExpr");
  1566. case_end;
  1567. case_ast_node(se, SliceExpr, expr);
  1568. return ssa_addr_load(p, ssa_build_addr(p, expr));
  1569. case_end;
  1570. case_ast_node(ie, IndexExpr, expr);
  1571. return ssa_addr_load(p, ssa_build_addr(p, expr));
  1572. case_end;
  1573. }
  1574. GB_PANIC("Unexpected expression: %.*s", LIT(ast_node_strings[expr->kind]));
  1575. return nullptr;
  1576. }
  1577. void ssa_build_stmt_list(ssaProc *p, Array<AstNode *> nodes) {
  1578. for_array(i, nodes) {
  1579. ssa_build_stmt(p, nodes[i]);
  1580. }
  1581. }
  1582. void ssa_build_when_stmt(ssaProc *p, AstNodeWhenStmt *ws) {
  1583. ssaValue *cond = ssa_build_expr(p, ws->cond);
  1584. GB_ASSERT(is_type_boolean(cond->type));
  1585. GB_ASSERT(cond->exact_value.kind == ExactValue_Bool);
  1586. if (cond->exact_value.value_bool) {
  1587. ssa_build_stmt_list(p, ws->body->BlockStmt.stmts);
  1588. } else if (ws->else_stmt) {
  1589. switch (ws->else_stmt->kind) {
  1590. case AstNode_BlockStmt:
  1591. ssa_build_stmt_list(p, ws->else_stmt->BlockStmt.stmts);
  1592. break;
  1593. case AstNode_WhenStmt:
  1594. ssa_build_when_stmt(p, &ws->else_stmt->WhenStmt);
  1595. break;
  1596. default:
  1597. GB_PANIC("Invalid `else` statement in `when` statement");
  1598. break;
  1599. }
  1600. }
  1601. }
  1602. void ssa_build_assign_op(ssaProc *p, ssaAddr lhs, ssaValue *value, TokenKind op) {
  1603. ssaValue *old_value = ssa_addr_load(p, lhs);
  1604. Type *type = old_value->type;
  1605. ssaValue *change = value;
  1606. if (is_type_pointer(type) && is_type_integer(value->type)) {
  1607. change = ssa_emit_conv(p, value, default_type(value->type));
  1608. } else {
  1609. change = ssa_emit_conv(p, value, type);
  1610. }
  1611. ssaValue *new_value = ssa_emit_arith(p, op, old_value, change, type);
  1612. ssa_addr_store(p, lhs, new_value);
  1613. }
  1614. void ssa_build_stmt_internal(ssaProc *p, AstNode *node);
  1615. void ssa_build_stmt(ssaProc *p, AstNode *node) {
  1616. u32 prev_stmt_state_flags = p->module->stmt_state_flags;
  1617. if (node->stmt_state_flags != 0) {
  1618. u32 in = node->stmt_state_flags;
  1619. u32 out = p->module->stmt_state_flags;
  1620. if (in & StmtStateFlag_bounds_check) {
  1621. out |= StmtStateFlag_bounds_check;
  1622. out &= ~StmtStateFlag_no_bounds_check;
  1623. } else if (in & StmtStateFlag_no_bounds_check) {
  1624. out |= StmtStateFlag_no_bounds_check;
  1625. out &= ~StmtStateFlag_bounds_check;
  1626. }
  1627. p->module->stmt_state_flags = out;
  1628. }
  1629. ssa_build_stmt_internal(p, node);
  1630. p->module->stmt_state_flags = prev_stmt_state_flags;
  1631. }
  1632. void ssa_build_stmt_internal(ssaProc *p, AstNode *node) {
  1633. if (p->curr_block == nullptr) {
  1634. ssaBlock *dead_block = ssa_new_block(p, ssaBlock_Plain, "");
  1635. ssa_start_block(p, dead_block);
  1636. }
  1637. switch (node->kind) {
  1638. case_ast_node(es, EmptyStmt, node);
  1639. case_end;
  1640. case_ast_node(bs, BlockStmt, node);
  1641. ssa_open_scope(p);
  1642. ssa_build_stmt_list(p, bs->stmts);
  1643. ssa_close_scope(p, ssaDeferExit_Default, nullptr);
  1644. case_end;
  1645. case_ast_node(us, UsingStmt, node);
  1646. case_end;
  1647. case_ast_node(ws, WhenStmt, node);
  1648. ssa_build_when_stmt(p, ws);
  1649. case_end;
  1650. #if 0
  1651. case_ast_node(s, IncDecStmt, node);
  1652. TokenKind op = Token_Add;
  1653. if (s->op.kind == Token_Dec) {
  1654. op = Token_Sub;
  1655. }
  1656. ssaAddr addr = ssa_build_addr(p, s->expr);
  1657. Type *t = ssa_addr_type(addr);
  1658. ssa_build_assign_op(p, addr, ssa_const_int(p, t, 1), op);
  1659. case_end;
  1660. #endif
  1661. case_ast_node(as, AssignStmt, node);
  1662. ssa_emit_comment(p, str_lit("AssignStmt"));
  1663. ssaModule *m = p->module;
  1664. gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&m->tmp_arena);
  1665. switch (as->op.kind) {
  1666. case Token_Eq: {
  1667. Array<ssaAddr> lvals = {0};
  1668. array_init(&lvals, m->tmp_allocator);
  1669. for_array(i, as->lhs) {
  1670. AstNode *lhs = as->lhs[i];
  1671. ssaAddr lval = {0};
  1672. if (!ssa_is_blank_ident(lhs)) {
  1673. lval = ssa_build_addr(p, lhs);
  1674. }
  1675. array_add(&lvals, lval);
  1676. }
  1677. if (as->lhs.count == as->rhs.count) {
  1678. if (as->lhs.count == 1) {
  1679. AstNode *rhs = as->rhs[0];
  1680. ssaValue *init = ssa_build_expr(p, rhs);
  1681. ssa_addr_store(p, lvals[0], init);
  1682. } else {
  1683. Array<ssaValue *> inits;
  1684. array_init(&inits, m->tmp_allocator, lvals.count);
  1685. for_array(i, as->rhs) {
  1686. ssaValue *init = ssa_build_expr(p, as->rhs[i]);
  1687. array_add(&inits, init);
  1688. }
  1689. for_array(i, inits) {
  1690. ssa_addr_store(p, lvals[i], inits[i]);
  1691. }
  1692. }
  1693. } else {
  1694. Array<ssaValue *> inits;
  1695. array_init(&inits, m->tmp_allocator, lvals.count);
  1696. for_array(i, as->rhs) {
  1697. ssaValue *init = ssa_build_expr(p, as->rhs[i]);
  1698. Type *t = base_type(init->type);
  1699. // TODO(bill): refactor for code reuse as this is repeated a bit
  1700. if (t->kind == Type_Tuple) {
  1701. for_array(i, t->Tuple.variables) {
  1702. Entity *e = t->Tuple.variables[i];
  1703. ssaValue *v = ssa_emit_value_index(p, init, i);
  1704. array_add(&inits, v);
  1705. }
  1706. } else {
  1707. array_add(&inits, init);
  1708. }
  1709. }
  1710. for_array(i, inits) {
  1711. ssa_addr_store(p, lvals[i], inits[i]);
  1712. }
  1713. }
  1714. } break;
  1715. default: {
  1716. // GB_PANIC("TODO(bill): assign operations");
  1717. // NOTE(bill): Only 1 += 1 is allowed, no tuples
  1718. // +=, -=, etc
  1719. i32 op = cast(i32)as->op.kind;
  1720. op += Token_Add - Token_AddEq; // Convert += to +
  1721. ssaAddr lhs = ssa_build_addr(p, as->lhs[0]);
  1722. ssaValue *value = ssa_build_expr(p, as->rhs[0]);
  1723. ssa_build_assign_op(p, lhs, value, cast(TokenKind)op);
  1724. } break;
  1725. }
  1726. gb_temp_arena_memory_end(tmp);
  1727. case_end;
  1728. case_ast_node(es, ExprStmt, node);
  1729. // NOTE(bill): No need to use return value
  1730. ssa_build_expr(p, es->expr);
  1731. case_end;
  1732. case_ast_node(ds, DeferStmt, node);
  1733. // GB_PANIC("TODO: DeferStmt");
  1734. ssa_emit_comment(p, str_lit("DeferStmt"));
  1735. i32 scope_level = p->scope_level;
  1736. if (ds->stmt->kind == AstNode_BlockStmt) {
  1737. scope_level--;
  1738. }
  1739. ssa_add_defer_node(p, scope_level, ds->stmt);
  1740. case_end;
  1741. case_ast_node(rs, ReturnStmt, node);
  1742. GB_PANIC("TODO: ReturnStmt");
  1743. case_end;
  1744. case_ast_node(is, IfStmt, node);
  1745. ssa_emit_comment(p, str_lit("IfStmt"));
  1746. if (is->init != nullptr) {
  1747. ssaBlock *init = ssa_new_block(p, ssaBlock_Plain, "if.init");
  1748. ssa_emit_jump(p, init);
  1749. ssa_start_block(p, init);
  1750. ssa_build_stmt(p, is->init);
  1751. }
  1752. ssaBlock *then = ssa_new_block(p, ssaBlock_Plain, "if.then");
  1753. ssaBlock *done = ssa_new_block(p, ssaBlock_Plain, "if.done");
  1754. ssaBlock *else_ = done;
  1755. if (is->else_stmt != nullptr) {
  1756. else_ = ssa_new_block(p, ssaBlock_Plain, "if.else");
  1757. }
  1758. ssaBlock *b = nullptr;
  1759. ssa_build_cond(p, is->cond, then, else_);
  1760. ssa_start_block(p, then);
  1761. ssa_open_scope(p);
  1762. ssa_build_stmt(p, is->body);
  1763. ssa_close_scope(p, ssaDeferExit_Default, nullptr);
  1764. ssa_emit_jump(p, done);
  1765. if (is->else_stmt != nullptr) {
  1766. ssa_start_block(p, else_);
  1767. ssa_open_scope(p);
  1768. ssa_build_stmt(p, is->else_stmt);
  1769. ssa_close_scope(p, ssaDeferExit_Default, nullptr);
  1770. ssa_emit_jump(p, done);
  1771. }
  1772. ssa_start_block(p, done);
  1773. case_end;
  1774. case_ast_node(fs, ForStmt, node);
  1775. ssa_emit_comment(p, str_lit("ForStmt"));
  1776. if (fs->init != nullptr) {
  1777. ssaBlock *init = ssa_new_block(p, ssaBlock_Plain, "for.init");
  1778. ssa_emit_jump(p, init);
  1779. ssa_start_block(p, init);
  1780. ssa_build_stmt(p, fs->init);
  1781. }
  1782. ssaBlock *body = ssa_new_block(p, ssaBlock_Plain, "for.body");
  1783. ssaBlock *done = ssa_new_block(p, ssaBlock_Plain, "for.done");
  1784. ssaBlock *loop = body;
  1785. if (fs->cond != nullptr) {
  1786. loop = ssa_new_block(p, ssaBlock_Plain, "for.loop");
  1787. }
  1788. ssaBlock *post = loop;
  1789. if (fs->post != nullptr) {
  1790. post = ssa_new_block(p, ssaBlock_Plain, "for.post");
  1791. }
  1792. ssa_emit_jump(p, loop);
  1793. ssa_start_block(p, loop);
  1794. if (loop != body) {
  1795. ssa_build_cond(p, fs->cond, body, done);
  1796. ssa_start_block(p, body);
  1797. }
  1798. ssa_push_target_list(p, done, post, nullptr);
  1799. ssa_open_scope(p);
  1800. ssa_build_stmt(p, fs->body);
  1801. ssa_close_scope(p, ssaDeferExit_Default, nullptr);
  1802. ssa_pop_target_list(p);
  1803. ssa_emit_jump(p, post);
  1804. if (fs->post != nullptr) {
  1805. ssa_start_block(p, post);
  1806. ssa_build_stmt(p, fs->post);
  1807. ssa_emit_jump(p, post);
  1808. }
  1809. ssa_start_block(p, done);
  1810. case_end;
  1811. case_ast_node(rs, RangeStmt, node);
  1812. GB_PANIC("TODO: RangeStmt");
  1813. case_end;
  1814. case_ast_node(rs, SwitchStmt, node);
  1815. GB_PANIC("TODO: SwitchStmt");
  1816. case_end;
  1817. case_ast_node(rs, TypeSwitchStmt, node);
  1818. GB_PANIC("TODO: TypeSwitchStmt");
  1819. case_end;
  1820. case_ast_node(bs, BranchStmt, node);
  1821. ssaBlock *b = nullptr;
  1822. switch (bs->token.kind) {
  1823. case Token_break:
  1824. for (ssaTargetList *t = p->target_list; t != nullptr && b == nullptr; t = t->prev) {
  1825. b = t->break_;
  1826. }
  1827. break;
  1828. case Token_continue:
  1829. for (ssaTargetList *t = p->target_list; t != nullptr && b == nullptr; t = t->prev) {
  1830. b = t->continue_;
  1831. }
  1832. break;
  1833. case Token_fallthrough:
  1834. for (ssaTargetList *t = p->target_list; t != nullptr && b == nullptr; t = t->prev) {
  1835. b = t->fallthrough_;
  1836. }
  1837. break;
  1838. }
  1839. if (b != nullptr) {
  1840. ssa_emit_defer_stmts(p, ssaDeferExit_Branch, b);
  1841. }
  1842. switch (bs->token.kind) {
  1843. case Token_break: ssa_emit_comment(p, str_lit("break")); break;
  1844. case Token_continue: ssa_emit_comment(p, str_lit("continue")); break;
  1845. case Token_fallthrough: ssa_emit_comment(p, str_lit("fallthrough")); break;
  1846. }
  1847. ssa_emit_jump(p, b);
  1848. case_end;
  1849. case_ast_node(pa, PushAllocator, node);
  1850. GB_PANIC("TODO: PushAllocator");
  1851. case_end;
  1852. case_ast_node(pc, PushContext, node);
  1853. GB_PANIC("TODO: PushContext");
  1854. case_end;
  1855. }
  1856. }
  1857. void ssa_print_value(gbFile *f, ssaValue *v) {
  1858. if (v == nullptr) {
  1859. gb_fprintf(f, "nil");
  1860. }
  1861. gb_fprintf(f, "v%d", v->id);
  1862. }
  1863. void ssa_print_exact_value(gbFile *f, ssaValue *v) {
  1864. Type *t = default_type(v->type);
  1865. ExactValue ev = v->exact_value;
  1866. switch (ev.kind) {
  1867. case ExactValue_Bool:
  1868. if (ev.value_bool == false) {
  1869. gb_fprintf(f, " [false]");
  1870. } else {
  1871. gb_fprintf(f, " [true]");
  1872. }
  1873. break;
  1874. case ExactValue_Integer:
  1875. if (is_type_unsigned(t)) {
  1876. gb_fprintf(f, " [%llu]", cast(unsigned long long)i128_to_u64(ev.value_integer));
  1877. } else {
  1878. gb_fprintf(f, " [%lld]", cast(long long)i128_to_i64(ev.value_integer));
  1879. }
  1880. break;
  1881. case ExactValue_Float:
  1882. if (is_type_f32(t)) {
  1883. f32 fp = cast(f32)ev.value_float;
  1884. u32 x = *cast(u32 *)&fp;
  1885. gb_fprintf(f, " [0x%x]", x);
  1886. } else if (is_type_f64(t)) {
  1887. f64 fp = cast(f64)ev.value_float;
  1888. u64 x = *cast(u64 *)&fp;
  1889. gb_fprintf(f, " [0x%llx]", cast(unsigned long long)x);
  1890. } else {
  1891. GB_PANIC("unhandled float");
  1892. }
  1893. break;
  1894. case ExactValue_String:
  1895. gb_fprintf(f, " [%.*s]", LIT(ev.value_string));
  1896. break;
  1897. case ExactValue_Pointer:
  1898. gb_fprintf(f, " [0x%llx]", cast(unsigned long long)cast(uintptr)ev.value_pointer);
  1899. break;
  1900. }
  1901. }
  1902. void ssa_print_reg_value(gbFile *f, ssaValue *v) {
  1903. gb_fprintf(f, " ");
  1904. gb_fprintf(f, "v%d = %.*s", v->id, LIT(ssa_op_strings[v->op]));
  1905. if (v->type != nullptr) {
  1906. gbString type_str = type_to_string(default_type(v->type));
  1907. gb_fprintf(f, " %s", type_str);
  1908. gb_string_free(type_str);
  1909. }
  1910. ssa_print_exact_value(f, v);
  1911. for_array(i, v->args) {
  1912. gb_fprintf(f, " ");
  1913. ssa_print_value(f, v->args[i]);
  1914. }
  1915. if (v->comment_string.len > 0) {
  1916. gb_fprintf(f, " ; %.*s", LIT(v->comment_string));
  1917. }
  1918. gb_fprintf(f, "\n");
  1919. }
  1920. void ssa_print_proc(gbFile *f, ssaProc *p) {
  1921. gbString type_str = type_to_string(p->entity->type);
  1922. gb_fprintf(f, "%.*s %s\n", LIT(p->name), type_str);
  1923. gb_string_free(type_str);
  1924. bool *printed = gb_alloc_array(heap_allocator(), bool, p->value_id+1);
  1925. for_array(i, p->blocks) {
  1926. ssaBlock *b = p->blocks[i];
  1927. gb_fprintf(f, " b%d:", b->id);
  1928. if (b->preds.count > 0) {
  1929. gb_fprintf(f, " <-");
  1930. for_array(j, b->preds) {
  1931. ssaBlock *pred = b->preds[j].block;
  1932. gb_fprintf(f, " b%d", pred->id);
  1933. }
  1934. }
  1935. if (b->name.len > 0) {
  1936. gb_fprintf(f, " ; %.*s", LIT(b->name));
  1937. }
  1938. gb_fprintf(f, "\n");
  1939. isize n = 0;
  1940. for_array(j, b->values) {
  1941. ssaValue *v = b->values[j];
  1942. if (v->op != ssaOp_Phi) {
  1943. continue;
  1944. }
  1945. ssa_print_reg_value(f, v);
  1946. printed[v->id] = true;
  1947. n++;
  1948. }
  1949. while (n < b->values.count) {
  1950. isize m = 0;
  1951. for_array(j, b->values) {
  1952. ssaValue *v = b->values[j];
  1953. if (printed[v->id]) {
  1954. continue;
  1955. }
  1956. bool skip = false;
  1957. for_array(k, v->args) {
  1958. ssaValue *w = v->args[k];
  1959. if (w != nullptr && w->block == b && !printed[w->id]) {
  1960. skip = true;
  1961. break;
  1962. }
  1963. }
  1964. if (skip) {
  1965. break;
  1966. }
  1967. ssa_print_reg_value(f, v);
  1968. printed[v->id] = true;
  1969. n++;
  1970. }
  1971. if (m == n) {
  1972. gb_fprintf(f, "!!!!DepCycle!!!!\n");
  1973. for_array(k, b->values) {
  1974. ssaValue *v = b->values[k];
  1975. if (printed[v->id]) {
  1976. continue;
  1977. }
  1978. ssa_print_reg_value(f, v);
  1979. printed[v->id] = true;
  1980. n++;
  1981. }
  1982. }
  1983. }
  1984. if (b->kind == ssaBlock_Plain) {
  1985. GB_ASSERT(b->succs.count == 1);
  1986. ssaBlock *next = b->succs[0].block;
  1987. gb_fprintf(f, " ");
  1988. gb_fprintf(f, "jump b%d", next->id);
  1989. gb_fprintf(f, "\n");
  1990. } else if (b->kind == ssaBlock_If) {
  1991. GB_ASSERT(b->succs.count == 2);
  1992. ssaBlock *yes = b->succs[0].block;
  1993. ssaBlock *no = b->succs[1].block;
  1994. gb_fprintf(f, " ");
  1995. gb_fprintf(f, "branch v%d, b%d, b%d", b->control->id, yes->id, no->id);
  1996. gb_fprintf(f, "\n");
  1997. } else if (b->kind == ssaBlock_Exit) {
  1998. gb_fprintf(f, " ");
  1999. gb_fprintf(f, "exit");
  2000. gb_fprintf(f, "\n");
  2001. } else if (b->kind == ssaBlock_Ret) {
  2002. gb_fprintf(f, " ");
  2003. gb_fprintf(f, "ret");
  2004. gb_fprintf(f, "\n");
  2005. }
  2006. }
  2007. gb_free(heap_allocator(), printed);
  2008. }
  2009. void ssa_opt_proc(ssaProc *p) {
  2010. }
  2011. void ssa_build_proc(ssaModule *m, ssaProc *p) {
  2012. p->module = m;
  2013. m->proc = p;
  2014. if (p->decl_info->proc_lit == nullptr ||
  2015. p->decl_info->proc_lit->kind != AstNode_ProcLit) {
  2016. return;
  2017. }
  2018. ast_node(pl, ProcLit, p->decl_info->proc_lit);
  2019. if (pl->body == nullptr) {
  2020. return;
  2021. }
  2022. p->entry = ssa_new_block(p, ssaBlock_Entry, "entry");
  2023. ssa_start_block(p, p->entry);
  2024. ssa_build_stmt(p, pl->body);
  2025. if (p->entity->type->Proc.result_count == 0) {
  2026. ssa_emit_defer_stmts(p, ssaDeferExit_Return, nullptr);
  2027. }
  2028. p->exit = ssa_new_block(p, ssaBlock_Exit, "exit");
  2029. ssa_emit_jump(p, p->exit);
  2030. ssa_opt_proc(p);
  2031. ssa_print_proc(gb_file_get_standard(gbFileStandard_Error), p);
  2032. }
  2033. bool ssa_generate(Parser *parser, CheckerInfo *info) {
  2034. if (global_error_collector.count != 0) {
  2035. return false;
  2036. }
  2037. ssaModule m = {0};
  2038. { // Init ssaModule
  2039. m.info = info;
  2040. isize token_count = parser->total_token_count;
  2041. isize arena_size = 4 * token_count * gb_max3(gb_size_of(ssaValue), gb_size_of(ssaBlock), gb_size_of(ssaProc));
  2042. gb_arena_init_from_allocator(&m.arena, heap_allocator(), arena_size);
  2043. gb_arena_init_from_allocator(&m.tmp_arena, heap_allocator(), arena_size);
  2044. m.tmp_allocator = gb_arena_allocator(&m.tmp_arena);
  2045. m.allocator = gb_arena_allocator(&m.arena);
  2046. map_init(&m.values, heap_allocator());
  2047. array_init(&m.registers, heap_allocator());
  2048. array_init(&m.procs, heap_allocator());
  2049. array_init(&m.procs_to_generate, heap_allocator());
  2050. }
  2051. isize global_variable_max_count = 0;
  2052. Entity *entry_point = nullptr;
  2053. bool has_dll_main = false;
  2054. bool has_win_main = false;
  2055. for_array(i, info->entities.entries) {
  2056. auto *entry = &info->entities.entries[i];
  2057. Entity *e = cast(Entity *)entry->key.ptr;
  2058. String name = e->token.string;
  2059. if (e->kind == Entity_Variable) {
  2060. global_variable_max_count++;
  2061. } else if (e->kind == Entity_Procedure && !e->scope->is_global) {
  2062. if (e->scope->is_init && name == "main") {
  2063. entry_point = e;
  2064. }
  2065. if (e->Procedure.is_export ||
  2066. (e->Procedure.link_name.len > 0) ||
  2067. (e->scope->is_file && e->Procedure.link_name.len > 0)) {
  2068. if (!has_dll_main && name == "DllMain") {
  2069. has_dll_main = true;
  2070. } else if (!has_win_main && name == "WinMain") {
  2071. has_win_main = true;
  2072. }
  2073. }
  2074. }
  2075. }
  2076. m.entry_point_entity = entry_point;
  2077. m.min_dep_map = generate_minimum_dependency_set(info, entry_point);
  2078. for_array(i, info->entities.entries) {
  2079. auto *entry = &info->entities.entries[i];
  2080. Entity *e = cast(Entity *)entry->key.ptr;
  2081. String name = e->token.string;
  2082. DeclInfo *decl = entry->value;
  2083. Scope *scope = e->scope;
  2084. if (!scope->is_file) {
  2085. continue;
  2086. }
  2087. if (!ptr_set_exists(&m.min_dep_map, e)) {
  2088. // NOTE(bill): Nothing depends upon it so doesn't need to be built
  2089. continue;
  2090. }
  2091. if (!scope->is_global) {
  2092. if (e->kind == Entity_Procedure && e->Procedure.is_export) {
  2093. } else if (e->kind == Entity_Variable && e->Variable.is_export) {
  2094. } else if (e->kind == Entity_Procedure && e->Procedure.link_name.len > 0) {
  2095. // Handle later
  2096. } else if (scope->is_init && e->kind == Entity_Procedure && name == "main") {
  2097. } else {
  2098. name = ssa_mangle_name(&m, e->token.pos.file, e);
  2099. }
  2100. }
  2101. switch (e->kind) {
  2102. case Entity_TypeName:
  2103. break;
  2104. case Entity_Variable: {
  2105. } break;
  2106. case Entity_Procedure: {
  2107. ast_node(pl, ProcLit, decl->proc_lit);
  2108. String original_name = name;
  2109. AstNode *body = pl->body;
  2110. if (e->Procedure.is_foreign) {
  2111. name = e->token.string; // NOTE(bill): Don't use the mangled name
  2112. }
  2113. if (e->Procedure.link_name.len > 0) {
  2114. name = e->Procedure.link_name;
  2115. }
  2116. if (e == entry_point) {
  2117. ssaProc *p = ssa_new_proc(&m, name, e, decl);
  2118. ssa_build_proc(&m, p);
  2119. }
  2120. // ssaValue *p = ssa_make_value_procedure(a, m, e, e->type, decl->type_expr, body, name);
  2121. // p->Proc.tags = pl->tags;
  2122. // ssa_module_add_value(m, e, p);
  2123. // HashKey hash_name = hash_string(name);
  2124. // if (map_get(&m.members, hash_name) == nullptr) {
  2125. // map_set(&m.members, hash_name, p);
  2126. // }
  2127. } break;
  2128. }
  2129. }
  2130. return true;
  2131. }
  2132. String ssa_mangle_name(ssaModule *m, String path, Entity *e) {
  2133. // NOTE(bill): prefix names not in the init scope
  2134. // TODO(bill): make robust and not just rely on the file's name
  2135. String name = e->token.string;
  2136. CheckerInfo *info = m->info;
  2137. gbAllocator a = m->allocator;
  2138. AstFile *file = *map_get(&info->files, hash_string(path));
  2139. char *str = gb_alloc_array(a, char, path.len+1);
  2140. gb_memmove(str, path.text, path.len);
  2141. str[path.len] = 0;
  2142. for (isize i = 0; i < path.len; i++) {
  2143. if (str[i] == '\\') {
  2144. str[i] = '/';
  2145. }
  2146. }
  2147. char const *base = gb_path_base_name(str);
  2148. char const *ext = gb_path_extension(base);
  2149. isize base_len = ext-1-base;
  2150. isize max_len = base_len + 1 + 10 + 1 + name.len;
  2151. bool is_overloaded = check_is_entity_overloaded(e);
  2152. if (is_overloaded) {
  2153. max_len += 21;
  2154. }
  2155. u8 *new_name = gb_alloc_array(a, u8, max_len);
  2156. isize new_name_len = gb_snprintf(
  2157. cast(char *)new_name, max_len,
  2158. "%.*s-%u.%.*s",
  2159. cast(int)base_len, base,
  2160. cast(u32)file->id,
  2161. LIT(name));
  2162. if (is_overloaded) {
  2163. char *str = cast(char *)new_name + new_name_len-1;
  2164. isize len = max_len-new_name_len;
  2165. isize extra = gb_snprintf(str, len, "-%tu", cast(usize)cast(uintptr)e);
  2166. new_name_len += extra-1;
  2167. }
  2168. return make_string(new_name, new_name_len-1);
  2169. }