aasmllvmmetadata.pas 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. {
  2. Copyright (c) 2019 by Jonas Maebe,
  3. member of the Free Pascal Compiler development team
  4. Support for LLVM metadata
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. ****************************************************************************
  17. }
  18. unit aasmllvmmetadata;
  19. {$i fpcdefs.inc}
  20. interface
  21. uses
  22. globtype,cclasses,
  23. cgbase,
  24. aasmtai,aasmcnst,
  25. symtype;
  26. type
  27. tspecialisedmetadatanodekind = (
  28. smeta_DIFile,
  29. smeta_DIBasicType,
  30. smeta_DISubroutineType,
  31. smeta_DIDerivedType,
  32. smeta_DICompositeType,
  33. smeta_DISubrange,
  34. smeta_DIEnumerator,
  35. smeta_DITemplateTypeParameter,
  36. smeta_DITemplateValueParameter,
  37. smeta_DINamespace,
  38. smeta_DIGlobalVariable,
  39. smeta_DISubprogram,
  40. smeta_DILexicalBlock,
  41. smeta_DILexicalBlockFile,
  42. smeta_DILocation,
  43. smeta_DILocalVariable,
  44. smeta_DIExpression,
  45. smeta_DIObjCProperty,
  46. smeta_DIImportedEntity,
  47. smeta_DIMacro,
  48. smeta_DIMacroFile
  49. );
  50. // represented by a tai_simpletypedconst() with inside a metadata struct,
  51. // or as a metadata register (for parameters)
  52. // tai_llvmmetadatastring = class
  53. tai_llvmbasemetadatanode = class abstract(tai_aggregatetypedconst)
  54. strict protected
  55. function getname: ansistring; virtual; abstract;
  56. public
  57. procedure addvalue(val: tai_abstracttypedconst); override;
  58. property name: ansistring read getname;
  59. constructor create; reintroduce;
  60. end;
  61. (* !0 = !{ type1 value1, ... } *)
  62. tai_llvmunnamedmetadatanode = class(tai_llvmbasemetadatanode)
  63. strict private class var
  64. snextid: TSuperRegister;
  65. class function getnextid: TSuperRegister;
  66. strict protected
  67. fnameval: TSuperRegister;
  68. public
  69. constructor create; reintroduce;
  70. function getname: ansistring; override;
  71. end;
  72. (* !name = !{ type1 value1, ... } *)
  73. tai_llvmnamedmetadatanode = class(tai_llvmbasemetadatanode)
  74. strict protected
  75. fname: ansistring;
  76. function getname: ansistring; override;
  77. public
  78. constructor create(const aName: ansistring);
  79. end;
  80. tai_llvmmetadatareftypedconst = class(tai_simple)
  81. strict private
  82. fval: tai_llvmbasemetadatanode;
  83. public
  84. constructor create(_val: tai_llvmbasemetadatanode);
  85. property val: tai_llvmbasemetadatanode read fval;
  86. end;
  87. { @g1 = global i32 0, *!id !value.name* }
  88. tai_llvmmetadatareferenceoperand = class(tai_simple)
  89. strict private
  90. fid: ansistring;
  91. fvalue: tai_llvmbasemetadatanode;
  92. public
  93. constructor create(const anID: ansistring; aValue: tai_llvmbasemetadatanode);
  94. property id: ansistring read fid;
  95. property value: tai_llvmbasemetadatanode read fvalue;
  96. end;
  97. { !name = !kindname(field1: value1, ...) }
  98. tai_llvmspecialisedmetadatanode = class(tai_llvmunnamedmetadatanode)
  99. { identifies name and fieldnames }
  100. kind: tspecialisedmetadatanodekind;
  101. end;
  102. tllvmmetadata = class
  103. strict private
  104. class function addstring(const s: TSymstr): TSuperRegister;
  105. class function regtostring(reg: TRegister): TSymStr;
  106. public
  107. class function getstringreg(const s: TSymstr): TRegister;
  108. class function getpcharreg(p: pchar; len: longint): TRegister;
  109. class function getregstring(reg: TRegister): TSymStr;
  110. end;
  111. function llvm_getmetadatareftypedconst(metadata: tai_llvmbasemetadatanode): tai_simpletypedconst;
  112. implementation
  113. uses
  114. verbose,
  115. fmodule,
  116. symdef;
  117. function llvm_getmetadatareftypedconst(metadata: tai_llvmbasemetadatanode): tai_simpletypedconst;
  118. begin
  119. result:=tai_simpletypedconst.create(llvm_metadatatype, tai_llvmmetadatareftypedconst.create(metadata));
  120. end;
  121. procedure tai_llvmbasemetadatanode.addvalue(val: tai_abstracttypedconst);
  122. begin
  123. { bypass string merging attempts, as we add tai_strings directly here }
  124. fvalues.add(val);
  125. end;
  126. constructor tai_llvmbasemetadatanode.create;
  127. begin
  128. inherited create(tck_array, llvm_metadatatype);
  129. typ:=ait_llvmmetadatanode;
  130. end;
  131. class function tai_llvmunnamedmetadatanode.getnextid: TSuperRegister;
  132. begin
  133. result:=snextid;
  134. inc(snextid);
  135. end;
  136. function tai_llvmunnamedmetadatanode.getname: ansistring;
  137. begin
  138. str(fnameval,result);
  139. end;
  140. constructor tai_llvmunnamedmetadatanode.create;
  141. begin
  142. inherited;
  143. fnameval:=getnextid;
  144. end;
  145. function tai_llvmnamedmetadatanode.getname: ansistring;
  146. begin
  147. result:=fname;
  148. end;
  149. constructor tai_llvmnamedmetadatanode.create(const aName: ansistring);
  150. begin
  151. inherited create;
  152. fname:=aName;
  153. end;
  154. constructor tai_llvmmetadatareftypedconst.create(_val: tai_llvmbasemetadatanode);
  155. begin
  156. inherited create(ait_llvmmetadatareftypedconst);
  157. fval:=_val;
  158. end;
  159. constructor tai_llvmmetadatareferenceoperand.create(const anID: ansistring; aValue: tai_llvmbasemetadatanode);
  160. begin
  161. inherited create(ait_llvmmetadatarefoperand);
  162. fid:=anID;
  163. fvalue:=aValue;
  164. end;
  165. /////////////////////////////////////////////////
  166. class function tllvmmetadata.addstring(const s: TSymStr): TSuperRegister;
  167. var
  168. index: longint;
  169. begin
  170. index:=current_module.llvmmetadatastrings.Add(s,nil);
  171. if index>high(result) then
  172. internalerror(2019122806);
  173. result:=index;
  174. end;
  175. class function tllvmmetadata.regtostring(reg: TRegister): TSymStr;
  176. begin
  177. if getregtype(reg)<>R_METADATAREGISTER then
  178. internalerror(2019122807);
  179. if getsubreg(reg)<>R_SUBMETASTRING then
  180. internalerror(2019122808);
  181. result:=current_module.llvmmetadatastrings.NameOfIndex(getsupreg(reg));
  182. end;
  183. class function tllvmmetadata.getstringreg(const s: TSymstr): TRegister;
  184. var
  185. supreg: TSuperRegister;
  186. index: longint;
  187. begin
  188. index:=current_module.llvmmetadatastrings.FindIndexOf(s);
  189. if index<>-1 then
  190. supreg:=index
  191. else
  192. supreg:=addstring(s);
  193. result:=newreg(R_METADATAREGISTER,supreg,R_SUBMETASTRING);
  194. end;
  195. class function tllvmmetadata.getpcharreg(p: pchar; len: longint): TRegister;
  196. var
  197. str: TSymStr;
  198. begin
  199. if len>0 then
  200. begin
  201. setlength(str,len);
  202. move(p[0],str[1],len);
  203. result:=getstringreg(str);
  204. end
  205. else
  206. result:=getstringreg('');
  207. end;
  208. class function tllvmmetadata.getregstring(reg: TRegister): TSymStr;
  209. begin
  210. result:=regtostring(reg);
  211. end;
  212. end.