ssa.cpp 77 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613
  1. struct ssaModule;
  2. struct ssaProcedure;
  3. struct ssaBlock;
  4. struct ssaValue;
  5. struct ssaModule {
  6. CheckerInfo * info;
  7. BaseTypeSizes sizes;
  8. gbArena arena;
  9. gbAllocator allocator;
  10. String layout;
  11. Map<ssaValue *> values; // Key: Entity *
  12. Map<ssaValue *> members; // Key: String
  13. gbArray(ssaValue *) nested_type_names; // ssaValue_TypeName
  14. i32 global_string_index;
  15. };
  16. struct ssaBlock {
  17. i32 id;
  18. AstNode *node;
  19. Scope *scope;
  20. isize scope_index;
  21. String label;
  22. ssaProcedure *parent;
  23. gbArray(ssaValue *) instrs;
  24. gbArray(ssaValue *) values;
  25. };
  26. struct ssaTargetList {
  27. ssaTargetList *prev;
  28. ssaBlock * break_;
  29. ssaBlock * continue_;
  30. ssaBlock * fallthrough_;
  31. };
  32. enum ssaDeferKind {
  33. ssaDefer_Default,
  34. ssaDefer_Return,
  35. ssaDefer_Branch,
  36. };
  37. struct ssaDefer {
  38. AstNode *stmt;
  39. isize scope_index;
  40. ssaBlock *block;
  41. };
  42. struct ssaProcedure {
  43. ssaProcedure *parent;
  44. gbArray(ssaProcedure *) children;
  45. ssaModule * module;
  46. String name;
  47. Type * type;
  48. AstNode * type_expr;
  49. AstNode * body;
  50. u64 tags;
  51. isize scope_index;
  52. gbArray(ssaDefer) defer_stmts;
  53. gbArray(ssaBlock *) blocks;
  54. ssaBlock * curr_block;
  55. ssaTargetList * target_list;
  56. };
  57. #define SSA_STARTUP_RUNTIME_PROC_NAME "__$startup_runtime"
  58. #define SSA_INSTR_KINDS \
  59. SSA_INSTR_KIND(Invalid), \
  60. SSA_INSTR_KIND(Local), \
  61. SSA_INSTR_KIND(Store), \
  62. SSA_INSTR_KIND(Load), \
  63. SSA_INSTR_KIND(GetElementPtr), \
  64. SSA_INSTR_KIND(ExtractValue), \
  65. SSA_INSTR_KIND(Conv), \
  66. SSA_INSTR_KIND(Br), \
  67. SSA_INSTR_KIND(Ret), \
  68. SSA_INSTR_KIND(Select), \
  69. SSA_INSTR_KIND(Unreachable), \
  70. SSA_INSTR_KIND(BinaryOp), \
  71. SSA_INSTR_KIND(Call), \
  72. SSA_INSTR_KIND(MemCopy), \
  73. SSA_INSTR_KIND(NoOp), \
  74. SSA_INSTR_KIND(ExtractElement), \
  75. SSA_INSTR_KIND(InsertElement), \
  76. SSA_INSTR_KIND(ShuffleVector), \
  77. SSA_INSTR_KIND(StartupRuntime), \
  78. SSA_INSTR_KIND(Count),
  79. enum ssaInstrKind {
  80. #define SSA_INSTR_KIND(x) GB_JOIN2(ssaInstr_, x)
  81. SSA_INSTR_KINDS
  82. #undef SSA_INSTR_KIND
  83. };
  84. String const ssa_instr_strings[] = {
  85. #define SSA_INSTR_KIND(x) {cast(u8 *)#x, gb_size_of(#x)-1}
  86. SSA_INSTR_KINDS
  87. #undef SSA_INSTR_KIND
  88. };
  89. #define SSA_CONV_KINDS \
  90. SSA_CONV_KIND(Invalid), \
  91. SSA_CONV_KIND(trunc), \
  92. SSA_CONV_KIND(zext), \
  93. SSA_CONV_KIND(fptrunc), \
  94. SSA_CONV_KIND(fpext), \
  95. SSA_CONV_KIND(fptoui), \
  96. SSA_CONV_KIND(fptosi), \
  97. SSA_CONV_KIND(uitofp), \
  98. SSA_CONV_KIND(sitofp), \
  99. SSA_CONV_KIND(ptrtoint), \
  100. SSA_CONV_KIND(inttoptr), \
  101. SSA_CONV_KIND(bitcast), \
  102. SSA_CONV_KIND(Count)
  103. enum ssaConvKind {
  104. #define SSA_CONV_KIND(x) GB_JOIN2(ssaConv_, x)
  105. SSA_CONV_KINDS
  106. #undef SSA_CONV_KIND
  107. };
  108. String const ssa_conv_strings[] = {
  109. #define SSA_CONV_KIND(x) {cast(u8 *)#x, gb_size_of(#x)-1}
  110. SSA_CONV_KINDS
  111. #undef SSA_CONV_KIND
  112. };
  113. struct ssaInstr {
  114. ssaInstrKind kind;
  115. ssaBlock *parent;
  116. Type *type;
  117. union {
  118. struct {
  119. Entity *entity;
  120. Type *type;
  121. } Local;
  122. struct {
  123. ssaValue *address;
  124. ssaValue *value;
  125. } Store;
  126. struct {
  127. Type *type;
  128. ssaValue *address;
  129. } Load;
  130. struct {
  131. ssaValue *address;
  132. Type * result_type;
  133. Type * elem_type;
  134. ssaValue *indices[2];
  135. isize index_count;
  136. b32 inbounds;
  137. } GetElementPtr;
  138. struct {
  139. ssaValue *address;
  140. Type * result_type;
  141. Type * elem_type;
  142. i32 index;
  143. } ExtractValue;
  144. struct {
  145. ssaConvKind kind;
  146. ssaValue *value;
  147. Type *from, *to;
  148. } Conv;
  149. struct {
  150. ssaValue *cond;
  151. ssaBlock *true_block;
  152. ssaBlock *false_block;
  153. } Br;
  154. struct { ssaValue *value; } Ret;
  155. struct {} Unreachable;
  156. struct {
  157. ssaValue *cond;
  158. ssaValue *true_value;
  159. ssaValue *false_value;
  160. } Select;
  161. struct {
  162. Type *type;
  163. Token op;
  164. ssaValue *left, *right;
  165. } BinaryOp;
  166. struct {
  167. Type *type; // return type
  168. ssaValue *value;
  169. ssaValue **args;
  170. isize arg_count;
  171. } Call;
  172. struct {
  173. ssaValue *dst, *src;
  174. ssaValue *len;
  175. i32 align;
  176. b32 is_volatile;
  177. } CopyMemory;
  178. struct {
  179. ssaValue *vector;
  180. ssaValue *index;
  181. } ExtractElement;
  182. struct {
  183. ssaValue *vector;
  184. ssaValue *elem;
  185. ssaValue *index;
  186. } InsertElement;
  187. struct {
  188. ssaValue *vector;
  189. i32 *indices;
  190. isize index_count;
  191. Type *type;
  192. } ShuffleVector;
  193. struct {} StartupRuntime;
  194. };
  195. };
  196. enum ssaValueKind {
  197. ssaValue_Invalid,
  198. ssaValue_Constant,
  199. ssaValue_TypeName,
  200. ssaValue_Global,
  201. ssaValue_Param,
  202. ssaValue_GlobalString,
  203. ssaValue_Proc,
  204. ssaValue_Block,
  205. ssaValue_Instr,
  206. ssaValue_Count,
  207. };
  208. struct ssaValue {
  209. ssaValueKind kind;
  210. i32 id;
  211. union {
  212. struct {
  213. Type * type;
  214. ExactValue value;
  215. } Constant;
  216. struct {
  217. String name;
  218. Type * type;
  219. } TypeName;
  220. struct {
  221. b32 is_constant;
  222. b32 is_thread_local;
  223. Entity * entity;
  224. Type * type;
  225. ssaValue *value;
  226. } Global;
  227. struct {
  228. ssaProcedure *parent;
  229. Entity *entity;
  230. Type * type;
  231. } Param;
  232. ssaProcedure Proc;
  233. ssaBlock Block;
  234. ssaInstr Instr;
  235. };
  236. };
  237. gb_global ssaValue *v_zero = NULL;
  238. gb_global ssaValue *v_one = NULL;
  239. gb_global ssaValue *v_zero32 = NULL;
  240. gb_global ssaValue *v_one32 = NULL;
  241. gb_global ssaValue *v_two32 = NULL;
  242. gb_global ssaValue *v_false = NULL;
  243. gb_global ssaValue *v_true = NULL;
  244. struct ssaAddr {
  245. ssaValue *addr;
  246. AstNode *expr; // NOTE(bill): Just for testing - probably remove later
  247. // HACK(bill): Fix how lvalues for vectors work
  248. b32 is_vector;
  249. ssaValue *index;
  250. };
  251. ssaAddr ssa_make_addr(ssaValue *addr, AstNode *expr) {
  252. ssaAddr v = {addr, expr, false, NULL};
  253. return v;
  254. }
  255. ssaAddr ssa_make_addr_vector(ssaValue *addr, ssaValue *index, AstNode *expr) {
  256. ssaAddr v = {addr, expr, true, index};
  257. return v;
  258. }
  259. void ssa_module_init(ssaModule *m, Checker *c) {
  260. // TODO(bill): Determine a decent size for the arena
  261. isize token_count = c->parser->total_token_count;
  262. isize arena_size = 4 * token_count * gb_size_of(ssaValue);
  263. gb_arena_init_from_allocator(&m->arena, gb_heap_allocator(), arena_size);
  264. m->allocator = gb_arena_allocator(&m->arena);
  265. m->info = &c->info;
  266. m->sizes = c->sizes;
  267. map_init(&m->values, m->allocator);
  268. map_init(&m->members, m->allocator);
  269. gb_array_init(m->nested_type_names, m->allocator);
  270. }
  271. void ssa_module_destroy(ssaModule *m) {
  272. map_destroy(&m->values);
  273. map_destroy(&m->members);
  274. gb_array_free(m->nested_type_names);
  275. gb_arena_free(&m->arena);
  276. }
  277. void ssa_module_add_value(ssaModule *m, Entity *e, ssaValue *v) {
  278. map_set(&m->values, hash_pointer(e), v);
  279. }
  280. Type *ssa_type(ssaValue *value);
  281. void ssa_set_type(ssaValue *value, Type *type);
  282. Type *ssa_type(ssaInstr *instr) {
  283. switch (instr->kind) {
  284. case ssaInstr_Local:
  285. return instr->Local.type;
  286. case ssaInstr_Store:
  287. return ssa_type(instr->Store.address);
  288. case ssaInstr_Load:
  289. return instr->Load.type;
  290. case ssaInstr_GetElementPtr:
  291. return instr->GetElementPtr.result_type;
  292. case ssaInstr_ExtractValue:
  293. return instr->ExtractValue.result_type;
  294. case ssaInstr_BinaryOp:
  295. return instr->BinaryOp.type;
  296. case ssaInstr_Conv:
  297. return instr->Conv.to;
  298. case ssaInstr_Select:
  299. return ssa_type(instr->Select.true_value);
  300. case ssaInstr_Call: {
  301. Type *pt = get_base_type(instr->Call.type);
  302. if (pt != NULL) {
  303. if (pt->kind == Type_Tuple && pt->Tuple.variable_count == 1)
  304. return pt->Tuple.variables[0]->type;
  305. return pt;
  306. }
  307. return NULL;
  308. } break;
  309. case ssaInstr_MemCopy:
  310. return t_int;
  311. case ssaInstr_ExtractElement: {
  312. Type *vt = ssa_type(instr->ExtractElement.vector);
  313. Type *bt = base_vector_type(get_base_type(vt));
  314. GB_ASSERT(!is_type_vector(bt));
  315. return bt;
  316. } break;
  317. case ssaInstr_InsertElement:
  318. return ssa_type(instr->InsertElement.vector);
  319. case ssaInstr_ShuffleVector:
  320. return instr->ShuffleVector.type;
  321. }
  322. return NULL;
  323. }
  324. void ssa_set_type(ssaInstr *instr, Type *type) {
  325. switch (instr->kind) {
  326. case ssaInstr_Local:
  327. instr->Local.type = type;
  328. break;
  329. case ssaInstr_Store:
  330. ssa_set_type(instr->Store.value, type);
  331. break;
  332. case ssaInstr_Load:
  333. instr->Load.type = type;
  334. break;
  335. case ssaInstr_GetElementPtr:
  336. instr->GetElementPtr.result_type = type;
  337. break;
  338. case ssaInstr_ExtractValue:
  339. instr->ExtractValue.result_type = type;
  340. break;
  341. case ssaInstr_BinaryOp:
  342. instr->BinaryOp.type = type;
  343. break;
  344. case ssaInstr_Conv:
  345. instr->Conv.to = type;
  346. break;
  347. case ssaInstr_Call:
  348. instr->Call.type = type;
  349. break;
  350. }
  351. }
  352. Type *ssa_type(ssaValue *value) {
  353. switch (value->kind) {
  354. case ssaValue_Constant:
  355. return value->Constant.type;
  356. case ssaValue_TypeName:
  357. return value->TypeName.type;
  358. case ssaValue_Global:
  359. return value->Global.type;
  360. case ssaValue_Param:
  361. return value->Param.type;
  362. case ssaValue_Proc:
  363. return value->Proc.type;
  364. case ssaValue_Instr:
  365. return ssa_type(&value->Instr);
  366. }
  367. return NULL;
  368. }
  369. void ssa_set_type(ssaValue *value, Type *type) {
  370. switch (value->kind) {
  371. case ssaValue_TypeName:
  372. value->TypeName.type = type;
  373. break;
  374. case ssaValue_Global:
  375. value->Global.type = type;
  376. break;
  377. case ssaValue_Proc:
  378. value->Proc.type = type;
  379. break;
  380. case ssaValue_Constant:
  381. value->Constant.type = type;
  382. break;
  383. case ssaValue_Instr:
  384. ssa_set_type(&value->Instr, type);
  385. break;
  386. }
  387. }
  388. ssaValue *ssa_build_expr(ssaProcedure *proc, AstNode *expr);
  389. ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue *tv);
  390. ssaAddr ssa_build_addr(ssaProcedure *proc, AstNode *expr);
  391. ssaValue *ssa_emit_conv(ssaProcedure *proc, ssaValue *value, Type *a_type);
  392. ssaValue *ssa_emit_transmute(ssaProcedure *proc, ssaValue *value, Type *a_type);
  393. void ssa_build_proc(ssaValue *value, ssaProcedure *parent);
  394. ssaValue *ssa_alloc_value(gbAllocator a, ssaValueKind kind) {
  395. ssaValue *v = gb_alloc_item(a, ssaValue);
  396. v->kind = kind;
  397. return v;
  398. }
  399. ssaValue *ssa_alloc_instr(ssaProcedure *proc, ssaInstrKind kind) {
  400. ssaValue *v = ssa_alloc_value(proc->module->allocator, ssaValue_Instr);
  401. v->Instr.kind = kind;
  402. if (proc->curr_block) {
  403. gb_array_append(proc->curr_block->values, v);
  404. }
  405. return v;
  406. }
  407. ssaValue *ssa_make_value_type_name(gbAllocator a, String name, Type *type) {
  408. ssaValue *v = ssa_alloc_value(a, ssaValue_TypeName);
  409. v->TypeName.name = name;
  410. v->TypeName.type = type;
  411. return v;
  412. }
  413. ssaValue *ssa_make_value_global(gbAllocator a, Entity *e, ssaValue *value) {
  414. ssaValue *v = ssa_alloc_value(a, ssaValue_Global);
  415. v->Global.entity = e;
  416. v->Global.type = e->type;
  417. v->Global.value = value;
  418. return v;
  419. }
  420. ssaValue *ssa_make_value_param(gbAllocator a, ssaProcedure *parent, Entity *e) {
  421. ssaValue *v = ssa_alloc_value(a, ssaValue_Param);
  422. v->Param.parent = parent;
  423. v->Param.entity = e;
  424. v->Param.type = e->type;
  425. return v;
  426. }
  427. ssaValue *ssa_make_instr_local(ssaProcedure *p, Entity *e) {
  428. ssaValue *v = ssa_alloc_instr(p, ssaInstr_Local);
  429. ssaInstr *i = &v->Instr;
  430. i->Local.entity = e;
  431. i->Local.type = e->type;
  432. ssa_module_add_value(p->module, e, v);
  433. return v;
  434. }
  435. ssaValue *ssa_make_instr_store(ssaProcedure *p, ssaValue *address, ssaValue *value) {
  436. ssaValue *v = ssa_alloc_instr(p, ssaInstr_Store);
  437. ssaInstr *i = &v->Instr;
  438. i->Store.address = address;
  439. i->Store.value = value;
  440. return v;
  441. }
  442. ssaValue *ssa_make_instr_load(ssaProcedure *p, ssaValue *address) {
  443. ssaValue *v = ssa_alloc_instr(p, ssaInstr_Load);
  444. ssaInstr *i = &v->Instr;
  445. i->Load.address = address;
  446. i->Load.type = ssa_type(address);
  447. return v;
  448. }
  449. ssaValue *ssa_make_instr_get_element_ptr(ssaProcedure *p, ssaValue *address,
  450. ssaValue *index0, ssaValue *index1, isize index_count,
  451. b32 inbounds) {
  452. ssaValue *v = ssa_alloc_instr(p, ssaInstr_GetElementPtr);
  453. ssaInstr *i = &v->Instr;
  454. i->GetElementPtr.address = address;
  455. i->GetElementPtr.indices[0] = index0;
  456. i->GetElementPtr.indices[1] = index1;
  457. i->GetElementPtr.index_count = index_count;
  458. i->GetElementPtr.elem_type = ssa_type(address);
  459. i->GetElementPtr.inbounds = inbounds;
  460. return v;
  461. }
  462. ssaValue *ssa_make_instr_extract_value(ssaProcedure *p, ssaValue *address, i32 index, Type *result_type) {
  463. ssaValue *v = ssa_alloc_instr(p, ssaInstr_ExtractValue);
  464. ssaInstr *i = &v->Instr;
  465. i->ExtractValue.address = address;
  466. i->ExtractValue.index = index;
  467. i->ExtractValue.result_type = result_type;
  468. Type *et = ssa_type(address);
  469. i->ExtractValue.elem_type = et;
  470. GB_ASSERT(et->kind == Type_Struct || et->kind == Type_Array || et->kind == Type_Tuple);
  471. return v;
  472. }
  473. ssaValue *ssa_make_instr_binary_op(ssaProcedure *p, Token op, ssaValue *left, ssaValue *right) {
  474. ssaValue *v = ssa_alloc_instr(p, ssaInstr_BinaryOp);
  475. ssaInstr *i = &v->Instr;
  476. i->BinaryOp.op = op;
  477. i->BinaryOp.left = left;
  478. i->BinaryOp.right = right;
  479. return v;
  480. }
  481. ssaValue *ssa_make_instr_br(ssaProcedure *p, ssaValue *cond, ssaBlock *true_block, ssaBlock *false_block) {
  482. ssaValue *v = ssa_alloc_instr(p, ssaInstr_Br);
  483. ssaInstr *i = &v->Instr;
  484. i->Br.cond = cond;
  485. i->Br.true_block = true_block;
  486. i->Br.false_block = false_block;
  487. return v;
  488. }
  489. ssaValue *ssa_make_instr_unreachable(ssaProcedure *p) {
  490. ssaValue *v = ssa_alloc_instr(p, ssaInstr_Unreachable);
  491. return v;
  492. }
  493. ssaValue *ssa_make_instr_ret(ssaProcedure *p, ssaValue *value) {
  494. ssaValue *v = ssa_alloc_instr(p, ssaInstr_Ret);
  495. v->Instr.Ret.value = value;
  496. return v;
  497. }
  498. ssaValue *ssa_make_instr_select(ssaProcedure *p, ssaValue *cond, ssaValue *t, ssaValue *f) {
  499. ssaValue *v = ssa_alloc_instr(p, ssaInstr_Select);
  500. v->Instr.Select.cond = cond;
  501. v->Instr.Select.true_value = t;
  502. v->Instr.Select.false_value = f;
  503. return v;
  504. }
  505. ssaValue *ssa_make_instr_call(ssaProcedure *p, ssaValue *value, ssaValue **args, isize arg_count, Type *result_type) {
  506. ssaValue *v = ssa_alloc_instr(p, ssaInstr_Call);
  507. v->Instr.Call.value = value;
  508. v->Instr.Call.args = args;
  509. v->Instr.Call.arg_count = arg_count;
  510. v->Instr.Call.type = result_type;
  511. return v;
  512. }
  513. ssaValue *ssa_make_instr_copy_memory(ssaProcedure *p, ssaValue *dst, ssaValue *src, ssaValue *len, i32 align, b32 is_volatile) {
  514. ssaValue *v = ssa_alloc_instr(p, ssaInstr_MemCopy);
  515. v->Instr.CopyMemory.dst = dst;
  516. v->Instr.CopyMemory.src = src;
  517. v->Instr.CopyMemory.len = len;
  518. v->Instr.CopyMemory.align = align;
  519. v->Instr.CopyMemory.is_volatile = is_volatile;
  520. return v;
  521. }
  522. ssaValue *ssa_make_instr_conv(ssaProcedure *p, ssaConvKind kind, ssaValue *value, Type *from, Type *to) {
  523. ssaValue *v = ssa_alloc_instr(p, ssaInstr_Conv);
  524. v->Instr.Conv.kind = kind;
  525. v->Instr.Conv.value = value;
  526. v->Instr.Conv.from = from;
  527. v->Instr.Conv.to = to;
  528. return v;
  529. }
  530. ssaValue *ssa_make_instr_extract_element(ssaProcedure *p, ssaValue *vector, ssaValue *index) {
  531. ssaValue *v = ssa_alloc_instr(p, ssaInstr_ExtractElement);
  532. v->Instr.ExtractElement.vector = vector;
  533. v->Instr.ExtractElement.index = index;
  534. return v;
  535. }
  536. ssaValue *ssa_make_instr_insert_element(ssaProcedure *p, ssaValue *vector, ssaValue *elem, ssaValue *index) {
  537. ssaValue *v = ssa_alloc_instr(p, ssaInstr_InsertElement);
  538. v->Instr.InsertElement.vector = vector;
  539. v->Instr.InsertElement.elem = elem;
  540. v->Instr.InsertElement.index = index;
  541. return v;
  542. }
  543. ssaValue *ssa_make_instr_shuffle_vector(ssaProcedure *p, ssaValue *vector, i32 *indices, isize index_count) {
  544. ssaValue *v = ssa_alloc_instr(p, ssaInstr_ShuffleVector);
  545. v->Instr.ShuffleVector.vector = vector;
  546. v->Instr.ShuffleVector.indices = indices;
  547. v->Instr.ShuffleVector.index_count = index_count;
  548. Type *vt = get_base_type(ssa_type(vector));
  549. v->Instr.ShuffleVector.type = make_type_vector(p->module->allocator, vt->Vector.elem, index_count);
  550. return v;
  551. }
  552. ssaValue *ssa_make_instr_no_op(ssaProcedure *p) {
  553. ssaValue *v = ssa_alloc_instr(p, ssaInstr_NoOp);
  554. return v;
  555. }
  556. ssaValue *ssa_make_value_constant(gbAllocator a, Type *type, ExactValue value) {
  557. ssaValue *v = ssa_alloc_value(a, ssaValue_Constant);
  558. v->Constant.type = type;
  559. v->Constant.value = value;
  560. return v;
  561. }
  562. ssaValue *ssa_make_value_procedure(gbAllocator a, ssaModule *m, Type *type, AstNode *type_expr, AstNode *body, String name) {
  563. ssaValue *v = ssa_alloc_value(a, ssaValue_Proc);
  564. v->Proc.module = m;
  565. v->Proc.type = type;
  566. v->Proc.type_expr = type_expr;
  567. v->Proc.body = body;
  568. v->Proc.name = name;
  569. return v;
  570. }
  571. ssaValue *ssa_make_value_block(ssaProcedure *proc, AstNode *node, Scope *scope, String label) {
  572. ssaValue *v = ssa_alloc_value(proc->module->allocator, ssaValue_Block);
  573. v->Block.label = label;
  574. v->Block.node = node;
  575. v->Block.scope = scope;
  576. v->Block.parent = proc;
  577. gb_array_init(v->Block.instrs, gb_heap_allocator());
  578. gb_array_init(v->Block.values, gb_heap_allocator());
  579. return v;
  580. }
  581. b32 ssa_is_blank_ident(AstNode *node) {
  582. if (node->kind == AstNode_Ident) {
  583. ast_node(i, Ident, node);
  584. return is_blank_ident(i->token.string);
  585. }
  586. return false;
  587. }
  588. ssaInstr *ssa_get_last_instr(ssaBlock *block) {
  589. if (block != NULL) {
  590. isize len = 0;
  591. if (block->instrs != NULL) {
  592. len = gb_array_count(block->instrs);
  593. }
  594. if (len > 0) {
  595. ssaValue *v = block->instrs[len-1];
  596. GB_ASSERT(v->kind == ssaValue_Instr);
  597. return &v->Instr;
  598. }
  599. }
  600. return NULL;
  601. }
  602. b32 ssa_is_instr_terminating(ssaInstr *i) {
  603. if (i != NULL) {
  604. switch (i->kind) {
  605. case ssaInstr_Ret:
  606. case ssaInstr_Unreachable:
  607. return true;
  608. }
  609. }
  610. return false;
  611. }
  612. ssaValue *ssa_emit(ssaProcedure *proc, ssaValue *instr) {
  613. GB_ASSERT(instr->kind == ssaValue_Instr);
  614. ssaBlock *b = proc->curr_block;
  615. instr->Instr.parent = b;
  616. if (b) {
  617. ssaInstr *i = ssa_get_last_instr(b);
  618. if (!ssa_is_instr_terminating(i)) {
  619. gb_array_append(b->instrs, instr);
  620. }
  621. }
  622. return instr;
  623. }
  624. ssaValue *ssa_emit_store(ssaProcedure *p, ssaValue *address, ssaValue *value) {
  625. return ssa_emit(p, ssa_make_instr_store(p, address, value));
  626. }
  627. ssaValue *ssa_emit_load(ssaProcedure *p, ssaValue *address) {
  628. return ssa_emit(p, ssa_make_instr_load(p, address));
  629. }
  630. ssaValue *ssa_emit_select(ssaProcedure *p, ssaValue *cond, ssaValue *t, ssaValue *f) {
  631. return ssa_emit(p, ssa_make_instr_select(p, cond, t, f));
  632. }
  633. ssaValue *ssa_add_local(ssaProcedure *proc, Entity *e) {
  634. return ssa_emit(proc, ssa_make_instr_local(proc, e));
  635. }
  636. ssaValue *ssa_add_local_for_identifier(ssaProcedure *proc, AstNode *name) {
  637. Entity **found = map_get(&proc->module->info->definitions, hash_pointer(name));
  638. if (found) {
  639. return ssa_add_local(proc, *found);
  640. }
  641. return NULL;
  642. }
  643. ssaValue *ssa_add_local_generated(ssaProcedure *proc, Type *type) {
  644. Entity *entity = make_entity_variable(proc->module->allocator,
  645. proc->curr_block->scope,
  646. empty_token,
  647. type);
  648. return ssa_emit(proc, ssa_make_instr_local(proc, entity));
  649. }
  650. ssaValue *ssa_add_param(ssaProcedure *proc, Entity *e) {
  651. ssaValue *v = ssa_make_value_param(proc->module->allocator, proc, e);
  652. ssaValue *l = ssa_add_local(proc, e);
  653. ssa_emit_store(proc, l, v);
  654. return v;
  655. }
  656. Type *ssa_type(ssaAddr lval) {
  657. if (lval.addr != NULL) {
  658. return ssa_type(lval.addr);
  659. }
  660. return NULL;
  661. }
  662. ssaBlock *ssa__make_block(ssaProcedure *proc, AstNode *node, String label) {
  663. Scope *scope = NULL;
  664. if (node != NULL) {
  665. Scope **found = map_get(&proc->module->info->scopes, hash_pointer(node));
  666. if (found) {
  667. scope = *found;
  668. } else {
  669. GB_PANIC("Block scope not found for %.*s", LIT(ast_node_strings[node->kind]));
  670. }
  671. }
  672. ssaValue *block = ssa_make_value_block(proc, node, scope, label);
  673. return &block->Block;
  674. }
  675. ssaBlock *ssa_add_block(ssaProcedure *proc, AstNode *node, String label) {
  676. ssaBlock *block = ssa__make_block(proc, node, label);
  677. gb_array_append(proc->blocks, block);
  678. return block;
  679. }
  680. void ssa_build_stmt(ssaProcedure *proc, AstNode *s);
  681. void ssa_emit_no_op(ssaProcedure *proc);
  682. void ssa_emit_jump(ssaProcedure *proc, ssaBlock *block);
  683. void ssa_build_defer_stmt(ssaProcedure *proc, ssaDefer d) {
  684. ssaBlock *b = ssa__make_block(proc, NULL, make_string("defer"));
  685. // HACK(bill): The prev block may defer injection before it's terminator
  686. ssaInstr *last_instr = ssa_get_last_instr(proc->curr_block);
  687. if (last_instr == NULL || !ssa_is_instr_terminating(last_instr)) {
  688. ssa_emit_jump(proc, b);
  689. }
  690. gb_array_append(proc->blocks, b);
  691. proc->curr_block = b;
  692. ssa_build_stmt(proc, d.stmt);
  693. }
  694. void ssa_emit_defer_stmts(ssaProcedure *proc, ssaDeferKind kind, ssaBlock *block) {
  695. isize count = gb_array_count(proc->defer_stmts);
  696. isize i = count;
  697. while (i --> 0) {
  698. ssaDefer d = proc->defer_stmts[i];
  699. if (kind == ssaDefer_Return) {
  700. ssa_build_defer_stmt(proc, d);
  701. } else if (kind == ssaDefer_Default) {
  702. if (proc->scope_index == d.scope_index &&
  703. d.scope_index > 1) {
  704. ssa_build_defer_stmt(proc, d);
  705. gb_array_pop(proc->defer_stmts);
  706. continue;
  707. } else {
  708. break;
  709. }
  710. } else if (kind == ssaDefer_Branch) {
  711. GB_ASSERT(block != NULL);
  712. isize lower_limit = block->scope_index+1;
  713. if (lower_limit < d.scope_index) {
  714. ssa_build_defer_stmt(proc, d);
  715. }
  716. }
  717. }
  718. }
  719. void ssa_emit_unreachable(ssaProcedure *proc) {
  720. ssa_emit(proc, ssa_make_instr_unreachable(proc));
  721. }
  722. void ssa_emit_ret(ssaProcedure *proc, ssaValue *v) {
  723. ssa_emit_defer_stmts(proc, ssaDefer_Return, NULL);
  724. ssa_emit(proc, ssa_make_instr_ret(proc, v));
  725. }
  726. void ssa_emit_jump(ssaProcedure *proc, ssaBlock *block) {
  727. ssa_emit(proc, ssa_make_instr_br(proc, NULL, block, NULL));
  728. proc->curr_block = NULL;
  729. }
  730. void ssa_emit_if(ssaProcedure *proc, ssaValue *cond, ssaBlock *true_block, ssaBlock *false_block) {
  731. ssaValue *br = ssa_make_instr_br(proc, cond, true_block, false_block);
  732. ssa_emit(proc, br);
  733. proc->curr_block = NULL;
  734. }
  735. void ssa_emit_no_op(ssaProcedure *proc) {
  736. ssa_emit(proc, ssa_make_instr_no_op(proc));
  737. }
  738. ssaValue *ssa_lvalue_store(ssaProcedure *proc, ssaAddr lval, ssaValue *value) {
  739. if (lval.addr != NULL) {
  740. if (lval.is_vector) {
  741. // HACK(bill): Fix how lvalues for vectors work
  742. ssaValue *v = ssa_emit_load(proc, lval.addr);
  743. Type *elem_type = get_base_type(ssa_type(v))->Vector.elem;
  744. ssaValue *elem = ssa_emit_conv(proc, value, elem_type);
  745. ssaValue *out = ssa_emit(proc, ssa_make_instr_insert_element(proc, v, elem, lval.index));
  746. return ssa_emit_store(proc, lval.addr, out);
  747. } else {
  748. value = ssa_emit_conv(proc, value, ssa_type(lval));
  749. return ssa_emit_store(proc, lval.addr, value);
  750. }
  751. }
  752. return NULL;
  753. }
  754. ssaValue *ssa_lvalue_load(ssaProcedure *proc, ssaAddr lval) {
  755. if (lval.addr != NULL) {
  756. if (lval.is_vector) {
  757. // HACK(bill): Fix how lvalues for vectors work
  758. ssaValue *v = ssa_emit_load(proc, lval.addr);
  759. return ssa_emit(proc, ssa_make_instr_extract_element(proc, v, lval.index));
  760. }
  761. return ssa_emit_load(proc, lval.addr);
  762. }
  763. GB_PANIC("Illegal lvalue load");
  764. return NULL;
  765. }
  766. void ssa_begin_procedure_body(ssaProcedure *proc) {
  767. gb_array_init(proc->blocks, gb_heap_allocator());
  768. gb_array_init(proc->defer_stmts, gb_heap_allocator());
  769. proc->curr_block = ssa_add_block(proc, proc->type_expr, make_string("entry"));
  770. if (proc->type->Proc.params != NULL) {
  771. auto *params = &proc->type->Proc.params->Tuple;
  772. for (isize i = 0; i < params->variable_count; i++) {
  773. Entity *e = params->variables[i];
  774. ssa_add_param(proc, e);
  775. }
  776. }
  777. }
  778. void ssa_end_procedure_body(ssaProcedure *proc) {
  779. if (proc->type->Proc.result_count == 0) {
  780. ssa_emit_ret(proc, NULL);
  781. }
  782. // Number blocks and registers
  783. i32 reg_id = 0;
  784. gb_for_array(i, proc->blocks) {
  785. ssaBlock *b = proc->blocks[i];
  786. b->id = i;
  787. gb_for_array(j, b->instrs) {
  788. ssaValue *value = b->instrs[j];
  789. GB_ASSERT(value->kind == ssaValue_Instr);
  790. ssaInstr *instr = &value->Instr;
  791. // NOTE(bill): Ignore non-returning instructions
  792. switch (instr->kind) {
  793. case ssaInstr_Store:
  794. case ssaInstr_Br:
  795. case ssaInstr_Ret:
  796. case ssaInstr_Unreachable:
  797. case ssaInstr_MemCopy:
  798. case ssaInstr_StartupRuntime:
  799. continue;
  800. case ssaInstr_Call:
  801. if (instr->Call.type == NULL) {
  802. continue;
  803. }
  804. break;
  805. }
  806. value->id = reg_id;
  807. reg_id++;
  808. }
  809. }
  810. }
  811. void ssa_push_target_list(ssaProcedure *proc, ssaBlock *break_, ssaBlock *continue_, ssaBlock *fallthrough_) {
  812. ssaTargetList *tl = gb_alloc_item(proc->module->allocator, ssaTargetList);
  813. tl->prev = proc->target_list;
  814. tl->break_ = break_;
  815. tl->continue_ = continue_;
  816. tl->fallthrough_ = fallthrough_;
  817. proc->target_list = tl;
  818. }
  819. void ssa_pop_target_list(ssaProcedure *proc) {
  820. proc->target_list = proc->target_list->prev;
  821. }
  822. ssaValue *ssa_emit_arith(ssaProcedure *proc, Token op, ssaValue *left, ssaValue *right, Type *type) {
  823. switch (op.kind) {
  824. case Token_AndNot: {
  825. // NOTE(bill): x &~ y == x & (~y) == x & (y ~ -1)
  826. // NOTE(bill): "not" `x` == `x` "xor" `-1`
  827. ssaValue *neg = ssa_make_value_constant(proc->module->allocator, type, make_exact_value_integer(-1));
  828. op.kind = Token_Xor;
  829. right = ssa_emit_arith(proc, op, right, neg, type);
  830. ssa_set_type(right, type);
  831. op.kind = Token_And;
  832. } /* fallthrough */
  833. case Token_Add:
  834. case Token_Sub:
  835. case Token_Mul:
  836. case Token_Quo:
  837. case Token_Mod:
  838. case Token_And:
  839. case Token_Or:
  840. case Token_Xor:
  841. left = ssa_emit_conv(proc, left, type);
  842. right = ssa_emit_conv(proc, right, type);
  843. break;
  844. }
  845. ssaValue *v = ssa_emit(proc, ssa_make_instr_binary_op(proc, op, left, right));
  846. ssa_set_type(v, type);
  847. return v;
  848. }
  849. ssaValue *ssa_emit_comp(ssaProcedure *proc, Token op, ssaValue *left, ssaValue *right) {
  850. Type *a = get_base_type(ssa_type(left));
  851. Type *b = get_base_type(ssa_type(right));
  852. if (are_types_identical(a, b)) {
  853. // NOTE(bill): No need for a conversion
  854. } else if (left->kind == ssaValue_Constant) {
  855. left = ssa_emit_conv(proc, left, ssa_type(right));
  856. } else if (right->kind == ssaValue_Constant) {
  857. right = ssa_emit_conv(proc, right, ssa_type(left));
  858. }
  859. ssaValue *v = ssa_make_instr_binary_op(proc, op, left, right);
  860. Type *result = t_bool;
  861. if (is_type_vector(a)) {
  862. result = make_type_vector(proc->module->allocator, t_bool, a->Vector.count);
  863. }
  864. ssa_set_type(v, result);
  865. return ssa_emit(proc, v);
  866. }
  867. ssaValue *ssa_emit_ptr_offset(ssaProcedure *proc, ssaValue *ptr, ssaValue *offset) {
  868. Type *type = ssa_type(ptr);
  869. ssaValue *gep = NULL;
  870. offset = ssa_emit_conv(proc, offset, t_int);
  871. gep = ssa_make_instr_get_element_ptr(proc, ptr, offset, NULL, 1, false);
  872. gep->Instr.GetElementPtr.elem_type = type_deref(type);
  873. gep->Instr.GetElementPtr.result_type = type;
  874. return ssa_emit(proc, gep);
  875. }
  876. ssaValue *ssa_emit_zero_gep(ssaProcedure *proc, ssaValue *s) {
  877. ssaValue *gep = NULL;
  878. // NOTE(bill): For some weird legacy reason in LLVM, structure elements must be accessed as an i32
  879. gep = ssa_make_instr_get_element_ptr(proc, s, NULL, NULL, 0, true);
  880. gep->Instr.GetElementPtr.elem_type = ssa_type(s);
  881. gep->Instr.GetElementPtr.result_type = ssa_type(s);
  882. return ssa_emit(proc, gep);
  883. }
  884. ssaValue *ssa_emit_struct_gep(ssaProcedure *proc, ssaValue *s, ssaValue *index, Type *result_type) {
  885. ssaValue *gep = NULL;
  886. // NOTE(bill): For some weird legacy reason in LLVM, structure elements must be accessed as an i32
  887. index = ssa_emit_conv(proc, index, t_i32);
  888. gep = ssa_make_instr_get_element_ptr(proc, s, v_zero, index, 2, true);
  889. gep->Instr.GetElementPtr.elem_type = ssa_type(s);
  890. gep->Instr.GetElementPtr.result_type = result_type;
  891. return ssa_emit(proc, gep);
  892. }
  893. ssaValue *ssa_emit_struct_gep(ssaProcedure *proc, ssaValue *s, i32 index, Type *result_type) {
  894. ssaValue *i = ssa_make_value_constant(proc->module->allocator, t_i32, make_exact_value_integer(index));
  895. return ssa_emit_struct_gep(proc, s, i, result_type);
  896. }
  897. ssaValue *ssa_emit_struct_ev(ssaProcedure *proc, ssaValue *s, i32 index, Type *result_type) {
  898. // NOTE(bill): For some weird legacy reason in LLVM, structure elements must be accessed as an i32
  899. return ssa_emit(proc, ssa_make_instr_extract_value(proc, s, index, result_type));
  900. }
  901. ssaValue *ssa_array_elem(ssaProcedure *proc, ssaValue *array) {
  902. Type *t = ssa_type(array);
  903. GB_ASSERT(t->kind == Type_Array);
  904. Type *base_type = t->Array.elem;
  905. ssaValue *elem = ssa_make_instr_get_element_ptr(proc, array, v_zero, v_zero, 2, true);
  906. Type *result_type = make_type_pointer(proc->module->allocator, base_type);
  907. elem->Instr.GetElementPtr.elem_type = t;
  908. elem->Instr.GetElementPtr.result_type = result_type;
  909. return ssa_emit(proc, elem);
  910. }
  911. ssaValue *ssa_array_len(ssaProcedure *proc, ssaValue *array) {
  912. Type *t = ssa_type(array);
  913. GB_ASSERT(t->kind == Type_Array);
  914. return ssa_make_value_constant(proc->module->allocator, t_int, make_exact_value_integer(t->Array.count));
  915. }
  916. ssaValue *ssa_array_cap(ssaProcedure *proc, ssaValue *array) {
  917. return ssa_array_len(proc, array);
  918. }
  919. ssaValue *ssa_slice_elem(ssaProcedure *proc, ssaValue *slice) {
  920. Type *t = ssa_type(slice);
  921. GB_ASSERT(t->kind == Type_Slice);
  922. Type *result_type = make_type_pointer(proc->module->allocator, t->Slice.elem);
  923. return ssa_emit_load(proc, ssa_emit_struct_gep(proc, slice, v_zero32, result_type));
  924. }
  925. ssaValue *ssa_slice_len(ssaProcedure *proc, ssaValue *slice) {
  926. Type *t = ssa_type(slice);
  927. GB_ASSERT(t->kind == Type_Slice);
  928. return ssa_emit_load(proc, ssa_emit_struct_gep(proc, slice, v_one32, t_int));
  929. }
  930. ssaValue *ssa_slice_cap(ssaProcedure *proc, ssaValue *slice) {
  931. Type *t = ssa_type(slice);
  932. GB_ASSERT(t->kind == Type_Slice);
  933. return ssa_emit_load(proc, ssa_emit_struct_gep(proc, slice, v_two32, t_int));
  934. }
  935. ssaValue *ssa_string_elem(ssaProcedure *proc, ssaValue *string) {
  936. Type *t = ssa_type(string);
  937. GB_ASSERT(t->kind == Type_Basic && t->Basic.kind == Basic_string);
  938. Type *base_type = t_u8;
  939. ssaValue *elem = ssa_make_instr_get_element_ptr(proc, string, v_zero, v_zero32, 2, true);
  940. Type *result_type = make_type_pointer(proc->module->allocator, base_type);
  941. elem->Instr.GetElementPtr.elem_type = t;
  942. elem->Instr.GetElementPtr.result_type = result_type;
  943. return ssa_emit_load(proc, ssa_emit(proc, elem));
  944. }
  945. ssaValue *ssa_string_len(ssaProcedure *proc, ssaValue *string) {
  946. Type *t = ssa_type(string);
  947. GB_ASSERT(t->kind == Type_Basic && t->Basic.kind == Basic_string);
  948. return ssa_emit_load(proc, ssa_emit_struct_gep(proc, string, v_one32, t_int));
  949. }
  950. ssaValue *ssa_emit_slice(ssaProcedure *proc, Type *slice_type, ssaValue *base, ssaValue *low, ssaValue *high, ssaValue *max) {
  951. // TODO(bill): array bounds checking for slice creation
  952. // TODO(bill): check that low < high <= max
  953. gbAllocator a = proc->module->allocator;
  954. Type *base_type = get_base_type(ssa_type(base));
  955. if (low == NULL) {
  956. low = v_zero;
  957. }
  958. if (high == NULL) {
  959. switch (base_type->kind) {
  960. case Type_Array: high = ssa_array_len(proc, base); break;
  961. case Type_Slice: high = ssa_slice_len(proc, base); break;
  962. case Type_Pointer: high = v_one; break;
  963. }
  964. }
  965. if (max == NULL) {
  966. switch (base_type->kind) {
  967. case Type_Array: max = ssa_array_cap(proc, base); break;
  968. case Type_Slice: max = ssa_slice_cap(proc, base); break;
  969. case Type_Pointer: max = high; break;
  970. }
  971. }
  972. GB_ASSERT(max != NULL);
  973. Token op_sub = {Token_Sub};
  974. ssaValue *len = ssa_emit_arith(proc, op_sub, high, low, t_int);
  975. ssaValue *cap = ssa_emit_arith(proc, op_sub, max, low, t_int);
  976. ssaValue *elem = NULL;
  977. switch (base_type->kind) {
  978. case Type_Array: elem = ssa_array_elem(proc, base); break;
  979. case Type_Slice: elem = ssa_slice_elem(proc, base); break;
  980. case Type_Pointer: elem = ssa_emit_load(proc, base); break;
  981. }
  982. elem = ssa_emit_ptr_offset(proc, elem, low);
  983. ssaValue *slice = ssa_add_local_generated(proc, slice_type);
  984. ssaValue *gep = NULL;
  985. gep = ssa_emit_struct_gep(proc, slice, v_zero32, ssa_type(elem));
  986. ssa_emit_store(proc, gep, elem);
  987. gep = ssa_emit_struct_gep(proc, slice, v_one32, t_int);
  988. ssa_emit_store(proc, gep, len);
  989. gep = ssa_emit_struct_gep(proc, slice, v_two32, t_int);
  990. ssa_emit_store(proc, gep, cap);
  991. return slice;
  992. }
  993. ssaValue *ssa_emit_substring(ssaProcedure *proc, ssaValue *base, ssaValue *low, ssaValue *high) {
  994. Type *bt = get_base_type(ssa_type(base));
  995. GB_ASSERT(bt == t_string);
  996. if (low == NULL) {
  997. low = v_zero;
  998. }
  999. if (high == NULL) {
  1000. high = ssa_string_len(proc, base);
  1001. }
  1002. Token op_sub = {Token_Sub};
  1003. ssaValue *elem, *len;
  1004. len = ssa_emit_arith(proc, op_sub, high, low, t_int);
  1005. elem = ssa_string_elem(proc, base);
  1006. elem = ssa_emit_ptr_offset(proc, elem, low);
  1007. ssaValue *str, *gep;
  1008. str = ssa_add_local_generated(proc, t_string);
  1009. gep = ssa_emit_struct_gep(proc, str, v_zero32, ssa_type(elem));
  1010. ssa_emit_store(proc, gep, elem);
  1011. gep = ssa_emit_struct_gep(proc, str, v_one32, t_int);
  1012. ssa_emit_store(proc, gep, len);
  1013. return str;
  1014. }
  1015. ssaValue *ssa_add_global_string_array(ssaProcedure *proc, ExactValue value) {
  1016. GB_ASSERT(value.kind == ExactValue_String);
  1017. gbAllocator a = gb_heap_allocator();
  1018. isize max_len = 4+8+1;
  1019. u8 *str = cast(u8 *)gb_alloc_array(a, u8, max_len);
  1020. isize len = gb_snprintf(cast(char *)str, max_len, ".str%x", proc->module->global_string_index);
  1021. proc->module->global_string_index++;
  1022. String name = make_string(str, len-1);
  1023. Token token = {Token_String};
  1024. token.string = name;
  1025. Type *type = make_type_array(a, t_u8, value.value_string.len);
  1026. Entity *entity = make_entity_constant(a, NULL, token, type, value);
  1027. ssaValue *g = ssa_make_value_global(a, entity, ssa_make_value_constant(a, type, value));
  1028. map_set(&proc->module->values, hash_pointer(entity), g);
  1029. map_set(&proc->module->members, hash_string(name), g);
  1030. return g;
  1031. }
  1032. ssaValue *ssa_emit_string(ssaProcedure *proc, ssaValue *elem, ssaValue *len) {
  1033. Type *t_u8_ptr = ssa_type(elem);
  1034. GB_ASSERT(t_u8_ptr->kind == Type_Pointer);
  1035. GB_ASSERT(is_type_u8(t_u8_ptr->Pointer.elem));
  1036. ssaValue *str = ssa_add_local_generated(proc, t_string);
  1037. ssaValue *str_elem = ssa_emit_struct_gep(proc, str, v_zero32, t_u8_ptr);
  1038. ssaValue *str_len = ssa_emit_struct_gep(proc, str, v_one32, t_int);
  1039. ssa_emit_store(proc, str_elem, elem);
  1040. ssa_emit_store(proc, str_len, len);
  1041. return str;
  1042. }
  1043. ssaValue *ssa_emit_conv(ssaProcedure *proc, ssaValue *value, Type *t) {
  1044. Type *src_type = ssa_type(value);
  1045. if (are_types_identical(t, src_type)) {
  1046. return value;
  1047. }
  1048. Type *src = get_enum_base_type(get_base_type(src_type));
  1049. Type *dst = get_enum_base_type(get_base_type(t));
  1050. if (are_types_identical(src, dst)) {
  1051. return value;
  1052. }
  1053. if (value->kind == ssaValue_Constant) {
  1054. if (dst->kind == Type_Basic) {
  1055. ExactValue ev = value->Constant.value;
  1056. if (is_type_float(dst)) {
  1057. ev = exact_value_to_float(ev);
  1058. } else if (is_type_string(dst)) {
  1059. //
  1060. } else if (is_type_integer(dst)) {
  1061. ev = exact_value_to_integer(ev);
  1062. } else if (is_type_pointer(dst)) {
  1063. // IMPORTANT NOTE(bill): LLVM doesn't support pointer constants expect `null`
  1064. ssaValue *i = ssa_make_value_constant(proc->module->allocator, t_uint, ev);
  1065. return ssa_emit(proc, ssa_make_instr_conv(proc, ssaConv_inttoptr, i, t_uint, dst));
  1066. }
  1067. return ssa_make_value_constant(proc->module->allocator, t, ev);
  1068. }
  1069. }
  1070. // integer -> integer
  1071. if (is_type_integer(src) && is_type_integer(dst)) {
  1072. GB_ASSERT(src->kind == Type_Basic &&
  1073. dst->kind == Type_Basic);
  1074. i64 sz = type_size_of(proc->module->sizes, proc->module->allocator, src);
  1075. i64 dz = type_size_of(proc->module->sizes, proc->module->allocator, dst);
  1076. if (sz == dz) {
  1077. // NOTE(bill): In LLVM, all integers are signed and rely upon 2's compliment
  1078. return value;
  1079. }
  1080. ssaConvKind kind = ssaConv_trunc;
  1081. if (dz >= sz) {
  1082. kind = ssaConv_zext;
  1083. }
  1084. return ssa_emit(proc, ssa_make_instr_conv(proc, kind, value, src, dst));
  1085. }
  1086. // boolean -> integer
  1087. if (is_type_boolean(src) && is_type_integer(dst)) {
  1088. return ssa_emit(proc, ssa_make_instr_conv(proc, ssaConv_zext, value, src, dst));
  1089. }
  1090. // integer -> boolean
  1091. if (is_type_integer(src) && is_type_boolean(dst)) {
  1092. Token op = {Token_NotEq};
  1093. return ssa_emit_comp(proc, op, value, v_zero);
  1094. }
  1095. // float -> float
  1096. if (is_type_float(src) && is_type_float(dst)) {
  1097. i64 sz = basic_type_sizes[src->Basic.kind];
  1098. i64 dz = basic_type_sizes[dst->Basic.kind];
  1099. ssaConvKind kind = ssaConv_fptrunc;
  1100. if (dz >= sz) {
  1101. kind = ssaConv_fpext;
  1102. }
  1103. return ssa_emit(proc, ssa_make_instr_conv(proc, kind, value, src, dst));
  1104. }
  1105. // float <-> integer
  1106. if (is_type_float(src) && is_type_integer(dst)) {
  1107. ssaConvKind kind = ssaConv_fptosi;
  1108. if (is_type_unsigned(dst)) {
  1109. kind = ssaConv_fptoui;
  1110. }
  1111. return ssa_emit(proc, ssa_make_instr_conv(proc, kind, value, src, dst));
  1112. }
  1113. if (is_type_integer(src) && is_type_float(dst)) {
  1114. ssaConvKind kind = ssaConv_sitofp;
  1115. if (is_type_unsigned(src)) {
  1116. kind = ssaConv_uitofp;
  1117. }
  1118. return ssa_emit(proc, ssa_make_instr_conv(proc, kind, value, src, dst));
  1119. }
  1120. // Pointer <-> int
  1121. if (is_type_pointer(src) && is_type_int_or_uint(dst)) {
  1122. return ssa_emit(proc, ssa_make_instr_conv(proc, ssaConv_ptrtoint, value, src, dst));
  1123. }
  1124. if (is_type_int_or_uint(src) && is_type_pointer(dst)) {
  1125. return ssa_emit(proc, ssa_make_instr_conv(proc, ssaConv_inttoptr, value, src, dst));
  1126. }
  1127. // Pointer <-> Pointer
  1128. if (is_type_pointer(src) && is_type_pointer(dst)) {
  1129. return ssa_emit(proc, ssa_make_instr_conv(proc, ssaConv_bitcast, value, src, dst));
  1130. }
  1131. // proc <-> proc
  1132. if (is_type_proc(src) && is_type_proc(dst)) {
  1133. return ssa_emit(proc, ssa_make_instr_conv(proc, ssaConv_bitcast, value, src, dst));
  1134. }
  1135. // pointer -> proc
  1136. if (is_type_pointer(src) && is_type_proc(dst)) {
  1137. return ssa_emit(proc, ssa_make_instr_conv(proc, ssaConv_bitcast, value, src, dst));
  1138. }
  1139. // proc -> pointer
  1140. if (is_type_proc(src) && is_type_pointer(dst)) {
  1141. return ssa_emit(proc, ssa_make_instr_conv(proc, ssaConv_bitcast, value, src, dst));
  1142. }
  1143. // []byte/[]u8 <-> string
  1144. if (is_type_u8_slice(src) && is_type_string(dst)) {
  1145. ssaValue *slice = ssa_add_local_generated(proc, src);
  1146. ssa_emit_store(proc, slice, value);
  1147. ssaValue *elem = ssa_slice_elem(proc, slice);
  1148. ssaValue *len = ssa_slice_len(proc, slice);
  1149. return ssa_emit_load(proc, ssa_emit_string(proc, elem, len));
  1150. }
  1151. if (is_type_string(src) && is_type_u8_slice(dst)) {
  1152. ssaValue *str = ssa_add_local_generated(proc, src);
  1153. ssa_emit_store(proc, str, value);
  1154. ssaValue *elem = ssa_string_elem(proc, str);
  1155. ssaValue *elem_ptr = ssa_add_local_generated(proc, ssa_type(elem));
  1156. ssa_emit_store(proc, elem_ptr, elem);
  1157. ssaValue *len = ssa_string_len(proc, str);
  1158. ssaValue *slice = ssa_emit_slice(proc, dst, elem_ptr, v_zero, len, len);
  1159. return ssa_emit_load(proc, slice);
  1160. }
  1161. if (is_type_vector(dst)) {
  1162. Type *dst_elem = dst->Vector.elem;
  1163. value = ssa_emit_conv(proc, value, dst_elem);
  1164. ssaValue *v = ssa_add_local_generated(proc, t);
  1165. v = ssa_emit_load(proc, v);
  1166. v = ssa_emit(proc, ssa_make_instr_insert_element(proc, v, value, v_zero32));
  1167. // NOTE(bill): Broadcast lowest value to all values
  1168. isize index_count = dst->Vector.count;
  1169. i32 *indices = gb_alloc_array(proc->module->allocator, i32, index_count);
  1170. for (isize i = 0; i < index_count; i++) {
  1171. indices[i] = 0;
  1172. }
  1173. v = ssa_emit(proc, ssa_make_instr_shuffle_vector(proc, v, indices, index_count));
  1174. return v;
  1175. }
  1176. gb_printf_err("Not Identical %s != %s\n", type_to_string(src_type), type_to_string(t));
  1177. gb_printf_err("Not Identical %s != %s\n", type_to_string(src), type_to_string(dst));
  1178. GB_PANIC("Invalid type conversion: `%s` to `%s`", type_to_string(src_type), type_to_string(t));
  1179. return NULL;
  1180. }
  1181. ssaValue *ssa_emit_transmute(ssaProcedure *proc, ssaValue *value, Type *t) {
  1182. Type *src_type = ssa_type(value);
  1183. if (are_types_identical(t, src_type)) {
  1184. return value;
  1185. }
  1186. Type *src = get_base_type(src_type);
  1187. Type *dst = get_base_type(t);
  1188. if (are_types_identical(t, src_type))
  1189. return value;
  1190. i64 sz = type_size_of(proc->module->sizes, proc->module->allocator, src);
  1191. i64 dz = type_size_of(proc->module->sizes, proc->module->allocator, dst);
  1192. if (sz == dz) {
  1193. return ssa_emit(proc, ssa_make_instr_conv(proc, ssaConv_bitcast, value, src, dst));
  1194. }
  1195. GB_PANIC("Invalid transmute conversion: `%s` to `%s`", type_to_string(src_type), type_to_string(t));
  1196. return NULL;
  1197. }
  1198. ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue *tv) {
  1199. switch (expr->kind) {
  1200. case_ast_node(bl, BasicLit, expr);
  1201. GB_PANIC("Non-constant basic literal");
  1202. case_end;
  1203. case_ast_node(i, Ident, expr);
  1204. Entity *e = *map_get(&proc->module->info->uses, hash_pointer(expr));
  1205. if (e->kind == Entity_Builtin) {
  1206. GB_PANIC("TODO(bill): ssa_build_single_expr Entity_Builtin");
  1207. return NULL;
  1208. }
  1209. auto *found = map_get(&proc->module->values, hash_pointer(e));
  1210. if (found) {
  1211. ssaValue *v = *found;
  1212. if (v->kind == ssaValue_Proc)
  1213. return v;
  1214. return ssa_emit_load(proc, v);
  1215. }
  1216. return NULL;
  1217. case_end;
  1218. case_ast_node(pe, ParenExpr, expr);
  1219. return ssa_build_single_expr(proc, unparen_expr(expr), tv);
  1220. case_end;
  1221. case_ast_node(de, DerefExpr, expr);
  1222. return ssa_lvalue_load(proc, ssa_build_addr(proc, expr));
  1223. case_end;
  1224. case_ast_node(se, SelectorExpr, expr);
  1225. return ssa_lvalue_load(proc, ssa_build_addr(proc, expr));
  1226. case_end;
  1227. case_ast_node(ue, UnaryExpr, expr);
  1228. switch (ue->op.kind) {
  1229. case Token_Pointer: {
  1230. ssaValue *v = ssa_emit_zero_gep(proc, ssa_build_addr(proc, ue->expr).addr);
  1231. ssa_set_type(v, type_of_expr(proc->module->info, expr));
  1232. return v;
  1233. }
  1234. case Token_Add:
  1235. return ssa_build_expr(proc, ue->expr);
  1236. case Token_Sub: {
  1237. // NOTE(bill): -`x` == 0 - `x`
  1238. ssaValue *left = v_zero;
  1239. ssaValue *right = ssa_build_expr(proc, ue->expr);
  1240. return ssa_emit_arith(proc, ue->op, left, right, tv->type);
  1241. } break;
  1242. case Token_Not: // Boolean not
  1243. case Token_Xor: { // Bitwise not
  1244. // NOTE(bill): "not" `x` == `x` "xor" `-1`
  1245. ExactValue neg_one = make_exact_value_integer(-1);
  1246. ssaValue *left = ssa_build_expr(proc, ue->expr);
  1247. ssaValue *right = ssa_make_value_constant(proc->module->allocator, tv->type, neg_one);
  1248. return ssa_emit_arith(proc, ue->op, left, right, tv->type);
  1249. } break;
  1250. }
  1251. case_end;
  1252. case_ast_node(be, BinaryExpr, expr);
  1253. switch (be->op.kind) {
  1254. case Token_Add:
  1255. case Token_Sub:
  1256. case Token_Mul:
  1257. case Token_Quo:
  1258. case Token_Mod:
  1259. case Token_And:
  1260. case Token_Or:
  1261. case Token_Xor:
  1262. case Token_AndNot:
  1263. case Token_Shl:
  1264. case Token_Shr:
  1265. return ssa_emit_arith(proc, be->op,
  1266. ssa_build_expr(proc, be->left),
  1267. ssa_build_expr(proc, be->right),
  1268. tv->type);
  1269. case Token_CmpEq:
  1270. case Token_NotEq:
  1271. case Token_Lt:
  1272. case Token_LtEq:
  1273. case Token_Gt:
  1274. case Token_GtEq: {
  1275. ssaValue *left = ssa_build_expr(proc, be->left);
  1276. ssaValue *right = ssa_build_expr(proc, be->right);
  1277. ssaValue *cmp = ssa_emit_comp(proc, be->op, left, right);
  1278. return ssa_emit_conv(proc, cmp, default_type(tv->type));
  1279. } break;
  1280. case Token_as:
  1281. return ssa_emit_conv(proc, ssa_build_expr(proc, be->left), tv->type);
  1282. case Token_transmute:
  1283. return ssa_emit_transmute(proc, ssa_build_expr(proc, be->left), tv->type);
  1284. default:
  1285. GB_PANIC("Invalid binary expression");
  1286. break;
  1287. }
  1288. case_end;
  1289. case_ast_node(pl, ProcLit, expr);
  1290. if (proc->children == NULL) {
  1291. gb_array_init(proc->children, gb_heap_allocator());
  1292. }
  1293. // NOTE(bill): Generate a new name
  1294. // parent$count
  1295. isize name_len = proc->name.len + 1 + 8 + 1;
  1296. u8 *name_text = gb_alloc_array(proc->module->allocator, u8, name_len);
  1297. name_len = gb_snprintf(cast(char *)name_text, name_len, "%.*s$%d", LIT(proc->name), cast(i32)gb_array_count(proc->children));
  1298. String name = make_string(name_text, name_len-1);
  1299. Type *type = type_of_expr(proc->module->info, expr);
  1300. ssaValue *value = ssa_make_value_procedure(proc->module->allocator,
  1301. proc->module, type, pl->type, pl->body, name);
  1302. value->Proc.tags = pl->tags;
  1303. gb_array_append(proc->children, &value->Proc);
  1304. ssa_build_proc(value, proc);
  1305. return value;
  1306. case_end;
  1307. case_ast_node(cl, CompoundLit, expr);
  1308. Type *type = type_of_expr(proc->module->info, expr);
  1309. Type *base_type = get_base_type(type);
  1310. ssaValue *v = ssa_add_local_generated(proc, type);
  1311. Type *et = NULL;
  1312. switch (base_type->kind) {
  1313. case Type_Vector: et = base_type->Vector.elem; break;
  1314. case Type_Array: et = base_type->Array.elem; break;
  1315. case Type_Slice: et = base_type->Slice.elem; break;
  1316. }
  1317. switch (base_type->kind) {
  1318. default: GB_PANIC("Unknown CompoundLit type: %s", type_to_string(type)); break;
  1319. case Type_Vector: {
  1320. isize index = 0;
  1321. ssaValue *result = ssa_emit_load(proc, v);
  1322. for (AstNode *elem = cl->elem_list;
  1323. elem != NULL;
  1324. elem = elem->next, index++) {
  1325. ssaValue *field_elem = ssa_build_expr(proc, elem);
  1326. Type *t = ssa_type(field_elem);
  1327. GB_ASSERT(t->kind != Type_Tuple);
  1328. ssaValue *ev = ssa_emit_conv(proc, field_elem, et);
  1329. ssaValue *i = ssa_make_value_constant(proc->module->allocator, t_int, make_exact_value_integer(index));
  1330. result = ssa_emit(proc, ssa_make_instr_insert_element(proc, result, ev, i));
  1331. }
  1332. if (index == 1 && base_type->Vector.count > 1) {
  1333. isize index_count = base_type->Vector.count;
  1334. i32 *indices = gb_alloc_array(proc->module->allocator, i32, index_count);
  1335. for (isize i = 0; i < index_count; i++) {
  1336. indices[i] = 0;
  1337. }
  1338. ssaValue *sv = ssa_emit(proc, ssa_make_instr_shuffle_vector(proc, result, indices, index_count));
  1339. ssa_emit_store(proc, v, sv);
  1340. return ssa_emit_load(proc, v);
  1341. }
  1342. return result;
  1343. } break;
  1344. case Type_Struct: {
  1345. auto *st = &base_type->Struct;
  1346. if (cl->elem_list != NULL) {
  1347. isize index = 0;
  1348. AstNode *elem = cl->elem_list;
  1349. for (;
  1350. elem != NULL;
  1351. elem = elem->next, index++) {
  1352. isize field_index = index;
  1353. ssaValue *field_expr = NULL;
  1354. Entity *field = NULL;
  1355. if (elem->kind == AstNode_FieldValue) {
  1356. ast_node(kv, FieldValue, elem);
  1357. Selection sel = lookup_field(base_type, kv->field->Ident.token.string);
  1358. field_index = sel.index[0];
  1359. field_expr = ssa_build_expr(proc, kv->value);
  1360. } else {
  1361. field_expr = ssa_build_expr(proc, elem);
  1362. }
  1363. GB_ASSERT(ssa_type(field_expr)->kind != Type_Tuple);
  1364. field = st->fields[field_index];
  1365. Type *ft = field->type;
  1366. ssaValue *fv = ssa_emit_conv(proc, field_expr, ft);
  1367. ssaValue *gep = ssa_emit_struct_gep(proc, v, field_index, ft);
  1368. ssa_emit_store(proc, gep, fv);
  1369. }
  1370. }
  1371. } break;
  1372. case Type_Array: {
  1373. isize index = 0;
  1374. for (AstNode *elem = cl->elem_list;
  1375. elem != NULL;
  1376. elem = elem->next, index++) {
  1377. ssaValue *field_expr = ssa_build_expr(proc, elem);
  1378. Type *t = ssa_type(field_expr);
  1379. GB_ASSERT(t->kind != Type_Tuple);
  1380. ssaValue *ev = ssa_emit_conv(proc, field_expr, et);
  1381. ssaValue *gep = ssa_emit_struct_gep(proc, v, index, et);
  1382. ssa_emit_store(proc, gep, ev);
  1383. }
  1384. } break;
  1385. case Type_Slice: {
  1386. i64 count = cl->elem_count;
  1387. ssaValue *array = ssa_add_local_generated(proc, make_type_array(proc->module->allocator, et, count));
  1388. isize index = 0;
  1389. for (AstNode *elem = cl->elem_list;
  1390. elem != NULL;
  1391. elem = elem->next, index++) {
  1392. ssaValue *field_expr = ssa_build_expr(proc, elem);
  1393. Type *t = ssa_type(field_expr);
  1394. GB_ASSERT(t->kind != Type_Tuple);
  1395. ssaValue *ev = ssa_emit_conv(proc, field_expr, et);
  1396. ssaValue *gep = ssa_emit_struct_gep(proc, array, index, et);
  1397. ssa_emit_store(proc, gep, ev);
  1398. }
  1399. ssaValue *elem = ssa_emit_struct_gep(proc, array, v_zero32,
  1400. make_type_pointer(proc->module->allocator, et));
  1401. ssaValue *len = ssa_array_len(proc, array);
  1402. ssaValue *gep = NULL;
  1403. gep = ssa_emit_struct_gep(proc, v, v_zero32, ssa_type(elem));
  1404. ssa_emit_store(proc, gep, elem);
  1405. gep = ssa_emit_struct_gep(proc, v, v_one32, t_int);
  1406. ssa_emit_store(proc, gep, len);
  1407. gep = ssa_emit_struct_gep(proc, v, v_two32, t_int);
  1408. ssa_emit_store(proc, gep, len);
  1409. } break;
  1410. }
  1411. return ssa_emit_load(proc, v);
  1412. case_end;
  1413. case_ast_node(ce, CallExpr, expr);
  1414. AstNode *p = unparen_expr(ce->proc);
  1415. if (p->kind == AstNode_Ident) {
  1416. Entity **found = map_get(&proc->module->info->uses, hash_pointer(p));
  1417. if (found && (*found)->kind == Entity_Builtin) {
  1418. Entity *e = *found;
  1419. switch (e->Builtin.id) {
  1420. case BuiltinProc_len: {
  1421. // len :: proc(Type) -> int
  1422. // NOTE(bill): len of an array is a constant expression
  1423. ssaValue *v = ssa_build_addr(proc, ce->arg_list).addr;
  1424. Type *t = get_base_type(ssa_type(v));
  1425. if (t == t_string)
  1426. return ssa_string_len(proc, v);
  1427. else if (t->kind == Type_Slice)
  1428. return ssa_slice_len(proc, v);
  1429. } break;
  1430. case BuiltinProc_cap: {
  1431. // cap :: proc(Type) -> int
  1432. // NOTE(bill): cap of an array is a constant expression
  1433. ssaValue *v = ssa_build_addr(proc, ce->arg_list).addr;
  1434. Type *t = get_base_type(ssa_type(v));
  1435. return ssa_slice_cap(proc, v);
  1436. } break;
  1437. case BuiltinProc_copy: {
  1438. // copy :: proc(dst, src: []Type) -> int
  1439. AstNode *dst_node = ce->arg_list;
  1440. AstNode *src_node = ce->arg_list->next;
  1441. ssaValue *dst_slice = ssa_build_expr(proc, dst_node);
  1442. ssaValue *src_slice = ssa_build_expr(proc, src_node);
  1443. Type *slice_type = get_base_type(ssa_type(dst_slice));
  1444. GB_ASSERT(slice_type->kind == Type_Slice);
  1445. Type *elem_type = slice_type->Slice.elem;
  1446. i64 size_of_elem = type_size_of(proc->module->sizes, proc->module->allocator, elem_type);
  1447. ssaValue *d = ssa_add_local_generated(proc, slice_type);
  1448. ssaValue *s = ssa_add_local_generated(proc, slice_type);
  1449. ssa_emit_store(proc, d, dst_slice);
  1450. ssa_emit_store(proc, s, src_slice);
  1451. ssaValue *dst = ssa_emit_conv(proc, ssa_slice_elem(proc, d), t_rawptr);
  1452. ssaValue *src = ssa_emit_conv(proc, ssa_slice_elem(proc, s), t_rawptr);
  1453. ssaValue *len_dst = ssa_slice_len(proc, d);
  1454. ssaValue *len_src = ssa_slice_len(proc, s);
  1455. Token lt = {Token_Lt};
  1456. ssaValue *cond = ssa_emit_comp(proc, lt, len_dst, len_src);
  1457. ssaValue *len = ssa_emit_select(proc, cond, len_dst, len_src);
  1458. Token mul = {Token_Mul};
  1459. ssaValue *elem_size = ssa_make_value_constant(proc->module->allocator, t_int,
  1460. make_exact_value_integer(size_of_elem));
  1461. ssaValue *byte_count = ssa_emit_arith(proc, mul, len, elem_size, t_int);
  1462. i32 align = cast(i32)type_align_of(proc->module->sizes, proc->module->allocator, elem_type);
  1463. b32 is_volatile = false;
  1464. ssa_emit(proc, ssa_make_instr_copy_memory(proc, dst, src, byte_count, align, is_volatile));
  1465. return len;
  1466. } break;
  1467. case BuiltinProc_append: {
  1468. // append :: proc(s: ^[]Type, item: Type) -> bool
  1469. AstNode *sptr_node = ce->arg_list;
  1470. AstNode *item_node = ce->arg_list->next;
  1471. ssaValue *slice = ssa_build_addr(proc, sptr_node).addr;
  1472. ssaValue *elem = ssa_slice_elem(proc, slice);
  1473. ssaValue *len = ssa_slice_len(proc, slice);
  1474. ssaValue *cap = ssa_slice_cap(proc, slice);
  1475. Type *elem_type = type_deref(ssa_type(elem));
  1476. ssaValue *item_value = ssa_build_expr(proc, item_node);
  1477. item_value = ssa_emit_conv(proc, item_value, elem_type);
  1478. ssaValue *item = ssa_add_local_generated(proc, elem_type);
  1479. ssa_emit_store(proc, item, item_value);
  1480. // NOTE(bill): Check if can append is possible
  1481. Token lt = {Token_Lt};
  1482. ssaValue *cond = ssa_emit_comp(proc, lt, len, cap);
  1483. ssaBlock *able = ssa_add_block(proc, NULL, make_string("builtin.append.able"));
  1484. ssaBlock *done = ssa__make_block(proc, NULL, make_string("builtin.append.done"));
  1485. ssa_emit_if(proc, cond, able, done);
  1486. proc->curr_block = able;
  1487. // Add new slice item
  1488. ssaValue *offset = ssa_emit_ptr_offset(proc, elem, len);
  1489. i64 item_size = type_size_of(proc->module->sizes, proc->module->allocator, elem_type);
  1490. ssaValue *byte_count = ssa_make_value_constant(proc->module->allocator, t_int,
  1491. make_exact_value_integer(item_size));
  1492. offset = ssa_emit_conv(proc, offset, t_rawptr);
  1493. item = ssa_emit_ptr_offset(proc, item, v_zero);
  1494. ssa_set_type(item, make_type_pointer(proc->module->allocator, ssa_type(item)));
  1495. item = ssa_emit_conv(proc, item, t_rawptr);
  1496. ssa_emit(proc, ssa_make_instr_copy_memory(proc, offset, item, byte_count, 1, false));
  1497. // Increment slice length
  1498. Token add = {Token_Add};
  1499. ssaValue *new_len = ssa_emit_arith(proc, add, len, v_one, t_int);
  1500. ssaValue *gep = ssa_emit_struct_gep(proc, slice, v_one32, t_int);
  1501. ssa_emit_store(proc, gep, new_len);
  1502. ssa_emit_jump(proc, done);
  1503. gb_array_append(proc->blocks, done);
  1504. proc->curr_block = done;
  1505. return ssa_emit_conv(proc, cond, t_bool);
  1506. } break;
  1507. case BuiltinProc_swizzle: {
  1508. ssaValue *vector = ssa_build_expr(proc, ce->arg_list);
  1509. isize index_count = ce->arg_list_count-1;
  1510. if (index_count == 0) {
  1511. return vector;
  1512. }
  1513. i32 *indices = gb_alloc_array(proc->module->allocator, i32, index_count);
  1514. isize index = 0;
  1515. for (AstNode *arg = ce->arg_list->next; arg != NULL; arg = arg->next) {
  1516. TypeAndValue *tv = type_and_value_of_expression(proc->module->info, arg);
  1517. GB_ASSERT(is_type_integer(tv->type));
  1518. GB_ASSERT(tv->value.kind == ExactValue_Integer);
  1519. indices[index++] = cast(i32)tv->value.value_integer;
  1520. }
  1521. return ssa_emit(proc, ssa_make_instr_shuffle_vector(proc, vector, indices, index_count));
  1522. } break;
  1523. case BuiltinProc_ptr_offset: {
  1524. ssaValue *ptr = ssa_build_expr(proc, ce->arg_list);
  1525. ssaValue *offset = ssa_build_expr(proc, ce->arg_list->next);
  1526. return ssa_emit_ptr_offset(proc, ptr, offset);
  1527. } break;
  1528. case BuiltinProc_ptr_sub: {
  1529. ssaValue *ptr_a = ssa_build_expr(proc, ce->arg_list);
  1530. ssaValue *ptr_b = ssa_build_expr(proc, ce->arg_list->next);
  1531. Type *ptr_type = get_base_type(ssa_type(ptr_a));
  1532. GB_ASSERT(ptr_type->kind == Type_Pointer);
  1533. isize elem_size = type_size_of(proc->module->sizes, proc->module->allocator, ptr_type->Pointer.elem);
  1534. Token sub = {Token_Sub};
  1535. ssaValue *v = ssa_emit_arith(proc, sub, ptr_a, ptr_b, t_int);
  1536. if (elem_size > 1) {
  1537. Token quo = {Token_Quo};
  1538. ssaValue *ez = ssa_make_value_constant(proc->module->allocator, t_int,
  1539. make_exact_value_integer(elem_size));
  1540. v = ssa_emit_arith(proc, quo, v, ez, t_int);
  1541. }
  1542. return v;
  1543. } break;
  1544. case BuiltinProc_slice_ptr: {
  1545. ssaValue *ptr = ssa_build_expr(proc, ce->arg_list);
  1546. ssaValue *len = ssa_build_expr(proc, ce->arg_list->next);
  1547. ssaValue *cap = len;
  1548. len = ssa_emit_conv(proc, len, t_int);
  1549. if (ce->arg_list->next->next != NULL) {
  1550. cap = ssa_build_expr(proc, ce->arg_list->next->next);
  1551. cap = ssa_emit_conv(proc, cap, t_int);
  1552. }
  1553. Type *slice_type = make_type_slice(proc->module->allocator, type_deref(ssa_type(ptr)));
  1554. ssaValue *slice = ssa_add_local_generated(proc, slice_type);
  1555. ssa_emit_store(proc, ssa_emit_struct_gep(proc, slice, v_zero32, ssa_type(ptr)), ptr);
  1556. ssa_emit_store(proc, ssa_emit_struct_gep(proc, slice, v_one32, t_int), len);
  1557. ssa_emit_store(proc, ssa_emit_struct_gep(proc, slice, v_two32, t_int), cap);
  1558. return ssa_emit_load(proc, slice);
  1559. } break;
  1560. }
  1561. }
  1562. }
  1563. // NOTE(bill): Regular call
  1564. ssaValue *value = ssa_build_expr(proc, ce->proc);
  1565. Type *proc_type_ = get_base_type(ssa_type(value));
  1566. GB_ASSERT(proc_type_->kind == Type_Proc);
  1567. auto *type = &proc_type_->Proc;
  1568. isize arg_index = 0;
  1569. isize arg_count = type->param_count;
  1570. ssaValue **args = gb_alloc_array(proc->module->allocator, ssaValue *, arg_count);
  1571. for (AstNode *arg = ce->arg_list; arg != NULL; arg = arg->next) {
  1572. ssaValue *a = ssa_build_expr(proc, arg);
  1573. Type *at = ssa_type(a);
  1574. if (at->kind == Type_Tuple) {
  1575. for (isize i = 0; i < at->Tuple.variable_count; i++) {
  1576. Entity *e = at->Tuple.variables[i];
  1577. ssaValue *v = ssa_emit_struct_ev(proc, a, i, e->type);
  1578. args[arg_index++] = v;
  1579. }
  1580. } else {
  1581. args[arg_index++] = a;
  1582. }
  1583. }
  1584. auto *pt = &proc_type_->Proc.params->Tuple;
  1585. for (isize i = 0; i < arg_count; i++) {
  1586. args[i] = ssa_emit_conv(proc, args[i], pt->variables[i]->type);
  1587. }
  1588. ssaValue *call = ssa_make_instr_call(proc, value, args, arg_count, type->results);
  1589. return ssa_emit(proc, call);
  1590. case_end;
  1591. case_ast_node(se, SliceExpr, expr);
  1592. return ssa_emit_load(proc, ssa_build_addr(proc, expr).addr);
  1593. case_end;
  1594. case_ast_node(ie, IndexExpr, expr);
  1595. return ssa_emit_load(proc, ssa_build_addr(proc, expr).addr);
  1596. case_end;
  1597. }
  1598. GB_PANIC("Unexpected expression: %.*s", LIT(ast_node_strings[expr->kind]));
  1599. return NULL;
  1600. }
  1601. ssaValue *ssa_build_expr(ssaProcedure *proc, AstNode *expr) {
  1602. expr = unparen_expr(expr);
  1603. TypeAndValue *tv = map_get(&proc->module->info->types, hash_pointer(expr));
  1604. GB_ASSERT_NOT_NULL(tv);
  1605. if (tv->value.kind != ExactValue_Invalid) {
  1606. if (tv->value.kind == ExactValue_String) {
  1607. // TODO(bill): Optimize by not allocating everytime
  1608. ssaValue *array = ssa_add_global_string_array(proc, tv->value);
  1609. ssaValue *elem = ssa_array_elem(proc, array);
  1610. return ssa_emit_load(proc, ssa_emit_string(proc, elem, ssa_array_len(proc, array)));
  1611. }
  1612. return ssa_make_value_constant(proc->module->allocator, tv->type, tv->value);
  1613. }
  1614. ssaValue *value = NULL;
  1615. if (tv->mode == Addressing_Variable) {
  1616. ssaAddr addr = ssa_build_addr(proc, expr);
  1617. value = ssa_lvalue_load(proc, addr);
  1618. } else {
  1619. value = ssa_build_single_expr(proc, expr, tv);
  1620. }
  1621. return value;
  1622. }
  1623. ssaValue *ssa_emit_deep_field_gep(ssaProcedure *proc, Type *type, ssaValue *e, Selection sel) {
  1624. GB_ASSERT(gb_array_count(sel.index) > 0);
  1625. gb_for_array(i, sel.index) {
  1626. isize index = sel.index[i];
  1627. if (is_type_pointer(type)) {
  1628. type = type_deref(type);
  1629. e = ssa_emit_load(proc, e);
  1630. e = ssa_emit_ptr_offset(proc, e, v_zero);
  1631. ssa_set_type(e, type);
  1632. }
  1633. type = get_base_type(type);
  1634. if (type->kind == Type_Union) {
  1635. ssaValue *v = ssa_emit_ptr_offset(proc, e, v_zero);
  1636. ssa_set_type(v, make_type_pointer(proc->module->allocator, type));
  1637. type = type->Union.fields[index]->type;
  1638. e = ssa_emit_conv(proc, v, make_type_pointer(proc->module->allocator, type));
  1639. e = ssa_emit_ptr_offset(proc, e, v_zero);
  1640. ssa_set_type(e, type);
  1641. } else {
  1642. type = type->Union.fields[index]->type;
  1643. e = ssa_emit_struct_gep(proc, e, index, type);
  1644. }
  1645. }
  1646. return e;
  1647. }
  1648. ssaAddr ssa_build_addr(ssaProcedure *proc, AstNode *expr) {
  1649. switch (expr->kind) {
  1650. case_ast_node(i, Ident, expr);
  1651. if (ssa_is_blank_ident(expr)) {
  1652. ssaAddr val = {};
  1653. return val;
  1654. }
  1655. Entity *e = entity_of_ident(proc->module->info, expr);
  1656. ssaValue *v = NULL;
  1657. ssaValue **found = map_get(&proc->module->values, hash_pointer(e));
  1658. if (found) {
  1659. v = *found;
  1660. } else {
  1661. GB_PANIC("Unknown value: %s, entity: %p\n", expr_to_string(expr), e);
  1662. }
  1663. return ssa_make_addr(v, expr);
  1664. case_end;
  1665. case_ast_node(pe, ParenExpr, expr);
  1666. return ssa_build_addr(proc, unparen_expr(expr));
  1667. case_end;
  1668. case_ast_node(se, SelectorExpr, expr);
  1669. Type *type = get_base_type(type_of_expr(proc->module->info, se->expr));
  1670. Selection sel = lookup_field(type, unparen_expr(se->selector)->Ident.token.string);
  1671. GB_ASSERT(sel.entity != NULL);
  1672. ssaValue *e = ssa_build_addr(proc, se->expr).addr;
  1673. e = ssa_emit_deep_field_gep(proc, type, e, sel);
  1674. return ssa_make_addr(e, expr);
  1675. case_end;
  1676. case_ast_node(ue, UnaryExpr, expr);
  1677. switch (ue->op.kind) {
  1678. case Token_Pointer: {
  1679. ssaAddr lval = ssa_build_addr(proc, ue->expr);
  1680. // ssaValue *v = ssa_emit_zero_gep(proc, lval.addr);
  1681. // Type *t = ssa_type(lval.addr);
  1682. // ssa_set_type(lval.addr, make_type_pointer(proc->module->allocator, t));
  1683. // return ssa_make_addr(v, expr);
  1684. return lval;
  1685. }
  1686. default:
  1687. GB_PANIC("Invalid unary expression for ssa_build_addr");
  1688. }
  1689. case_end;
  1690. case_ast_node(be, BinaryExpr, expr);
  1691. switch (be->op.kind) {
  1692. case Token_as: {
  1693. // HACK(bill): Do have to make new variable to do this?
  1694. // NOTE(bill): Needed for dereference of pointer conversion
  1695. Type *type = type_of_expr(proc->module->info, expr);
  1696. ssaValue *v = ssa_add_local_generated(proc, type);
  1697. ssa_emit_store(proc, v, ssa_emit_conv(proc, ssa_build_expr(proc, be->left), type));
  1698. return ssa_make_addr(v, expr);
  1699. }
  1700. case Token_transmute: {
  1701. // HACK(bill): Do have to make new variable to do this?
  1702. // NOTE(bill): Needed for dereference of pointer conversion
  1703. Type *type = type_of_expr(proc->module->info, expr);
  1704. ssaValue *v = ssa_add_local_generated(proc, type);
  1705. ssa_emit_store(proc, v, ssa_emit_transmute(proc, ssa_build_expr(proc, be->left), type));
  1706. return ssa_make_addr(v, expr);
  1707. }
  1708. default:
  1709. GB_PANIC("Invalid binary expression for ssa_build_addr: %.*s\n", LIT(be->op.string));
  1710. break;
  1711. }
  1712. case_end;
  1713. case_ast_node(ie, IndexExpr, expr);
  1714. ssaValue *v = NULL;
  1715. Type *t = get_base_type(type_of_expr(proc->module->info, ie->expr));
  1716. ssaValue *elem = NULL;
  1717. switch (t->kind) {
  1718. case Type_Vector: {
  1719. // HACK(bill): Fix how lvalues for vectors work
  1720. ssaValue *vector = ssa_build_addr(proc, ie->expr).addr;
  1721. ssaValue *index = ssa_emit_conv(proc, ssa_build_expr(proc, ie->index), t_int);
  1722. return ssa_make_addr_vector(vector, index, expr);
  1723. } break;
  1724. case Type_Array: {
  1725. ssaValue *array = ssa_build_addr(proc, ie->expr).addr;
  1726. elem = ssa_array_elem(proc, array);
  1727. } break;
  1728. case Type_Slice: {
  1729. ssaValue *slice = ssa_build_addr(proc, ie->expr).addr;
  1730. elem = ssa_slice_elem(proc, slice);
  1731. } break;
  1732. case Type_Basic: { // Basic_string
  1733. TypeAndValue *tv = map_get(&proc->module->info->types, hash_pointer(ie->expr));
  1734. if (tv->mode == Addressing_Constant) {
  1735. ssaValue *array = ssa_add_global_string_array(proc, tv->value);
  1736. elem = ssa_array_elem(proc, array);
  1737. } else {
  1738. elem = ssa_string_elem(proc, ssa_build_addr(proc, ie->expr).addr);
  1739. }
  1740. } break;
  1741. case Type_Pointer: {
  1742. ssaValue *array = ssa_emit_load(proc, ssa_build_expr(proc, ie->expr));
  1743. elem = ssa_array_elem(proc, array);
  1744. } break;
  1745. }
  1746. ssaValue *index = ssa_emit_conv(proc, ssa_build_expr(proc, ie->index), t_int);
  1747. v = ssa_emit_ptr_offset(proc, elem, index);
  1748. Type *lval_type = type_deref(ssa_type(v));
  1749. // gb_printf("%s\n", type_to_string(lval_type));
  1750. ssa_set_type(v, lval_type);
  1751. return ssa_make_addr(v, expr);
  1752. case_end;
  1753. case_ast_node(se, SliceExpr, expr);
  1754. ssaValue *low = NULL;
  1755. ssaValue *high = NULL;
  1756. ssaValue *max = NULL;
  1757. if (se->low != NULL) low = ssa_build_expr(proc, se->low);
  1758. if (se->high != NULL) high = ssa_build_expr(proc, se->high);
  1759. if (se->triple_indexed) max = ssa_build_expr(proc, se->max);
  1760. Type *type = type_of_expr(proc->module->info, expr);
  1761. switch (type->kind) {
  1762. case Type_Slice:
  1763. case Type_Array: {
  1764. ssaValue *base = ssa_build_addr(proc, se->expr).addr;
  1765. return ssa_make_addr(ssa_emit_slice(proc, type, base, low, high, max), expr);
  1766. } break;
  1767. case Type_Basic: {
  1768. // NOTE(bill): max is not needed
  1769. ssaValue *base = ssa_build_addr(proc, se->expr).addr;
  1770. return ssa_make_addr(ssa_emit_substring(proc, base, low, high), expr);
  1771. } break;
  1772. }
  1773. GB_PANIC("Unknown slicable type");
  1774. case_end;
  1775. case_ast_node(de, DerefExpr, expr);
  1776. ssaValue *e = ssa_build_expr(proc, de->expr);
  1777. ssaValue *gep = ssa_emit_zero_gep(proc, e);
  1778. // HACK(bill): need to deref here as stack variables are of type pointer
  1779. // and addresses are already pointers
  1780. // TODO(bill): Completely redo the type system for SSA
  1781. Type *t = type_deref(ssa_type(e));
  1782. gep->Instr.GetElementPtr.result_type = t;
  1783. gep->Instr.GetElementPtr.elem_type = t;
  1784. return ssa_make_addr(gep, expr);
  1785. case_end;
  1786. }
  1787. TokenPos token_pos = ast_node_token(expr).pos;
  1788. GB_PANIC("Unexpected address expression\n"
  1789. "\tAstNode: %.*s @ "
  1790. "%.*s(%td:%td)\n",
  1791. LIT(ast_node_strings[expr->kind]),
  1792. LIT(token_pos.file), token_pos.line, token_pos.column);
  1793. return ssa_make_addr(NULL, NULL);
  1794. }
  1795. void ssa_build_assign_op(ssaProcedure *proc, ssaAddr lhs, ssaValue *value, Token op) {
  1796. ssaValue *old_value = ssa_lvalue_load(proc, lhs);
  1797. ssaValue *change = ssa_emit_conv(proc, value, ssa_type(old_value));
  1798. ssaValue *new_value = ssa_emit_arith(proc, op, old_value, change, ssa_type(old_value));
  1799. ssa_lvalue_store(proc, lhs, new_value);
  1800. }
  1801. void ssa_build_cond(ssaProcedure *proc, AstNode *cond, ssaBlock *true_block, ssaBlock *false_block) {
  1802. switch (cond->kind) {
  1803. case_ast_node(pe, ParenExpr, cond);
  1804. ssa_build_cond(proc, pe->expr, true_block, false_block);
  1805. return;
  1806. case_end;
  1807. case_ast_node(ue, UnaryExpr, cond);
  1808. if (ue->op.kind == Token_Not) {
  1809. ssa_build_cond(proc, ue->expr, false_block, true_block);
  1810. return;
  1811. }
  1812. case_end;
  1813. case_ast_node(be, BinaryExpr, cond);
  1814. if (be->op.kind == Token_CmpAnd) {
  1815. ssaBlock *block = ssa_add_block(proc, NULL, make_string("cmp-and"));
  1816. ssa_build_cond(proc, be->left, block, false_block);
  1817. proc->curr_block = block;
  1818. ssa_build_cond(proc, be->right, true_block, false_block);
  1819. return;
  1820. } else if (be->op.kind == Token_CmpOr) {
  1821. ssaBlock *block = ssa_add_block(proc, NULL, make_string("cmp-or"));
  1822. ssa_build_cond(proc, be->left, true_block, block);
  1823. proc->curr_block = block;
  1824. ssa_build_cond(proc, be->right, true_block, false_block);
  1825. return;
  1826. }
  1827. case_end;
  1828. }
  1829. ssaValue *expr = ssa_build_expr(proc, cond);
  1830. ssa_emit_if(proc, expr, true_block, false_block);
  1831. }
  1832. void ssa_build_stmt_list(ssaProcedure *proc, AstNode *list) {
  1833. for (AstNode *stmt = list ; stmt != NULL; stmt = stmt->next)
  1834. ssa_build_stmt(proc, stmt);
  1835. }
  1836. void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
  1837. switch (node->kind) {
  1838. case_ast_node(bs, EmptyStmt, node);
  1839. case_end;
  1840. case_ast_node(vd, VarDecl, node);
  1841. if (vd->kind == Declaration_Mutable) {
  1842. if (vd->name_count == vd->value_count) { // 1:1 assigment
  1843. gbArray(ssaAddr) lvals;
  1844. gbArray(ssaValue *) inits;
  1845. gb_array_init_reserve(lvals, gb_heap_allocator(), vd->name_count);
  1846. gb_array_init_reserve(inits, gb_heap_allocator(), vd->name_count);
  1847. defer (gb_array_free(lvals));
  1848. defer (gb_array_free(inits));
  1849. for (AstNode *name = vd->name_list; name != NULL; name = name->next) {
  1850. ssaAddr lval = ssa_make_addr(NULL, NULL);
  1851. if (!ssa_is_blank_ident(name)) {
  1852. ssa_add_local_for_identifier(proc, name);
  1853. lval = ssa_build_addr(proc, name);
  1854. GB_ASSERT(lval.addr != NULL);
  1855. }
  1856. gb_array_append(lvals, lval);
  1857. }
  1858. for (AstNode *value = vd->value_list; value != NULL; value = value->next) {
  1859. ssaValue *init = ssa_build_expr(proc, value);
  1860. gb_array_append(inits, init);
  1861. }
  1862. gb_for_array(i, inits) {
  1863. ssaValue *v = ssa_emit_conv(proc, inits[i], ssa_type(lvals[i]));
  1864. ssa_lvalue_store(proc, lvals[i], v);
  1865. }
  1866. } else if (vd->value_count == 0) { // declared and zero-initialized
  1867. for (AstNode *name = vd->name_list; name != NULL; name = name->next) {
  1868. if (!ssa_is_blank_ident(name)) {
  1869. ssa_add_local_for_identifier(proc, name);
  1870. }
  1871. }
  1872. } else { // Tuple(s)
  1873. gbArray(ssaAddr) lvals;
  1874. gbArray(ssaValue *) inits;
  1875. gb_array_init_reserve(lvals, gb_heap_allocator(), vd->name_count);
  1876. gb_array_init_reserve(inits, gb_heap_allocator(), vd->name_count);
  1877. defer (gb_array_free(lvals));
  1878. defer (gb_array_free(inits));
  1879. for (AstNode *name = vd->name_list; name != NULL; name = name->next) {
  1880. ssaAddr lval = ssa_make_addr(NULL, NULL);
  1881. if (!ssa_is_blank_ident(name)) {
  1882. ssa_add_local_for_identifier(proc, name);
  1883. lval = ssa_build_addr(proc, name);
  1884. }
  1885. gb_array_append(lvals, lval);
  1886. }
  1887. for (AstNode *value = vd->value_list; value != NULL; value = value->next) {
  1888. ssaValue *init = ssa_build_expr(proc, value);
  1889. Type *t = ssa_type(init);
  1890. if (t->kind == Type_Tuple) {
  1891. for (isize i = 0; i < t->Tuple.variable_count; i++) {
  1892. Entity *e = t->Tuple.variables[i];
  1893. ssaValue *v = ssa_emit_struct_ev(proc, init, i, e->type);
  1894. gb_array_append(inits, v);
  1895. }
  1896. } else {
  1897. gb_array_append(inits, init);
  1898. }
  1899. }
  1900. gb_for_array(i, inits) {
  1901. ssaValue *v = ssa_emit_conv(proc, inits[i], ssa_type(lvals[i]));
  1902. ssa_lvalue_store(proc, lvals[i], v);
  1903. }
  1904. }
  1905. }
  1906. case_end;
  1907. case_ast_node(pd, ProcDecl, node);
  1908. if (proc->children == NULL) {
  1909. gb_array_init(proc->children, gb_heap_allocator());
  1910. }
  1911. if (pd->body != NULL) {
  1912. // NOTE(bill): Generate a new name
  1913. // parent$name-guid
  1914. String pd_name = pd->name->Ident.token.string;
  1915. isize name_len = proc->name.len + 1 + pd_name.len + 1 + 10 + 1;
  1916. u8 *name_text = gb_alloc_array(proc->module->allocator, u8, name_len);
  1917. i32 guid = cast(i32)gb_array_count(proc->children);
  1918. name_len = gb_snprintf(cast(char *)name_text, name_len, "%.*s$%.*s-%d", LIT(proc->name), LIT(pd_name), guid);
  1919. String name = make_string(name_text, name_len-1);
  1920. Entity **found = map_get(&proc->module->info->definitions, hash_pointer(pd->name));
  1921. GB_ASSERT_MSG(found != NULL, "Unable to find: %.*s", LIT(pd->name->Ident.token.string));
  1922. Entity *e = *found;
  1923. ssaValue *value = ssa_make_value_procedure(proc->module->allocator,
  1924. proc->module, e->type, pd->type, pd->body, name);
  1925. value->Proc.tags = pd->tags;
  1926. ssa_module_add_value(proc->module, e, value);
  1927. gb_array_append(proc->children, &value->Proc);
  1928. ssa_build_proc(value, proc);
  1929. } else {
  1930. String name = pd->name->Ident.token.string;
  1931. if (pd->foreign_name.len > 0) {
  1932. name = pd->foreign_name;
  1933. }
  1934. Entity **found = map_get(&proc->module->info->definitions, hash_pointer(pd->name));
  1935. GB_ASSERT(found != NULL);
  1936. Entity *e = *found;
  1937. ssaValue *value = ssa_make_value_procedure(proc->module->allocator,
  1938. proc->module, e->type, pd->type, pd->body, name);
  1939. ssa_module_add_value(proc->module, e, value);
  1940. gb_array_append(proc->children, &value->Proc);
  1941. ssa_build_proc(value, proc);
  1942. }
  1943. case_end;
  1944. case_ast_node(td, TypeDecl, node);
  1945. // NOTE(bill): Generate a new name
  1946. // parent_proc.name-guid
  1947. String td_name = td->name->Ident.token.string;
  1948. isize name_len = proc->name.len + 1 + td_name.len + 1 + 10 + 1;
  1949. u8 *name_text = gb_alloc_array(proc->module->allocator, u8, name_len);
  1950. i32 guid = cast(i32)gb_array_count(proc->module->nested_type_names);
  1951. name_len = gb_snprintf(cast(char *)name_text, name_len, "%.*s.%.*s-%d", LIT(proc->name), LIT(td_name), guid);
  1952. String name = make_string(name_text, name_len-1);
  1953. Entity **found = map_get(&proc->module->info->definitions, hash_pointer(td->name));
  1954. GB_ASSERT(found != NULL);
  1955. Entity *e = *found;
  1956. ssaValue *value = ssa_make_value_type_name(proc->module->allocator,
  1957. name, e->type);
  1958. // HACK(bill): Override name of type so printer prints it correctly
  1959. e->type->Named.name = name;
  1960. ssa_module_add_value(proc->module, e, value);
  1961. gb_array_append(proc->module->nested_type_names, value);
  1962. case_end;
  1963. case_ast_node(ids, IncDecStmt, node);
  1964. Token op = ids->op;
  1965. if (op.kind == Token_Increment) {
  1966. op.kind = Token_Add;
  1967. } else if (op.kind == Token_Decrement) {
  1968. op.kind = Token_Sub;
  1969. }
  1970. ssaAddr lval = ssa_build_addr(proc, ids->expr);
  1971. ssaValue *one = ssa_emit_conv(proc, v_one, ssa_type(lval));
  1972. ssa_build_assign_op(proc, lval, one, op);
  1973. case_end;
  1974. case_ast_node(as, AssignStmt, node);
  1975. switch (as->op.kind) {
  1976. case Token_Eq: {
  1977. gbArray(ssaAddr) lvals;
  1978. gb_array_init(lvals, gb_heap_allocator());
  1979. defer (gb_array_free(lvals));
  1980. for (AstNode *lhs = as->lhs_list;
  1981. lhs != NULL;
  1982. lhs = lhs->next) {
  1983. ssaAddr lval = {};
  1984. if (!ssa_is_blank_ident(lhs)) {
  1985. lval = ssa_build_addr(proc, lhs);
  1986. }
  1987. gb_array_append(lvals, lval);
  1988. }
  1989. if (as->lhs_count == as->rhs_count) {
  1990. if (as->lhs_count == 1) {
  1991. AstNode *rhs = as->rhs_list;
  1992. ssaValue *init = ssa_build_expr(proc, rhs);
  1993. ssa_lvalue_store(proc, lvals[0], init);
  1994. } else {
  1995. gbArray(ssaValue *) inits;
  1996. gb_array_init_reserve(inits, gb_heap_allocator(), gb_array_count(lvals));
  1997. defer (gb_array_free(inits));
  1998. for (AstNode *rhs = as->rhs_list; rhs != NULL; rhs = rhs->next) {
  1999. ssaValue *init = ssa_build_expr(proc, rhs);
  2000. gb_array_append(inits, init);
  2001. }
  2002. gb_for_array(i, inits) {
  2003. ssa_lvalue_store(proc, lvals[i], inits[i]);
  2004. }
  2005. }
  2006. } else {
  2007. gbArray(ssaValue *) inits;
  2008. gb_array_init_reserve(inits, gb_heap_allocator(), gb_array_count(lvals));
  2009. defer (gb_array_free(inits));
  2010. for (AstNode *rhs = as->rhs_list; rhs != NULL; rhs = rhs->next) {
  2011. ssaValue *init = ssa_build_expr(proc, rhs);
  2012. Type *t = ssa_type(init);
  2013. // TODO(bill): refactor for code reuse as this is repeated a bit
  2014. if (t->kind == Type_Tuple) {
  2015. for (isize i = 0; i < t->Tuple.variable_count; i++) {
  2016. Entity *e = t->Tuple.variables[i];
  2017. ssaValue *v = ssa_emit_struct_ev(proc, init, i, e->type);
  2018. gb_array_append(inits, v);
  2019. }
  2020. } else {
  2021. gb_array_append(inits, init);
  2022. }
  2023. }
  2024. gb_for_array(i, inits) {
  2025. ssa_lvalue_store(proc, lvals[i], inits[i]);
  2026. }
  2027. }
  2028. } break;
  2029. default: {
  2030. // NOTE(bill): Only 1 += 1 is allowed, no tuples
  2031. // +=, -=, etc
  2032. Token op = as->op;
  2033. i32 kind = op.kind;
  2034. kind += Token_Add - Token_AddEq; // Convert += to +
  2035. op.kind = cast(TokenKind)kind;
  2036. ssaAddr lhs = ssa_build_addr(proc, as->lhs_list);
  2037. ssaValue *value = ssa_build_expr(proc, as->rhs_list);
  2038. ssa_build_assign_op(proc, lhs, value, op);
  2039. } break;
  2040. }
  2041. case_end;
  2042. case_ast_node(es, ExprStmt, node);
  2043. // NOTE(bill): No need to use return value
  2044. ssa_build_expr(proc, es->expr);
  2045. case_end;
  2046. case_ast_node(bs, BlockStmt, node);
  2047. proc->scope_index++;
  2048. ssa_build_stmt_list(proc, bs->list);
  2049. ssa_emit_defer_stmts(proc, ssaDefer_Default, NULL);
  2050. proc->scope_index--;
  2051. case_end;
  2052. case_ast_node(ds, DeferStmt, node);
  2053. isize scope_index = proc->scope_index;
  2054. if (ds->stmt->kind == AstNode_BlockStmt)
  2055. scope_index--;
  2056. ssaDefer d = {ds->stmt, scope_index, proc->curr_block};
  2057. gb_array_append(proc->defer_stmts, d);
  2058. case_end;
  2059. case_ast_node(rs, ReturnStmt, node);
  2060. ssaValue *v = NULL;
  2061. auto *return_type_tuple = &proc->type->Proc.results->Tuple;
  2062. isize return_count = proc->type->Proc.result_count;
  2063. if (rs->result_count == 1 && return_count > 1) {
  2064. GB_PANIC("ReturnStmt tuple return statement");
  2065. } else if (return_count == 1) {
  2066. Entity *e = return_type_tuple->variables[0];
  2067. v = ssa_build_expr(proc, rs->result_list);
  2068. ssa_set_type(v, e->type);
  2069. } else if (return_count == 0) {
  2070. // No return values
  2071. } else {
  2072. // 1:1 multiple return values
  2073. Type *ret_type = proc->type->Proc.results;
  2074. v = ssa_add_local_generated(proc, ret_type);
  2075. isize i = 0;
  2076. AstNode *r = rs->result_list;
  2077. for (;
  2078. i < return_count && r != NULL;
  2079. i++, r = r->next) {
  2080. Entity *e = return_type_tuple->variables[i];
  2081. ssaValue *res = ssa_build_expr(proc, r);
  2082. ssa_set_type(res, e->type);
  2083. ssaValue *field = ssa_emit_struct_gep(proc, v, i, e->type);
  2084. ssa_emit_store(proc, field, res);
  2085. }
  2086. v = ssa_emit_load(proc, v);
  2087. }
  2088. ssa_emit_ret(proc, v);
  2089. case_end;
  2090. case_ast_node(is, IfStmt, node);
  2091. if (is->init != NULL) {
  2092. ssaBlock *init = ssa_add_block(proc, node, make_string("if.init"));
  2093. ssa_emit_jump(proc, init);
  2094. proc->curr_block = init;
  2095. ssa_build_stmt(proc, is->init);
  2096. }
  2097. ssaBlock *then = ssa_add_block(proc, node, make_string("if.then"));
  2098. ssaBlock *done = ssa__make_block(proc, node, make_string("if.done")); // NOTE(bill): Append later
  2099. ssaBlock *else_ = done;
  2100. if (is->else_stmt != NULL) {
  2101. else_ = ssa_add_block(proc, is->else_stmt, make_string("if.else"));
  2102. }
  2103. ssa_build_cond(proc, is->cond, then, else_);
  2104. proc->curr_block = then;
  2105. proc->scope_index++;
  2106. ssa_build_stmt(proc, is->body);
  2107. ssa_emit_defer_stmts(proc, ssaDefer_Default, NULL);
  2108. proc->scope_index--;
  2109. ssa_emit_jump(proc, done);
  2110. if (is->else_stmt != NULL) {
  2111. proc->curr_block = else_;
  2112. proc->scope_index++;
  2113. ssa_build_stmt(proc, is->else_stmt);
  2114. ssa_emit_defer_stmts(proc, ssaDefer_Default, NULL);
  2115. proc->scope_index--;
  2116. ssa_emit_jump(proc, done);
  2117. }
  2118. gb_array_append(proc->blocks, done);
  2119. proc->curr_block = done;
  2120. case_end;
  2121. case_ast_node(fs, ForStmt, node);
  2122. if (fs->init != NULL) {
  2123. ssaBlock *init = ssa_add_block(proc, node, make_string("for.init"));
  2124. ssa_emit_jump(proc, init);
  2125. proc->curr_block = init;
  2126. ssa_build_stmt(proc, fs->init);
  2127. }
  2128. ssaBlock *body = ssa_add_block(proc, node, make_string("for.body"));
  2129. ssaBlock *done = ssa__make_block(proc, node, make_string("for.done")); // NOTE(bill): Append later
  2130. ssaBlock *loop = body;
  2131. if (fs->cond != NULL) {
  2132. loop = ssa_add_block(proc, node, make_string("for.loop"));
  2133. }
  2134. ssaBlock *cont = loop;
  2135. if (fs->post != NULL) {
  2136. cont = ssa_add_block(proc, node, make_string("for.post"));
  2137. }
  2138. ssa_emit_jump(proc, loop);
  2139. proc->curr_block = loop;
  2140. if (loop != body) {
  2141. ssa_build_cond(proc, fs->cond, body, done);
  2142. proc->curr_block = body;
  2143. }
  2144. ssa_push_target_list(proc, done, cont, NULL);
  2145. proc->scope_index++;
  2146. ssa_build_stmt(proc, fs->body);
  2147. ssa_emit_defer_stmts(proc, ssaDefer_Default, NULL);
  2148. proc->scope_index--;
  2149. ssa_pop_target_list(proc);
  2150. ssa_emit_jump(proc, cont);
  2151. if (fs->post != NULL) {
  2152. proc->curr_block = cont;
  2153. ssa_build_stmt(proc, fs->post);
  2154. ssa_emit_jump(proc, loop);
  2155. }
  2156. gb_array_append(proc->blocks, done);
  2157. proc->curr_block = done;
  2158. case_end;
  2159. case_ast_node(bs, BranchStmt, node);
  2160. ssaBlock *block = NULL;
  2161. switch (bs->token.kind) {
  2162. case Token_break: {
  2163. for (ssaTargetList *t = proc->target_list; t != NULL && block == NULL; t = t->prev) {
  2164. block = t->break_;
  2165. }
  2166. } break;
  2167. case Token_continue: {
  2168. for (ssaTargetList *t = proc->target_list; t != NULL && block == NULL; t = t->prev) {
  2169. block = t->continue_;
  2170. }
  2171. } break;
  2172. case Token_fallthrough: {
  2173. for (ssaTargetList *t = proc->target_list; t != NULL && block == NULL; t = t->prev) {
  2174. block = t->fallthrough_;
  2175. }
  2176. } break;
  2177. }
  2178. if (block != NULL && bs->token.kind != Token_fallthrough) {
  2179. ssa_emit_defer_stmts(proc, ssaDefer_Branch, block);
  2180. }
  2181. ssa_emit_jump(proc, block);
  2182. ssa_emit_unreachable(proc);
  2183. case_end;
  2184. }
  2185. }
  2186. void ssa_emit_startup_runtime(ssaProcedure *proc) {
  2187. GB_ASSERT(proc->parent == NULL && are_strings_equal(proc->name, make_string("main")));
  2188. ssa_emit(proc, ssa_alloc_instr(proc, ssaInstr_StartupRuntime));
  2189. }
  2190. void ssa_insert_code_before_proc(ssaProcedure* proc, ssaProcedure *parent) {
  2191. if (parent == NULL) {
  2192. if (are_strings_equal(proc->name, make_string("main"))) {
  2193. ssa_emit_startup_runtime(proc);
  2194. }
  2195. }
  2196. }
  2197. void ssa_build_proc(ssaValue *value, ssaProcedure *parent) {
  2198. ssaProcedure *proc = &value->Proc;
  2199. proc->parent = parent;
  2200. if (proc->body != NULL) {
  2201. ssa_begin_procedure_body(proc);
  2202. ssa_insert_code_before_proc(proc, parent);
  2203. ssa_build_stmt(proc, proc->body);
  2204. ssa_end_procedure_body(proc);
  2205. }
  2206. }