llvmdef.pas 43 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109
  1. {
  2. Copyright (c) 2013 by Jonas Maebe
  3. This unit implements some LLVM type helper routines.
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15. ****************************************************************************
  16. }
  17. {$i fpcdefs.inc}
  18. unit llvmdef;
  19. interface
  20. uses
  21. cclasses,globtype,
  22. aasmbase,
  23. parabase,
  24. symconst,symbase,symtype,symdef,
  25. llvmbase;
  26. type
  27. { there are three different circumstances in which procdefs are used:
  28. a) definition of a procdef that's implemented in the current module
  29. b) declaration of an external routine that's called in the current one
  30. c) alias declaration of a procdef implemented in the current module
  31. d) defining a procvar type
  32. The main differences between the contexts are:
  33. a) information about sign extension of result type, proc name, parameter names & sign-extension info & types
  34. b) information about sign extension of result type, proc name, no parameter names, with parameter sign-extension info & types
  35. c) no information about sign extension of result type, proc name, no parameter names, no information about sign extension of parameters, parameter types
  36. d) no information about sign extension of result type, no proc name, no parameter names, no information about sign extension of parameters, parameter types
  37. }
  38. tllvmprocdefdecltype = (lpd_def,lpd_decl,lpd_alias,lpd_procvar);
  39. { returns the identifier to use as typename for a def in llvm (llvm only
  40. allows naming struct types) -- only supported for tabstractrecorddef
  41. descendantds and complex procvars }
  42. function llvmtypeidentifier(def: tdef): TSymStr;
  43. { encode a type into the internal format used by LLVM (for a type
  44. declaration) }
  45. function llvmencodetypedecl(def: tdef): TSymStr;
  46. { same as above, but use a type name if possible (for any use) }
  47. function llvmencodetypename(def: tdef): TSymStr;
  48. { encode a procdef/procvardef into the internal format used by LLVM }
  49. function llvmencodeproctype(def: tabstractprocdef; const customname: TSymStr; pddecltype: tllvmprocdefdecltype): TSymStr;
  50. { incremental version of the above }
  51. procedure llvmaddencodedproctype(def: tabstractprocdef; const customname: TSymStr; pddecltype: tllvmprocdefdecltype; var encodedstr: TSymStr);
  52. { function result types may have to be represented differently, e.g. a
  53. record consisting of 4 longints must be returned as a record consisting of
  54. two int64's on x86-64. This function is used to create (and reuse)
  55. temporary recorddefs for such purposes.}
  56. function llvmgettemprecorddef(const fieldtypes: array of tdef; packrecords, recordalignmin: shortint): trecorddef;
  57. { get the llvm type corresponding to a parameter, e.g. a record containing
  58. two integer int64 for an arbitrary record split over two individual int64
  59. parameters, or an int32 for an int16 parameter on a platform that requires
  60. such parameters to be zero/sign extended. The second parameter can be used
  61. to get the type before zero/sign extension, as e.g. required to generate
  62. function declarations. }
  63. function llvmgetcgparadef(const cgpara: tcgpara; beforevalueext: boolean; callercallee: tcallercallee): tdef;
  64. { can be used to extract the value extension info from acgpara. Pass in
  65. the def of the cgpara as first parameter and a local variable holding
  66. a copy of the def of the location (value extension only makes sense for
  67. ordinal parameters that are smaller than a single location). The routine
  68. will return the def of the location without sign extension (if applicable)
  69. and the kind of sign extension that was originally performed in the
  70. signext parameter }
  71. procedure llvmextractvalueextinfo(paradef: tdef; var paralocdef: tdef; out signext: tllvmvalueextension);
  72. { returns whether a paraloc should be translated into an llvm "byval"
  73. parameter. These are declared as pointers to a particular type, but
  74. usually turned into copies onto the stack. The exact behaviour for
  75. parameters that should be passed in registers is undefined and depends on
  76. the platform, and furthermore this modifier sometimes inhibits
  77. optimizations. As a result,we only use it for aggregate parameters of
  78. which we know that they should be passed on the stack }
  79. function llvmbyvalparaloc(paraloc: pcgparalocation): boolean;
  80. { returns whether a def is representated by an aggregate type in llvm
  81. (struct, array) }
  82. function llvmaggregatetype(def: tdef): boolean;
  83. function llvmconvop(var fromsize, tosize: tdef; inregs: boolean): tllvmop;
  84. { mangle a global identifier so that it's recognised by LLVM as a global
  85. (in the sense of module-global) label and so that it won't mangle the
  86. name further according to platform conventions (we already did that) }
  87. function llvmmangledname(const s: TSymStr): TSymStr;
  88. { convert a parameter attribute to a string. Depending on the target
  89. LLVM version, we may have to add the dereferenced parameter type as well }
  90. function llvmparatypeattr(const attr: TSymStr; paradef: tdef; strippointer: boolean): TSymStr;
  91. function llvmasmsymname(const sym: TAsmSymbol): TSymStr;
  92. function llvmfloatintrinsicsuffix(def: tfloatdef): TIDString;
  93. implementation
  94. uses
  95. globals,cutils,constexp,
  96. verbose,systems,
  97. fmodule,
  98. symtable,symsym,
  99. llvmsym,hlcgobj,
  100. defutil,blockutl,cgbase,paramgr,
  101. llvminfo,cpubase;
  102. {******************************************************************
  103. Type encoding
  104. *******************************************************************}
  105. function llvmtypeidentifier(def: tdef): TSymStr;
  106. begin
  107. if assigned(def.typesym) then
  108. result:='%"typ.'+def.fullownerhierarchyname(false)+def.typesym.realname+'"'
  109. else
  110. result:='%"typ.'+def.fullownerhierarchyname(false)+def.unique_id_str+'"';
  111. end;
  112. function llvmaggregatetype(def: tdef): boolean;
  113. begin
  114. result:=
  115. (def.typ in [recorddef,filedef,variantdef]) or
  116. ((def.typ=arraydef) and
  117. not is_dynamic_array(def)) or
  118. ((def.typ=setdef) and
  119. not is_smallset(def)) or
  120. is_shortstring(def) or
  121. is_object(def) or
  122. ((def.typ=procvardef) and
  123. not tprocvardef(def).is_addressonly)
  124. end;
  125. function llvmconvop(var fromsize, tosize: tdef; inregs: boolean): tllvmop;
  126. var
  127. fromregtyp,
  128. toregtyp: tregistertype;
  129. frombytesize,
  130. tobytesize: asizeint;
  131. begin
  132. fromregtyp:=chlcgobj.def2regtyp(fromsize);
  133. toregtyp:=chlcgobj.def2regtyp(tosize);
  134. { int to pointer or vice versa }
  135. if fromregtyp=R_ADDRESSREGISTER then
  136. begin
  137. case toregtyp of
  138. R_INTREGISTER:
  139. result:=la_ptrtoint;
  140. R_ADDRESSREGISTER:
  141. result:=la_bitcast;
  142. else
  143. result:=la_ptrtoint_to_x;
  144. end;
  145. end
  146. else if toregtyp=R_ADDRESSREGISTER then
  147. begin
  148. case fromregtyp of
  149. R_INTREGISTER:
  150. result:=la_inttoptr;
  151. R_ADDRESSREGISTER:
  152. result:=la_bitcast;
  153. else
  154. result:=la_x_to_inttoptr;
  155. end;
  156. end
  157. else
  158. begin
  159. { treat comp and currency as extended in registers (see comment at start
  160. of thlgcobj.a_loadfpu_ref_reg) }
  161. if inregs and
  162. (fromsize.typ=floatdef) then
  163. begin
  164. if tfloatdef(fromsize).floattype in [s64comp,s64currency] then
  165. fromsize:=sc80floattype;
  166. { at the value level, s80real and sc80real are the same }
  167. if tfloatdef(fromsize).floattype<>s80real then
  168. frombytesize:=fromsize.size
  169. else
  170. frombytesize:=sc80floattype.size;
  171. end
  172. else
  173. frombytesize:=fromsize.size;
  174. if inregs and
  175. (tosize.typ=floatdef) then
  176. begin
  177. if tfloatdef(tosize).floattype in [s64comp,s64currency] then
  178. tosize:=sc80floattype;
  179. if tfloatdef(tosize).floattype<>s80real then
  180. tobytesize:=tosize.size
  181. else
  182. tobytesize:=sc80floattype.size;
  183. end
  184. else
  185. tobytesize:=tosize.size;
  186. { need zero/sign extension, float truncation or plain bitcast? }
  187. if tobytesize<>frombytesize then
  188. begin
  189. case fromregtyp of
  190. R_FPUREGISTER,
  191. R_MMREGISTER:
  192. begin
  193. { todo: update once we support vectors }
  194. if not(toregtyp in [R_FPUREGISTER,R_MMREGISTER]) then
  195. internalerror(2014062202);
  196. if tobytesize<frombytesize then
  197. result:=la_fptrunc
  198. else
  199. result:=la_fpext
  200. end;
  201. else
  202. begin
  203. if tobytesize<frombytesize then
  204. result:=la_trunc
  205. else if is_signed(fromsize) then
  206. { fromsize is signed -> sign extension }
  207. result:=la_sext
  208. else
  209. result:=la_zext;
  210. end;
  211. end;
  212. end
  213. else if (fromsize=llvmbool1type) and
  214. (tosize<>llvmbool1type) then
  215. begin
  216. if is_cbool(tosize) then
  217. result:=la_sext
  218. else
  219. result:=la_zext
  220. end
  221. else if (tosize=llvmbool1type) and
  222. (fromsize<>llvmbool1type) then
  223. begin
  224. { would have to compare with 0, can't just take the lowest bit }
  225. if is_cbool(fromsize) then
  226. internalerror(2016052001)
  227. else
  228. result:=la_trunc
  229. end
  230. else
  231. result:=la_bitcast;
  232. end;
  233. end;
  234. function llvmmangledname(const s: TSymStr): TSymStr;
  235. begin
  236. if copy(s,1,length('llvm.'))<>'llvm.' then
  237. if s[1]<>'"' then
  238. result:='@"\01'+s+'"'
  239. else
  240. begin
  241. { already quoted -> insert \01 and prepend @ }
  242. result:='@'+s;
  243. insert('\01',result,3);
  244. end
  245. else
  246. result:='@'+s
  247. end;
  248. function llvmparatypeattr(const attr: TSymStr; paradef: tdef; strippointer: boolean): TSymStr;
  249. begin
  250. result:=attr;
  251. if llvmflag_para_attr_type in llvmversion_properties[current_settings.llvmversion] then
  252. begin
  253. if not strippointer then
  254. result:=result+'('+llvmencodetypename(paradef)+')'
  255. else
  256. begin
  257. if paradef.typ<>pointerdef then
  258. internalerror(2022060310);
  259. result:=result+'('+llvmencodetypename(tpointerdef(paradef).pointeddef)+')'
  260. end;
  261. end;
  262. end;
  263. function llvmasmsymname(const sym: TAsmSymbol): TSymStr;
  264. begin
  265. { AT_ADDR and AT_LABEL represent labels in the code, which have
  266. a different type in llvm compared to (global) data labels }
  267. if sym.bind=AB_TEMP then
  268. result:='%'+sym.name
  269. else if not(sym.typ in [AT_LABEL,AT_ADDR]) then
  270. result:=llvmmangledname(sym.name)
  271. else
  272. result:='label %'+sym.name;
  273. end;
  274. function llvmfloatintrinsicsuffix(def: tfloatdef): TIDString;
  275. begin
  276. case def.floattype of
  277. s32real:
  278. result:='_f32';
  279. s64real:
  280. result:='_f64';
  281. s80real,sc80real:
  282. result:='_f80';
  283. s128real:
  284. result:='_f128';
  285. else
  286. { comp/currency need to be converted to s(c)80real first }
  287. internalerror(2019122902);
  288. end;
  289. end;
  290. function llvmbyvalparaloc(paraloc: pcgparalocation): boolean;
  291. begin
  292. { "byval" is broken for register paras on several platforms in llvm
  293. (search for "byval" in llvm's bug tracker). Additionally, it should only
  294. be used to pass aggregate parameters on the stack, because it reportedly
  295. inhibits llvm's midlevel optimizers.
  296. Exception (for now?): parameters that have special shifting
  297. requirements, because modelling those in llvm is not easy (and clang
  298. nor llvm-gcc seem to do so either) }
  299. result:=
  300. ((paraloc^.loc=LOC_REFERENCE) and
  301. llvmaggregatetype(paraloc^.def)) or
  302. ((paraloc^.loc in [LOC_REGISTER,LOC_CREGISTER]) and
  303. (paraloc^.shiftval<>0))
  304. end;
  305. procedure llvmaddencodedabstractrecordtype(def: tabstractrecorddef; var encodedstr: TSymStr); forward;
  306. type
  307. tllvmencodeflag = (lef_inaggregate, lef_noimplicitderef, lef_typedecl);
  308. tllvmencodeflags = set of tllvmencodeflag;
  309. procedure llvmaddencodedtype_intern(def: tdef; const flags: tllvmencodeflags; var encodedstr: TSymStr);
  310. begin
  311. case def.typ of
  312. stringdef :
  313. begin
  314. case tstringdef(def).stringtype of
  315. st_widestring,
  316. st_unicodestring:
  317. { the variable does not point to the header, but to a
  318. null-terminated string/array with undefined bounds }
  319. encodedstr:=encodedstr+'i16*';
  320. st_ansistring:
  321. encodedstr:=encodedstr+'i8*';
  322. st_shortstring:
  323. { length byte followed by string bytes }
  324. if tstringdef(def).len>0 then
  325. encodedstr:=encodedstr+'['+tostr(tstringdef(def).len+1)+' x i8]'
  326. else
  327. encodedstr:=encodedstr+'[0 x i8]';
  328. else
  329. internalerror(2013100201);
  330. end;
  331. end;
  332. enumdef:
  333. begin
  334. encodedstr:=encodedstr+'i'+tostr(def.size*8);
  335. end;
  336. orddef :
  337. begin
  338. if is_void(def) then
  339. encodedstr:=encodedstr+'void'
  340. { mainly required because comparison operations return i1, and
  341. we need a way to represent the i1 type in Pascal. We don't
  342. reuse pasbool1type, because putting an i1 in a record or
  343. passing it as a parameter may result in unexpected behaviour }
  344. else if def=llvmbool1type then
  345. encodedstr:=encodedstr+'i1'
  346. else if torddef(def).ordtype<>customint then
  347. encodedstr:=encodedstr+'i'+tostr(def.size*8)
  348. else
  349. encodedstr:=encodedstr+'i'+tostr(def.packedbitsize);
  350. end;
  351. pointerdef :
  352. begin
  353. if def=llvm_metadatatype then
  354. encodedstr:=encodedstr+'metadata'
  355. else if is_voidpointer(def) then
  356. encodedstr:=encodedstr+'i8*'
  357. else
  358. begin
  359. llvmaddencodedtype_intern(tpointerdef(def).pointeddef,[],encodedstr);
  360. encodedstr:=encodedstr+'*';
  361. end;
  362. end;
  363. floatdef :
  364. begin
  365. case tfloatdef(def).floattype of
  366. s32real:
  367. encodedstr:=encodedstr+'float';
  368. s64real:
  369. encodedstr:=encodedstr+'double';
  370. { necessary to be able to force our own size/alignment }
  371. s80real:
  372. { prevent llvm from allocating the standard ABI size for
  373. extended }
  374. if lef_inaggregate in flags then
  375. encodedstr:=encodedstr+'[10 x i8]'
  376. else
  377. encodedstr:=encodedstr+'x86_fp80';
  378. sc80real:
  379. encodedstr:=encodedstr+'x86_fp80';
  380. s64comp,
  381. s64currency:
  382. encodedstr:=encodedstr+'i64';
  383. s128real:
  384. {$if defined(powerpc) or defined(powerpc128)}
  385. encodedstr:=encodedstr+'ppc_fp128';
  386. {$else}
  387. encodedstr:=encodedstr+'fp128';
  388. {$endif}
  389. end;
  390. end;
  391. filedef :
  392. begin
  393. case tfiledef(def).filetyp of
  394. ft_text :
  395. llvmaddencodedtype_intern(search_system_type('TEXTREC').typedef,[lef_inaggregate]+[lef_typedecl]*flags,encodedstr);
  396. ft_typed :
  397. begin
  398. { in case of ISO-like I/O, the typed file def includes a
  399. get/put buffer of the size of the file's elements }
  400. if (m_isolike_io in current_settings.modeswitches) and
  401. not is_void(tfiledef(def).typedfiledef) then
  402. encodedstr:=encodedstr+'<{';
  403. llvmaddencodedtype_intern(search_system_type('FILEREC').typedef,[lef_inaggregate]+[lef_typedecl]*flags,encodedstr);
  404. if (m_isolike_io in current_settings.modeswitches) and
  405. not is_void(tfiledef(def).typedfiledef) then
  406. begin
  407. encodedstr:=encodedstr+',[';
  408. encodedstr:=encodedstr+tostr(tfiledef(def).typedfiledef.size);
  409. encodedstr:=encodedstr+' x i8]}>'
  410. end;
  411. end;
  412. ft_untyped :
  413. llvmaddencodedtype_intern(search_system_type('FILEREC').typedef,[lef_inaggregate]+[lef_typedecl]*flags,encodedstr);
  414. end;
  415. end;
  416. recorddef :
  417. begin
  418. { avoid endlessly recursive definitions }
  419. if not(lef_typedecl in flags) then
  420. encodedstr:=encodedstr+llvmtypeidentifier(def)
  421. else
  422. llvmaddencodedabstractrecordtype(trecorddef(def),encodedstr);
  423. end;
  424. variantdef :
  425. begin
  426. llvmaddencodedtype_intern(search_system_type('TVARDATA').typedef,[lef_inaggregate]+[lef_typedecl]*flags,encodedstr);
  427. end;
  428. classrefdef :
  429. begin
  430. if is_class(tclassrefdef(def).pointeddef) then
  431. begin
  432. llvmaddencodedtype_intern(tobjectdef(tclassrefdef(def).pointeddef).vmt_def,flags,encodedstr);
  433. encodedstr:=encodedstr+'*';
  434. end
  435. else if is_objcclass(tclassrefdef(def).pointeddef) then
  436. llvmaddencodedtype_intern(objc_idtype,flags,encodedstr)
  437. else
  438. encodedstr:=encodedstr+'i8*'
  439. end;
  440. setdef :
  441. begin
  442. { just an array as far as llvm is concerned; don't use a "packed
  443. array of i1" or so, this requires special support in backends
  444. and guarantees nothing about the internal format }
  445. if is_smallset(def) then
  446. llvmaddencodedtype_intern(cgsize_orddef(def_cgsize(def)),[lef_inaggregate],encodedstr)
  447. else
  448. encodedstr:=encodedstr+'['+tostr(tsetdef(def).size)+' x i8]';
  449. end;
  450. formaldef :
  451. begin
  452. { var/const/out x (always treated as "pass by reference" -> don't
  453. add extra "*" here) }
  454. encodedstr:=encodedstr+'i8';
  455. end;
  456. arraydef :
  457. begin
  458. if tarraydef(def).is_hwvector then
  459. begin
  460. encodedstr:=encodedstr+'<'+tostr(tarraydef(def).elecount)+' x ';
  461. llvmaddencodedtype_intern(tarraydef(def).elementdef,[lef_inaggregate],encodedstr);
  462. encodedstr:=encodedstr+'>';
  463. end
  464. else if is_array_of_const(def) then
  465. begin
  466. encodedstr:=encodedstr+'[0 x ';
  467. llvmaddencodedtype_intern(search_system_type('TVARREC').typedef,[lef_inaggregate],encodedstr);
  468. encodedstr:=encodedstr+']';
  469. end
  470. else if is_open_array(def) then
  471. begin
  472. encodedstr:=encodedstr+'[0 x ';
  473. llvmaddencodedtype_intern(tarraydef(def).elementdef,[lef_inaggregate],encodedstr);
  474. encodedstr:=encodedstr+']';
  475. end
  476. else if is_dynamic_array(def) then
  477. begin
  478. llvmaddencodedtype_intern(tarraydef(def).elementdef,[lef_inaggregate],encodedstr);
  479. encodedstr:=encodedstr+'*';
  480. end
  481. else if is_packed_array(def) and
  482. (tarraydef(def).elementdef.typ in [enumdef,orddef]) then
  483. begin
  484. { encode as an array of bytes rather than as an array of
  485. packedbitsloadsize(elesize), because even if the load size
  486. is e.g. 2 bytes, the array may only be 1 or 3 bytes long
  487. (and if this array is inside a record, it must not be
  488. encoded as a type that is too long) }
  489. encodedstr:=encodedstr+'['+tostr(tarraydef(def).size)+' x ';
  490. llvmaddencodedtype_intern(u8inttype,[lef_inaggregate],encodedstr);
  491. encodedstr:=encodedstr+']';
  492. end
  493. else
  494. begin
  495. encodedstr:=encodedstr+'['+tostr(tarraydef(def).elecount)+' x ';
  496. llvmaddencodedtype_intern(tarraydef(def).elementdef,[lef_inaggregate],encodedstr);
  497. encodedstr:=encodedstr+']';
  498. end;
  499. end;
  500. procdef,
  501. procvardef :
  502. begin
  503. if (def.typ=procdef) or
  504. tprocvardef(def).is_addressonly then
  505. begin
  506. llvmaddencodedproctype(tabstractprocdef(def),'',lpd_procvar,encodedstr);
  507. if def.typ=procvardef then
  508. encodedstr:=encodedstr+'*';
  509. end
  510. else if not(lef_typedecl in flags) then
  511. begin
  512. { in case the procvardef recursively references itself, e.g.
  513. via a pointer }
  514. encodedstr:=encodedstr+llvmtypeidentifier(def);
  515. { blocks are implicit pointers }
  516. if is_block(def) then
  517. encodedstr:=encodedstr+'*'
  518. end
  519. else if is_block(def) then
  520. begin
  521. llvmaddencodedtype_intern(get_block_literal_type_for_proc(tabstractprocdef(def)),flags,encodedstr);
  522. end
  523. else
  524. begin
  525. encodedstr:=encodedstr+'<{';
  526. { code pointer }
  527. llvmaddencodedproctype(tabstractprocdef(def),'',lpd_procvar,encodedstr);
  528. { data pointer (maybe todo: generate actual layout if
  529. available) }
  530. encodedstr:=encodedstr+'*, i8*}>';
  531. end;
  532. end;
  533. objectdef :
  534. case tobjectdef(def).objecttype of
  535. odt_class,
  536. odt_objcclass,
  537. odt_object,
  538. odt_cppclass:
  539. begin
  540. if not(lef_typedecl in flags) then
  541. encodedstr:=encodedstr+llvmtypeidentifier(def)
  542. else
  543. llvmaddencodedabstractrecordtype(tabstractrecorddef(def),encodedstr);
  544. if ([lef_typedecl,lef_noimplicitderef]*flags=[]) and
  545. is_implicit_pointer_object_type(def) then
  546. encodedstr:=encodedstr+'*'
  547. end;
  548. odt_interfacecom,
  549. odt_interfacecorba,
  550. odt_dispinterface:
  551. begin
  552. { type is a pointer to a pointer to the vmt }
  553. llvmaddencodedtype_intern(tobjectdef(def).vmt_def,flags,encodedstr);
  554. if ([lef_typedecl,lef_noimplicitderef]*flags=[]) then
  555. encodedstr:=encodedstr+'**';
  556. end;
  557. odt_interfacecom_function,
  558. odt_interfacecom_property,
  559. odt_objcprotocol:
  560. begin
  561. { opaque for now }
  562. encodedstr:=encodedstr+'i8*'
  563. end;
  564. odt_helper:
  565. llvmaddencodedtype_intern(tobjectdef(def).extendeddef,flags,encodedstr);
  566. else
  567. internalerror(2013100601);
  568. end;
  569. undefineddef,
  570. errordef :
  571. internalerror(2013100604);
  572. else
  573. internalerror(2013100603);
  574. end;
  575. end;
  576. function llvmencodetypename(def: tdef): TSymStr;
  577. begin
  578. result:='';
  579. llvmaddencodedtype_intern(def,[],result);
  580. end;
  581. procedure llvmaddencodedtype(def: tdef; inaggregate: boolean; var encodedstr: TSymStr);
  582. var
  583. flags: tllvmencodeflags;
  584. begin
  585. if inaggregate then
  586. flags:=[lef_inaggregate]
  587. else
  588. flags:=[];
  589. llvmaddencodedtype_intern(def,flags,encodedstr);
  590. end;
  591. procedure llvmaddencodedabstractrecordtype(def: tabstractrecorddef; var encodedstr: TSymStr);
  592. var
  593. st: tllvmshadowsymtable;
  594. symdeflist: tfpobjectlist;
  595. i: longint;
  596. nopacked: boolean;
  597. begin
  598. st:=tabstractrecordsymtable(def.symtable).llvmst;
  599. symdeflist:=st.symdeflist;
  600. nopacked:=df_llvm_no_struct_packing in def.defoptions;
  601. if nopacked then
  602. encodedstr:=encodedstr+'{ '
  603. else
  604. encodedstr:=encodedstr+'<{ ';
  605. if symdeflist.count>0 then
  606. begin
  607. i:=0;
  608. if (def.typ=objectdef) and
  609. assigned(tobjectdef(def).childof) and
  610. is_class_or_interface_or_dispinterface(tllvmshadowsymtableentry(symdeflist[0]).def) then
  611. begin
  612. { insert the struct for the class rather than a pointer to the struct }
  613. if (tllvmshadowsymtableentry(symdeflist[0]).def.typ<>objectdef) then
  614. internalerror(2008070601);
  615. llvmaddencodedtype_intern(tllvmshadowsymtableentry(symdeflist[0]).def,[lef_inaggregate,lef_noimplicitderef],encodedstr);
  616. inc(i);
  617. end;
  618. while i<symdeflist.count do
  619. begin
  620. if i<>0 then
  621. encodedstr:=encodedstr+', ';
  622. llvmaddencodedtype_intern(tllvmshadowsymtableentry(symdeflist[i]).def,[lef_inaggregate],encodedstr);
  623. inc(i);
  624. end;
  625. end;
  626. if nopacked then
  627. encodedstr:=encodedstr+' }'
  628. else
  629. encodedstr:=encodedstr+' }>';
  630. end;
  631. procedure llvmextractvalueextinfo(paradef: tdef; var paralocdef: tdef; out signext: tllvmvalueextension);
  632. begin
  633. { implicit zero/sign extension for ABI compliance? (yes, if the size
  634. of a paraloc is larger than the size of the entire parameter) }
  635. if is_ordinal(paradef) and
  636. is_ordinal(paralocdef) and
  637. (paradef.size<paralocdef.size) then
  638. begin
  639. paralocdef:=paradef;
  640. if is_signed(paradef) then
  641. signext:=lve_signext
  642. else
  643. signext:=lve_zeroext
  644. end
  645. else
  646. signext:=lve_none;
  647. end;
  648. procedure llvmaddencodedparaloctype(hp: tparavarsym; proccalloption: tproccalloption; withparaname, withattributes: boolean; var first: boolean; var encodedstr: TSymStr);
  649. var
  650. para: PCGPara;
  651. paraloc: PCGParaLocation;
  652. side: tcallercallee;
  653. signext: tllvmvalueextension;
  654. usedef: tdef;
  655. firstloc: boolean;
  656. begin
  657. if (proccalloption in cdecl_pocalls) and
  658. is_array_of_const(hp.vardef) then
  659. begin
  660. if not first then
  661. encodedstr:=encodedstr+', '
  662. else
  663. first:=false;
  664. encodedstr:=encodedstr+'...';
  665. exit
  666. end;
  667. if not withparaname then
  668. side:=callerside
  669. else
  670. side:=calleeside;
  671. { don't add parameters that don't take up registers or stack space;
  672. clang doesn't either and some LLVM backends don't support them }
  673. if hp.paraloc[side].isempty then
  674. exit;
  675. para:[email protected][side];
  676. paraloc:=para^.location;
  677. firstloc:=true;
  678. repeat
  679. usedef:=paraloc^.def;
  680. llvmextractvalueextinfo(hp.vardef,usedef,signext);
  681. { implicit zero/sign extension for ABI compliance? }
  682. if not first then
  683. encodedstr:=encodedstr+', ';
  684. llvmaddencodedtype_intern(usedef,[],encodedstr);
  685. { in case signextstr<>'', there should be only one paraloc -> no need
  686. to clear (reason: it means that the paraloc is larger than the
  687. original parameter) }
  688. if withattributes then
  689. encodedstr:=encodedstr+llvmvalueextension2str[signext];
  690. { sret: hidden pointer for structured function result }
  691. if vo_is_funcret in hp.varoptions then
  692. begin
  693. { "sret" is only valid for the firstparameter, while in FPC this
  694. can sometimes be second one (self comes before). In general,
  695. this is not a problem: we can just leave out sret, which means
  696. the result will be a bit less well optimised), but it is for
  697. AArch64: there, the sret parameter must be passed in a different
  698. register (-> paranr_result is smaller than paranr_self for that
  699. platform in symconst) }
  700. {$ifdef aarch64}
  701. if not first and
  702. not is_managed_type(hp.vardef) then
  703. internalerror(2015101404);
  704. {$endif aarch64}
  705. if withattributes then
  706. begin
  707. if first
  708. {$ifdef aarch64}
  709. and not is_managed_type(hp.vardef)
  710. {$endif aarch64}
  711. then
  712. encodedstr:=encodedstr+llvmparatypeattr(' sret',hp.vardef,false)+' noalias nocapture'
  713. else
  714. encodedstr:=encodedstr+' noalias nocapture';
  715. end;
  716. end
  717. else if not paramanager.push_addr_param(hp.varspez,hp.vardef,proccalloption) and
  718. llvmbyvalparaloc(paraloc) then
  719. begin
  720. encodedstr:=encodedstr+'*';
  721. if withattributes then
  722. begin
  723. encodedstr:=encodedstr+llvmparatypeattr(' byval',hp.vardef,false);
  724. if firstloc and
  725. (para^.alignment<>std_param_align) then
  726. begin
  727. encodedstr:=encodedstr+' align '+tostr(para^.alignment);
  728. end;
  729. end
  730. end
  731. else if withattributes and
  732. paramanager.push_addr_param(hp.varspez,hp.vardef,proccalloption) then
  733. begin
  734. { it's not valid to take the address of a parameter and store it for
  735. use past the end of the function call (since the address can always
  736. be on the stack and become invalid later) }
  737. encodedstr:=encodedstr+' nocapture';
  738. { open array/array of const/variant array may be a valid pointer but empty }
  739. if not is_special_array(hp.vardef) and
  740. { e.g. empty records }
  741. (hp.vardef.size<>0) then
  742. begin
  743. case hp.varspez of
  744. vs_value,
  745. vs_const:
  746. begin
  747. encodedstr:=encodedstr+' readonly dereferenceable('
  748. end;
  749. vs_var,
  750. vs_out:
  751. begin
  752. { while normally these are not nil, it is technically possible
  753. to pass nil via ptrtype(nil)^ }
  754. encodedstr:=encodedstr+' dereferenceable_or_null(';
  755. end;
  756. vs_constref:
  757. begin
  758. encodedstr:=encodedstr+' readonly dereferenceable_or_null(';
  759. end;
  760. else
  761. internalerror(2018120801);
  762. end;
  763. if hp.vardef.typ<>formaldef then
  764. encodedstr:=encodedstr+tostr(hp.vardef.size)+')'
  765. else
  766. encodedstr:=encodedstr+'1)';
  767. end;
  768. end;
  769. if withparaname then
  770. begin
  771. if paraloc^.llvmloc.loc<>LOC_REFERENCE then
  772. internalerror(2014010803);
  773. encodedstr:=encodedstr+' '+llvmasmsymname(paraloc^.llvmloc.sym);
  774. end;
  775. paraloc:=paraloc^.next;
  776. firstloc:=false;
  777. first:=false;
  778. until not assigned(paraloc);
  779. end;
  780. function llvmencodeproctype(def: tabstractprocdef; const customname: TSymStr; pddecltype: tllvmprocdefdecltype): TSymStr;
  781. begin
  782. result:='';
  783. llvmaddencodedproctype(def,customname,pddecltype,result);
  784. end;
  785. procedure llvmaddencodedproctype(def: tabstractprocdef; const customname: TSymStr; pddecltype: tllvmprocdefdecltype; var encodedstr: TSymStr);
  786. var
  787. callingconv: ansistring;
  788. usedef: tdef;
  789. paranr: longint;
  790. hp: tparavarsym;
  791. signext: tllvmvalueextension;
  792. useside: tcallercallee;
  793. first: boolean;
  794. begin
  795. if not(pddecltype in [lpd_alias,lpd_procvar]) then
  796. begin
  797. callingconv:=llvm_callingconvention_name(def.proccalloption);
  798. if callingconv<>'' then
  799. encodedstr:=encodedstr+' '+callingconv;
  800. end;
  801. { when writing a definition, we have to write the parameter names, and
  802. those are only available on the callee side. In all other cases,
  803. we are at the callerside }
  804. if pddecltype=lpd_def then
  805. useside:=calleeside
  806. else
  807. useside:=callerside;
  808. def.init_paraloc_info(useside);
  809. first:=true;
  810. { function result (return-by-ref is handled explicitly) }
  811. if not paramanager.ret_in_param(def.returndef,def) or
  812. def.generate_safecall_wrapper then
  813. begin
  814. if not def.generate_safecall_wrapper then
  815. usedef:=llvmgetcgparadef(def.funcretloc[useside],false,useside)
  816. else
  817. usedef:=ossinttype;
  818. llvmextractvalueextinfo(def.returndef,usedef,signext);
  819. { specifying result sign extention information for an alias causes
  820. an error for some reason }
  821. if pddecltype in [lpd_decl,lpd_def] then
  822. encodedstr:=encodedstr+llvmvalueextension2str[signext];
  823. encodedstr:=encodedstr+' ';
  824. llvmaddencodedtype_intern(usedef,[],encodedstr);
  825. end
  826. else
  827. begin
  828. encodedstr:=encodedstr+' ';
  829. llvmaddencodedtype(voidtype,false,encodedstr);
  830. end;
  831. encodedstr:=encodedstr+' ';
  832. { add procname? }
  833. if (pddecltype in [lpd_decl,lpd_def]) and
  834. (def.typ=procdef) then
  835. if customname='' then
  836. encodedstr:=encodedstr+llvmmangledname(tprocdef(def).mangledname)
  837. else
  838. encodedstr:=encodedstr+llvmmangledname(customname);
  839. encodedstr:=encodedstr+'(';
  840. { parameters }
  841. first:=true;
  842. for paranr:=0 to def.paras.count-1 do
  843. begin
  844. hp:=tparavarsym(def.paras[paranr]);
  845. llvmaddencodedparaloctype(hp,def.proccalloption,pddecltype in [lpd_def],not(pddecltype in [lpd_procvar,lpd_alias]),first,encodedstr);
  846. end;
  847. if po_varargs in def.procoptions then
  848. begin
  849. if not first then
  850. encodedstr:=encodedstr+', ';
  851. encodedstr:=encodedstr+'...';
  852. end;
  853. encodedstr:=encodedstr+')'
  854. end;
  855. function llvmgettemprecorddef(const fieldtypes: array of tdef; packrecords, recordalignmin: shortint): trecorddef;
  856. procedure addtypename(var typename: TSymStr; hdef: tdef);
  857. begin
  858. case hdef.typ of
  859. orddef:
  860. case torddef(hdef).ordtype of
  861. s8bit,
  862. u8bit,
  863. pasbool1,
  864. pasbool8:
  865. typename:=typename+'i8';
  866. s16bit,
  867. u16bit:
  868. typename:=typename+'i16';
  869. s32bit,
  870. u32bit:
  871. typename:=typename+'i32';
  872. s64bit,
  873. u64bit:
  874. typename:=typename+'i64';
  875. customint:
  876. typename:=typename+'i'+tostr(torddef(hdef).packedbitsize);
  877. else
  878. { other types should not appear currently, add as needed }
  879. internalerror(2014012001);
  880. end;
  881. floatdef:
  882. case tfloatdef(hdef).floattype of
  883. s32real:
  884. typename:=typename+'f32';
  885. s64real:
  886. typename:=typename+'f64';
  887. else
  888. { other types should not appear currently, add as needed }
  889. internalerror(2014012008);
  890. end;
  891. arraydef:
  892. begin
  893. if not is_special_array(hdef) and
  894. not is_packed_array(hdef) then
  895. begin
  896. typename:=typename+'['+tostr(tarraydef(hdef).elecount)+'x';
  897. addtypename(typename,tarraydef(hdef).elementdef);
  898. typename:=typename+']';
  899. end
  900. else
  901. typename:=typename+'d'+hdef.unique_id_str;
  902. end
  903. else
  904. typename:=typename+'d'+hdef.unique_id_str;
  905. end;
  906. end;
  907. var
  908. i: longint;
  909. res: PHashSetItem;
  910. oldsymtablestack: tsymtablestack;
  911. hrecst: trecordsymtable;
  912. hrecdef: trecorddef;
  913. sym: tfieldvarsym;
  914. typename: TSymStr;
  915. begin
  916. typename:=internaltypeprefixName[itp_llvmstruct];
  917. for i:=low(fieldtypes) to high(fieldtypes) do
  918. begin
  919. addtypename(typename,fieldtypes[i]);
  920. end;
  921. if not assigned(current_module) then
  922. internalerror(2014012002);
  923. res:=current_module.llvmdefs.FindOrAdd(@typename[1],length(typename));
  924. if not assigned(res^.Data) then
  925. begin
  926. res^.Data:=crecorddef.create_global_internal(typename,packrecords,
  927. recordalignmin);
  928. for i:=low(fieldtypes) to high(fieldtypes) do
  929. trecorddef(res^.Data).add_field_by_def('F'+tostr(i),fieldtypes[i]);
  930. end;
  931. trecordsymtable(trecorddef(res^.Data).symtable).addalignmentpadding;
  932. result:=trecorddef(res^.Data);
  933. end;
  934. function llvmgetcgparadef(const cgpara: tcgpara; beforevalueext: boolean; callercallee: tcallercallee): tdef;
  935. var
  936. retdeflist: array[0..9] of tdef;
  937. retloc: pcgparalocation;
  938. usedef: tdef;
  939. valueext: tllvmvalueextension;
  940. paraslots,
  941. i: longint;
  942. sizeleft: asizeint;
  943. begin
  944. { single location }
  945. if not assigned(cgpara.location^.next) then
  946. begin
  947. { def of the location, except in case of zero/sign-extension and
  948. zero-sized records }
  949. if not is_special_array(cgpara.def) and
  950. (cgpara.def.size=0) then
  951. usedef:=cgpara.def
  952. else
  953. usedef:=cgpara.location^.def;
  954. if beforevalueext then
  955. llvmextractvalueextinfo(cgpara.def,usedef,valueext);
  956. { comp and currency are handled by the x87 in this case. They cannot
  957. be represented directly in llvm, and llvmdef translates them into
  958. i64 (since that's their storage size and internally they also are
  959. int64). Solve this by changing the type to s80real in the
  960. returndef/parameter declaration. }
  961. if (usedef.typ=floatdef) and
  962. (tfloatdef(usedef).floattype in [s64comp,s64currency]) then
  963. usedef:=s80floattype;
  964. result:=usedef;
  965. exit
  966. end;
  967. { multiple locations -> create temp record }
  968. retloc:=cgpara.location;
  969. i:=0;
  970. sizeleft:=cgpara.Def.size;
  971. repeat
  972. if i>high(retdeflist) then
  973. internalerror(2016121801);
  974. if assigned(retloc^.next) then
  975. begin
  976. retdeflist[i]:=retloc^.def;
  977. dec(sizeleft,retloc^.def.size);
  978. end
  979. { on the callerside, "byval" parameter locations have the implicit
  980. pointer in their type -> remove if we wish to create a record
  981. containing all actual parameter data }
  982. else if (callercallee=callerside) and
  983. not retloc^.llvmvalueloc then
  984. begin
  985. if retloc^.def.typ<>pointerdef then
  986. internalerror(2019020201);
  987. retdeflist[i]:=tpointerdef(retloc^.def).pointeddef
  988. end
  989. else if retloc^.def.size<>sizeleft then
  990. begin
  991. case sizeleft of
  992. 1:
  993. retdeflist[i]:=u8inttype;
  994. 2:
  995. retdeflist[i]:=u16inttype;
  996. 3:
  997. retdeflist[i]:=u24inttype;
  998. 4:
  999. retdeflist[i]:=u32inttype;
  1000. 5:
  1001. retdeflist[i]:=u40inttype;
  1002. 6:
  1003. retdeflist[i]:=u48inttype;
  1004. 7:
  1005. retdeflist[i]:=u56inttype;
  1006. else
  1007. retdeflist[i]:=retloc^.def;
  1008. end
  1009. end
  1010. else
  1011. begin
  1012. if retloc^.def.typ<>floatdef then
  1013. begin
  1014. paraslots:=sizeleft div cgpara.Alignment;
  1015. if (paraslots>1) and
  1016. ((paraslots*cgpara.Alignment)=sizeleft) then
  1017. retdeflist[i]:=carraydef.getreusable(cgsize_orddef(int_cgsize(cgpara.Alignment)),paraslots)
  1018. else
  1019. retdeflist[i]:=retloc^.def;
  1020. end
  1021. else
  1022. retdeflist[i]:=retloc^.def;
  1023. end;
  1024. inc(i);
  1025. retloc:=retloc^.next;
  1026. until not assigned(retloc);
  1027. result:=llvmgettemprecorddef(slice(retdeflist,i),C_alignment,
  1028. targetinfos[target_info.system]^.alignment.recordalignmin);
  1029. include(result.defoptions,df_llvm_no_struct_packing);
  1030. end;
  1031. function llvmencodetypedecl(def: tdef): TSymStr;
  1032. begin
  1033. result:='';
  1034. llvmaddencodedtype_intern(def,[lef_typedecl],result);
  1035. end;
  1036. end.