tgllvm.pas 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. {
  2. Copyright (c) 1998-2002 by Florian Klaempfl
  3. This unit implements the LLVM-specific temp. generator
  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. unit tgllvm;
  18. {$i fpcdefs.inc}
  19. interface
  20. uses
  21. cclasses,
  22. globals,globtype,
  23. symtype,
  24. cpubase,cpuinfo,cgbase,cgutils,
  25. aasmbase,aasmtai,aasmdata,
  26. tgobj;
  27. type
  28. { LLVM temp manager: in LLVM, you allocate every temp separately using
  29. the "alloca" instrinsic. Every such temp is a separate stack slot, but
  30. can be turned into a regvar (or be decomposed) by LLVM. To avoid
  31. problems with turning stack slots into regvars, we don't allocate one
  32. big blob of memory that we manage ourselves using the regular temp
  33. manager. On the other hand, to avoid using a needlessly large amount of
  34. stack space we still try to reuse stack slots.
  35. We basically let the original temp manager handle the temp allocation,
  36. with the following modifications:
  37. * don't use partial temp locations, and don't merge temp locations
  38. (suballoc_and_merging:=false)
  39. * since there is no frame pointer at the llvm level, convert the
  40. temp offsets into local symbols
  41. * we keep track of the offset by making it part of the symbol name
  42. }
  43. { ttgllvm }
  44. ttgllvm = class(ttgobj)
  45. protected
  46. function temppostoref(pos, alignment: longint): treference; override;
  47. function reftotemppos(const ref: treference): longint; override;
  48. function internalistemp(const ref: treference): boolean; override;
  49. public
  50. constructor create;
  51. end;
  52. implementation
  53. uses
  54. cutils,
  55. systems,verbose,
  56. procinfo,
  57. symconst
  58. ;
  59. { ttgllvm }
  60. function ttgllvm.temppostoref(pos, alignment: longint): treference;
  61. begin
  62. reference_reset_symbol(result,
  63. current_asmdata.DefineAsmSymbol('$llvmtemp'+tostr(pos),AB_LOCAL,AT_TEMP),
  64. 0,alignment);
  65. end;
  66. function ttgllvm.reftotemppos(const ref: treference): longint;
  67. var
  68. error: longint;
  69. begin
  70. if assigned(ref.symbol) and
  71. (ref.symbol.typ=AT_TEMP) and
  72. (ref.base=NR_NO) and
  73. (ref.index=NR_NO) and
  74. (ref.offset=0) then
  75. begin
  76. val(copy(ref.symbol.Name,length('$llvmtemp')+1,high(ref.symbol.Name)),result,error);
  77. if error<>0 then
  78. internalerror(2010081501);
  79. end
  80. else
  81. result:=high(longint);
  82. end;
  83. function ttgllvm.internalistemp(const ref: treference): boolean;
  84. begin
  85. Result:=assigned(ref.symbol) and
  86. (ref.symbol.typ=AT_TEMP) and
  87. (ref.base=NR_NO) and
  88. (ref.index=NR_NO) and
  89. (ref.offset=0);
  90. end;
  91. constructor ttgllvm.create;
  92. begin
  93. inherited create;
  94. suballoc_and_merging:=false;
  95. { always use positive offsets, because symbol names cannot contain "-"
  96. without being quoted }
  97. direction:=1;
  98. end;
  99. end.