llvmdef.pas 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627
  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. parabase,
  23. symbase,symtype,symdef,
  24. llvmbase;
  25. type
  26. { there are three different circumstances in which procdefs are used:
  27. a) definition of a procdef that's implemented in the current module or
  28. declaration of an external routine that's called in the current one
  29. b) alias declaration of a procdef implemented in the current module
  30. c) defining a procvar type
  31. The main differences between the contexts are:
  32. a) information about sign extension of result type, proc name, parameter names & types
  33. b) no information about sign extension of result type, proc name, no parameter names, parameter types
  34. c) information about sign extension of result type, no proc name, no parameter names, parameter types
  35. }
  36. tllvmprocdefdecltype = (lpd_decl,lpd_alias,lpd_procvar);
  37. { Encode a type into the internal format used by LLVM. }
  38. function llvmencodetype(def: tdef): TSymStr;
  39. { incremental version of llvmencodetype(). "inaggregate" indicates whether
  40. this was a recursive call to get the type of an entity part of an
  41. aggregate type (array, record, ...) }
  42. procedure llvmaddencodedtype(def: tdef; inaggregate: boolean; var encodedstr: TSymStr);
  43. { encode a procdef/procvardef into the internal format used by LLVM }
  44. function llvmencodeproctype(def: tabstractprocdef; const customname: TSymStr; pddecltype: tllvmprocdefdecltype): TSymStr;
  45. { incremental version of the above }
  46. procedure llvmaddencodedproctype(def: tabstractprocdef; const customname: TSymStr; pddecltype: tllvmprocdefdecltype; var encodedstr: TSymStr);
  47. { function result types may have to be represented differently, e.g. a
  48. record consisting of 4 longints must be returned as a record consisting of
  49. two int64's on x86-64. This function is used to create (and reuse)
  50. temporary recorddefs for such purposes.}
  51. function llvmgettemprecorddef(fieldtypes: tfplist; packrecords: shortint): trecorddef;
  52. { get the llvm type corresponding to a parameter, e.g. a record containing
  53. two integer int64 for an arbitrary record split over two individual int64
  54. parameters, or an int32 for an int16 parameter on a platform that requires
  55. such parameters to be zero/sign extended. The second parameter can be used
  56. to get the type before zero/sign extension, as e.g. required to generate
  57. function declarations. }
  58. function llvmgetcgparadef(const cgpara: tcgpara; beforevalueext: boolean): tdef;
  59. { can be used to extract the value extension info from acgpara. Pass in
  60. the def of the cgpara as first parameter and a local variable holding
  61. a copy of the def of the location (value extension only makes sense for
  62. ordinal parameters that are smaller than a single location). The routine
  63. will return the def of the location without sign extension (if applicable)
  64. and the kind of sign extension that was originally performed in the
  65. signext parameter }
  66. procedure llvmextractvalueextinfo(paradef: tdef; var paralocdef: tdef; out signext: tllvmvalueextension);
  67. { returns whether a paraloc should be translated into an llvm "byval"
  68. parameter. These are declared as pointers to a particular type, but
  69. usually turned into copies onto the stack. The exact behaviour for
  70. parameters that should be passed in registers is undefined and depends on
  71. the platform, and furthermore this modifier sometimes inhibits
  72. optimizations. As a result,we only use it for aggregate parameters of
  73. which we know that they should be passed on the stack }
  74. function llvmbyvalparaloc(paraloc: pcgparalocation): boolean;
  75. { returns whether a def is representated by an aggregate type in llvm
  76. (struct, array) }
  77. function llvmaggregatetype(def: tdef): boolean;
  78. implementation
  79. uses
  80. cutils,constexp,
  81. verbose,systems,
  82. fmodule,
  83. symtable,symconst,symsym,
  84. llvmsym,
  85. defutil,cgbase,paramgr;
  86. {******************************************************************
  87. Type encoding
  88. *******************************************************************}
  89. function llvmaggregatetype(def: tdef): boolean;
  90. begin
  91. result:=
  92. (def.typ in [recorddef,filedef,variantdef]) or
  93. ((def.typ=arraydef) and
  94. not is_dynamic_array(def)) or
  95. ((def.typ=setdef) and
  96. not is_smallset(def)) or
  97. is_shortstring(def) or
  98. is_object(def) or
  99. ((def.typ=procvardef) and
  100. not tprocvardef(def).is_addressonly)
  101. end;
  102. function llvmbyvalparaloc(paraloc: pcgparalocation): boolean;
  103. begin
  104. { "byval" is broken for register paras on several platforms in llvm
  105. (search for "byval" in llvm's bug tracker). Additionally, it should only
  106. be used to pass aggregate parameters on the stack, because it reportedly
  107. inhibits llvm's midlevel optimizers.
  108. Exception (for now?): parameters that have special shifting
  109. requirements, because modelling those in llvm is not easy (and clang
  110. nor llvm-gcc seem to do so either) }
  111. result:=
  112. ((paraloc^.loc=LOC_REFERENCE) and
  113. llvmaggregatetype(paraloc^.def)) or
  114. (paraloc^.shiftval<>0)
  115. end;
  116. procedure llvmaddencodedabstractrecordtype(def: tabstractrecorddef; var encodedstr: TSymStr); forward;
  117. procedure llvmaddencodedtype_intern(def: tdef; inaggregate, noimplicitderef: boolean; var encodedstr: TSymStr);
  118. begin
  119. case def.typ of
  120. stringdef :
  121. begin
  122. case tstringdef(def).stringtype of
  123. st_widestring,
  124. st_unicodestring:
  125. { the variable does not point to the header, but to a
  126. null-terminated string/array with undefined bounds }
  127. encodedstr:=encodedstr+'i16*';
  128. st_ansistring:
  129. encodedstr:=encodedstr+'i8*';
  130. st_shortstring:
  131. { length byte followed by string bytes }
  132. if tstringdef(def).len>0 then
  133. encodedstr:=encodedstr+'['+tostr(tstringdef(def).len+1)+' x i8]}'
  134. else
  135. encodedstr:=encodedstr+'[0 x i8]';
  136. else
  137. internalerror(2013100201);
  138. end;
  139. end;
  140. enumdef:
  141. begin
  142. encodedstr:=encodedstr+'i'+tostr(def.size*8);
  143. end;
  144. orddef :
  145. begin
  146. if is_void(def) then
  147. encodedstr:=encodedstr+'void'
  148. { mainly required because comparison operations return i1, and
  149. otherwise we always have to immediatel extend them to i8 for
  150. no good reason; besides, Pascal booleans can only contain 0
  151. or 1 in valid code anyway (famous last words...) }
  152. else if torddef(def).ordtype=pasbool8 then
  153. encodedstr:=encodedstr+'i1'
  154. else
  155. encodedstr:=encodedstr+'i'+tostr(def.size*8);
  156. end;
  157. pointerdef :
  158. begin
  159. if is_voidpointer(def) then
  160. encodedstr:=encodedstr+'i8*'
  161. else
  162. begin
  163. llvmaddencodedtype_intern(tpointerdef(def).pointeddef,inaggregate,false,encodedstr);
  164. encodedstr:=encodedstr+'*';
  165. end;
  166. end;
  167. floatdef :
  168. begin
  169. case tfloatdef(def).floattype of
  170. s32real:
  171. encodedstr:=encodedstr+'float';
  172. s64real:
  173. encodedstr:=encodedstr+'double';
  174. { necessary to be able to force our own size/alignment }
  175. s80real:
  176. { prevent llvm from allocating the standard ABI size for
  177. extended }
  178. if inaggregate then
  179. encodedstr:=encodedstr+'[10 x i8]'
  180. else
  181. encodedstr:=encodedstr+'x86_fp80';
  182. sc80real:
  183. encodedstr:=encodedstr+'x86_fp80';
  184. s64comp,
  185. s64currency:
  186. encodedstr:=encodedstr+'i64';
  187. s128real:
  188. {$if defined(powerpc) or defined(powerpc128)}
  189. encodedstr:=encodedstr+'ppc_fp128';
  190. {$else}
  191. encodedstr:=encodedstr+'fp128';
  192. {$endif}
  193. else
  194. internalerror(2013100202);
  195. end;
  196. end;
  197. filedef :
  198. begin
  199. case tfiledef(def).filetyp of
  200. ft_text :
  201. llvmaddencodedtype_intern(search_system_type('TEXTREC').typedef,inaggregate,false,encodedstr);
  202. ft_typed,
  203. ft_untyped :
  204. llvmaddencodedtype_intern(search_system_type('FILEREC').typedef,inaggregate,false,encodedstr);
  205. else
  206. internalerror(2013100203);
  207. end;
  208. end;
  209. recorddef :
  210. begin
  211. llvmaddencodedabstractrecordtype(trecorddef(def),encodedstr);
  212. end;
  213. variantdef :
  214. begin
  215. llvmaddencodedtype_intern(search_system_type('TVARDATA').typedef,inaggregate,false,encodedstr);
  216. end;
  217. classrefdef :
  218. begin
  219. { todo: define proper type for VMT and use that }
  220. encodedstr:=encodedstr+'i8*';
  221. end;
  222. setdef :
  223. begin
  224. { just an array as far as llvm is concerned; don't use a "packed
  225. array of i1" or so, this requires special support in backends
  226. and guarantees nothing about the internal format }
  227. if is_smallset(def) then
  228. llvmaddencodedtype_intern(cgsize_orddef(def_cgsize(def)),inaggregate,false,encodedstr)
  229. else
  230. encodedstr:=encodedstr+'['+tostr(tsetdef(def).size)+' x i8]';
  231. end;
  232. formaldef :
  233. begin
  234. { var/const/out x }
  235. encodedstr:=encodedstr+'i8*';
  236. end;
  237. arraydef :
  238. begin
  239. if is_array_of_const(def) then
  240. begin
  241. encodedstr:=encodedstr+'[0 x ';
  242. llvmaddencodedtype_intern(search_system_type('TVARREC').typedef,true,false,encodedstr);
  243. encodedstr:=encodedstr+']';
  244. end
  245. else if is_open_array(def) then
  246. begin
  247. encodedstr:=encodedstr+'[0 x ';
  248. llvmaddencodedtype_intern(tarraydef(def).elementdef,true,false,encodedstr);
  249. encodedstr:=encodedstr+']';
  250. end
  251. else if is_dynamic_array(def) then
  252. begin
  253. llvmaddencodedtype_intern(tarraydef(def).elementdef,inaggregate,false,encodedstr);
  254. encodedstr:=encodedstr+'*';
  255. end
  256. else if is_packed_array(def) then
  257. begin
  258. encodedstr:=encodedstr+'['+tostr(tarraydef(def).size div tarraydef(def).elementdef.packedbitsize)+' x ';
  259. { encode as an array of integers with the size on which we
  260. perform the packedbits operations }
  261. llvmaddencodedtype_intern(cgsize_orddef(int_cgsize(packedbitsloadsize(tarraydef(def).elementdef.packedbitsize))),true,false,encodedstr);
  262. encodedstr:=encodedstr+']';
  263. end
  264. else
  265. begin
  266. encodedstr:=encodedstr+'['+tostr(tarraydef(def).elecount)+' x ';
  267. llvmaddencodedtype_intern(tarraydef(def).elementdef,true,false,encodedstr);
  268. encodedstr:=encodedstr+']';
  269. end;
  270. end;
  271. procvardef :
  272. begin
  273. if tprocvardef(def).is_addressonly then
  274. begin
  275. llvmaddencodedproctype(tprocdef(def),'',lpd_procvar,encodedstr);
  276. encodedstr:=encodedstr+'*';
  277. end
  278. else
  279. begin
  280. encodedstr:=encodedstr+'{';
  281. { code pointer }
  282. llvmaddencodedproctype(tprocvardef(def),'',lpd_procvar,encodedstr);
  283. { data pointer (maybe todo: generate actual layout if
  284. available) }
  285. encodedstr:=encodedstr+'*, i8*}';
  286. end;
  287. end;
  288. objectdef :
  289. case tobjectdef(def).objecttype of
  290. odt_class,
  291. odt_objcclass,
  292. odt_object,
  293. odt_cppclass:
  294. begin
  295. { for now don't handle fields yet }
  296. encodedstr:=encodedstr+'{[i8 x '+tostr(def.size)+']}';
  297. if not noimplicitderef and
  298. is_implicit_pointer_object_type(def) then
  299. encodedstr:=encodedstr+'*'
  300. end;
  301. odt_interfacecom,
  302. odt_interfacecom_function,
  303. odt_interfacecom_property,
  304. odt_interfacecorba,
  305. odt_dispinterface,
  306. odt_objcprotocol:
  307. begin
  308. { opaque for now }
  309. encodedstr:=encodedstr+'i8*'
  310. end;
  311. else
  312. internalerror(2013100601);
  313. end;
  314. undefineddef,
  315. errordef :
  316. internalerror(2013100604);
  317. procdef :
  318. begin
  319. { should be handled via llvmencodeproctype/llvmaddencodedproctype }
  320. internalerror(2014012601);
  321. end;
  322. else
  323. internalerror(2013100603);
  324. end;
  325. end;
  326. procedure llvmaddencodedtype(def: tdef; inaggregate: boolean; var encodedstr: TSymStr);
  327. begin
  328. llvmaddencodedtype_intern(def,inaggregate,false,encodedstr);
  329. end;
  330. procedure llvmaddencodedabstractrecordtype(def: tabstractrecorddef; var encodedstr: TSymStr);
  331. var
  332. st: tllvmshadowsymtable;
  333. symdeflist: tfpobjectlist;
  334. i: longint;
  335. begin
  336. st:=tabstractrecordsymtable(def.symtable).llvmst;
  337. symdeflist:=st.symdeflist;
  338. if tabstractrecordsymtable(def.symtable).usefieldalignment<>C_alignment then
  339. encodedstr:=encodedstr+'<';
  340. encodedstr:=encodedstr+'{ ';
  341. if symdeflist.count>0 then
  342. begin
  343. i:=0;
  344. if (def.typ=objectdef) and
  345. assigned(tobjectdef(def).childof) and
  346. is_class_or_interface_or_dispinterface(tllvmshadowsymtableentry(symdeflist[0]).def) then
  347. begin
  348. { insert the struct for the class rather than a pointer to the struct }
  349. if (tllvmshadowsymtableentry(symdeflist[0]).def.typ<>objectdef) then
  350. internalerror(2008070601);
  351. llvmaddencodedtype_intern(tllvmshadowsymtableentry(symdeflist[0]).def,true,true,encodedstr);
  352. inc(i);
  353. end;
  354. while i<symdeflist.count do
  355. begin
  356. if i<>0 then
  357. encodedstr:=encodedstr+', ';
  358. llvmaddencodedtype_intern(tllvmshadowsymtableentry(symdeflist[i]).def,true,false,encodedstr);
  359. inc(i);
  360. end;
  361. end;
  362. encodedstr:=encodedstr+' }';
  363. if tabstractrecordsymtable(def.symtable).usefieldalignment<>C_alignment then
  364. encodedstr:=encodedstr+'>';
  365. end;
  366. procedure llvmextractvalueextinfo(paradef: tdef; var paralocdef: tdef; out signext: tllvmvalueextension);
  367. begin
  368. { implicit zero/sign extension for ABI compliance? (yes, if the size
  369. of a paraloc is larger than the size of the entire parameter) }
  370. if is_ordinal(paradef) and
  371. is_ordinal(paralocdef) and
  372. (paradef.size<paralocdef.size) then
  373. begin
  374. paralocdef:=paradef;
  375. if is_signed(paradef) then
  376. signext:=lve_signext
  377. else
  378. signext:=lve_zeroext
  379. end
  380. else
  381. signext:=lve_none;
  382. end;
  383. procedure llvmaddencodedparaloctype(hp: tparavarsym; proccalloption: tproccalloption; withparaname: boolean; var first: boolean; var encodedstr: TSymStr);
  384. var
  385. paraloc: PCGParaLocation;
  386. signext: tllvmvalueextension;
  387. usedef: tdef;
  388. begin
  389. paraloc:=hp.paraloc[calleeside].location;
  390. repeat
  391. usedef:=paraloc^.def;
  392. llvmextractvalueextinfo(hp.vardef,usedef,signext);
  393. { implicit zero/sign extension for ABI compliance? }
  394. if not first then
  395. encodedstr:=encodedstr+', '
  396. else
  397. first:=false;
  398. llvmaddencodedtype(usedef,false,encodedstr);
  399. { in case signextstr<>'', there should be only one paraloc -> no need
  400. to clear (reason: it means that the paraloc is larger than the
  401. original parameter) }
  402. encodedstr:=encodedstr+llvmvalueextension2str[signext];
  403. { sret: hidden pointer for structured function result }
  404. if vo_is_funcret in hp.varoptions then
  405. encodedstr:=encodedstr+' sret'
  406. else if not paramanager.push_addr_param(hp.varspez,hp.vardef,proccalloption) and
  407. llvmbyvalparaloc(paraloc) then
  408. encodedstr:=encodedstr+'* byval';
  409. if withparaname then
  410. begin
  411. if paraloc^.llvmloc.loc<>LOC_REFERENCE then
  412. internalerror(2014010803);
  413. encodedstr:=encodedstr+' '+paraloc^.llvmloc.sym.name;
  414. end;
  415. paraloc:=paraloc^.next;
  416. until not assigned(paraloc);
  417. end;
  418. function llvmencodeproctype(def: tabstractprocdef; const customname: TSymStr; pddecltype: tllvmprocdefdecltype): TSymStr;
  419. begin
  420. result:='';
  421. llvmaddencodedproctype(def,customname,pddecltype,result);
  422. end;
  423. procedure llvmaddencodedproctype(def: tabstractprocdef; const customname: TSymStr; pddecltype: tllvmprocdefdecltype; var encodedstr: TSymStr);
  424. var
  425. usedef: tdef;
  426. paranr: longint;
  427. hp: tparavarsym;
  428. signext: tllvmvalueextension;
  429. first: boolean;
  430. begin
  431. def.init_paraloc_info(calleeside);
  432. first:=true;
  433. { function result (return-by-ref is handled explicitly) }
  434. if not paramanager.ret_in_param(def.returndef,def) then
  435. begin
  436. usedef:=llvmgetcgparadef(def.funcretloc[calleeside],false);
  437. llvmextractvalueextinfo(def.returndef,usedef,signext);
  438. { specifying result sign extention information for an alias causes
  439. an error for some reason }
  440. if pddecltype in [lpd_decl,lpd_procvar] then
  441. encodedstr:=encodedstr+llvmvalueextension2str[signext];
  442. encodedstr:=encodedstr+' ';
  443. llvmaddencodedtype_intern(usedef,false,false,encodedstr);
  444. end
  445. else
  446. begin
  447. encodedstr:=encodedstr+' ';
  448. llvmaddencodedtype(voidtype,false,encodedstr);
  449. end;
  450. encodedstr:=encodedstr+' ';
  451. { add procname? }
  452. if (pddecltype in [lpd_decl]) and
  453. (def.typ=procdef) then
  454. if customname='' then
  455. encodedstr:=encodedstr+tprocdef(def).mangledname
  456. else
  457. encodedstr:=encodedstr+customname;
  458. encodedstr:=encodedstr+'(';
  459. { parameters }
  460. first:=true;
  461. for paranr:=0 to def.paras.count-1 do
  462. begin
  463. hp:=tparavarsym(def.paras[paranr]);
  464. llvmaddencodedparaloctype(hp,def.proccalloption,pddecltype in [lpd_decl],first,encodedstr);
  465. end;
  466. encodedstr:=encodedstr+')'
  467. end;
  468. function llvmgettemprecorddef(fieldtypes: tfplist; packrecords: shortint): trecorddef;
  469. var
  470. i: longint;
  471. res: PHashSetItem;
  472. oldsymtablestack: tsymtablestack;
  473. hrecst: trecordsymtable;
  474. hdef: tdef;
  475. hrecdef: trecorddef;
  476. sym: tfieldvarsym;
  477. typename: string;
  478. begin
  479. typename:='$llvmstruct_';
  480. for i:=0 to fieldtypes.count-1 do
  481. begin
  482. hdef:=tdef(fieldtypes[i]);
  483. case hdef.typ of
  484. orddef:
  485. case torddef(hdef).ordtype of
  486. s8bit,
  487. u8bit:
  488. typename:=typename+'i8';
  489. s16bit,
  490. u16bit:
  491. typename:=typename+'i16';
  492. s32bit,
  493. u32bit:
  494. typename:=typename+'i32';
  495. s64bit,
  496. u64bit:
  497. typename:=typename+'i64';
  498. else
  499. { other types should not appear currently, add as needed }
  500. internalerror(2014012001);
  501. end;
  502. floatdef:
  503. case tfloatdef(hdef).floattype of
  504. s32real:
  505. typename:=typename+'f32';
  506. s64real:
  507. typename:=typename+'f64';
  508. else
  509. { other types should not appear currently, add as needed }
  510. internalerror(2014012008);
  511. end;
  512. else
  513. { other types should not appear currently, add as needed }
  514. internalerror(2014012009);
  515. end;
  516. end;
  517. if not assigned(current_module) then
  518. internalerror(2014012002);
  519. res:=current_module.llvmdefs.FindOrAdd(@typename[1],length(typename));
  520. if not assigned(res^.Data) then
  521. begin
  522. oldsymtablestack:=symtablestack;
  523. { do not simply push/pop current_module.localsymtable, because
  524. that can have side-effects (e.g., it removes helpers) }
  525. symtablestack:=nil;
  526. hrecst:=trecordsymtable.create(typename,packrecords);
  527. hrecdef:=trecorddef.create(typename,hrecst);
  528. for i:=0 to fieldtypes.count-1 do
  529. begin
  530. sym:=tfieldvarsym.create('$f'+tostr(i),vs_value,tdef(fieldtypes[i]),[]);
  531. hrecst.insert(sym);
  532. hrecst.addfield(sym,vis_hidden);
  533. end;
  534. res^.Data:=hrecdef;
  535. if assigned(current_module.localsymtable) then
  536. current_module.localsymtable.insertdef(tdef(res^.Data))
  537. else
  538. current_module.globalsymtable.insertdef(tdef(res^.Data));
  539. symtablestack:=oldsymtablestack;
  540. end;
  541. result:=trecorddef(res^.Data);
  542. end;
  543. function llvmgetcgparadef(const cgpara: tcgpara; beforevalueext: boolean): tdef;
  544. var
  545. retdeflist: tfplist;
  546. retloc: pcgparalocation;
  547. usedef: tdef;
  548. valueext: tllvmvalueextension;
  549. begin
  550. { single location }
  551. if not assigned(cgpara.location^.next) then
  552. begin
  553. { def of the location, except in case of zero/sign-extension }
  554. usedef:=cgpara.location^.def;
  555. if beforevalueext then
  556. llvmextractvalueextinfo(cgpara.def,usedef,valueext);
  557. result:=usedef;
  558. exit
  559. end;
  560. { multiple locations -> create temp record }
  561. retdeflist:=tfplist.create;
  562. retloc:=cgpara.location;
  563. repeat
  564. retdeflist.add(retloc^.def);
  565. retloc:=retloc^.next;
  566. until not assigned(retloc);
  567. result:=llvmgettemprecorddef(retdeflist,C_alignment);
  568. end;
  569. function llvmencodetype(def: tdef): TSymStr;
  570. begin
  571. result:='';
  572. llvmaddencodedtype(def,false,result);
  573. end;
  574. end.