PageRenderTime 68ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/hphp/runtime/vm/jit/vasm-unit.h

https://gitlab.com/0072016/0072016-PHP.LLC
C Header | 195 lines | 93 code | 30 blank | 72 comment | 7 complexity | 76732957e5d306bf7abb55d3cf337a08 MD5 | raw file
  1. /*
  2. +----------------------------------------------------------------------+
  3. | HipHop for PHP |
  4. +----------------------------------------------------------------------+
  5. | Copyright (c) 2010-2015 Facebook, Inc. (http://www.facebook.com) |
  6. +----------------------------------------------------------------------+
  7. | This source file is subject to version 3.01 of the PHP license, |
  8. | that is bundled with this package in the file LICENSE, and is |
  9. | available through the world-wide-web at the following url: |
  10. | http://www.php.net/license/3_01.txt |
  11. | If you did not receive a copy of the PHP license and are unable to |
  12. | obtain it through the world-wide-web, please send a note to |
  13. | license@php.net so we can mail you a copy immediately. |
  14. +----------------------------------------------------------------------+
  15. */
  16. #ifndef incl_HPHP_JIT_VASM_UNIT_H_
  17. #define incl_HPHP_JIT_VASM_UNIT_H_
  18. #include "hphp/runtime/base/datatype.h"
  19. #include "hphp/runtime/vm/jit/types.h"
  20. #include "hphp/runtime/vm/jit/containers.h"
  21. #include "hphp/runtime/vm/jit/vasm.h"
  22. #include "hphp/runtime/vm/jit/vasm-instr.h"
  23. #include "hphp/runtime/vm/jit/vasm-reg.h"
  24. #include "hphp/util/immed.h"
  25. #include <functional>
  26. #include <type_traits>
  27. namespace HPHP { namespace jit {
  28. ///////////////////////////////////////////////////////////////////////////////
  29. /*
  30. * Block of Vinstrs, managed by Vunit.
  31. */
  32. struct Vblock {
  33. explicit Vblock(AreaIndex area) : area(area) {}
  34. AreaIndex area;
  35. jit::vector<Vinstr> code;
  36. };
  37. /*
  38. * Vector of Vregs, for Vtuples and VcallArgs.
  39. */
  40. using VregList = jit::vector<Vreg>;
  41. /*
  42. * Source operands for vcall/vinvoke instructions, packed into a struct for
  43. * convenience and to keep the instructions compact.
  44. */
  45. struct VcallArgs {
  46. VregList args;
  47. VregList simdArgs;
  48. VregList stkArgs;
  49. };
  50. ///////////////////////////////////////////////////////////////////////////////
  51. /*
  52. * Vasm constant.
  53. *
  54. * Either a 1, 4, or 8 byte unsigned value, 8 byte double, or the disp32 part
  55. * of a thread-local address of an immutable constant that varies by
  56. * thread. Constants may represent an undefined value of any type, indicated by
  57. * the isUndef member. Also contains convenience constructors for various
  58. * pointer and enum types.
  59. */
  60. struct Vconst {
  61. enum Kind { Quad, Long, Byte, Double, ThreadLocal };
  62. using ullong = unsigned long long;
  63. using ulong = unsigned long;
  64. Vconst() : kind(Quad), val(0) {}
  65. explicit Vconst(Kind k) : kind(k), isUndef(true), val(0) {}
  66. explicit Vconst(bool b) : kind(Byte), val(b) {}
  67. explicit Vconst(uint8_t b) : kind(Byte), val(b) {}
  68. explicit Vconst(int8_t b) : Vconst(uint8_t(b)) {}
  69. explicit Vconst(uint32_t i) : kind(Long), val(i) {}
  70. // For historical reasons Vconst(int) produces an 8-byte constant.
  71. explicit Vconst(int32_t i) : Vconst(int64_t(i)) {}
  72. explicit Vconst(uint16_t) = delete;
  73. explicit Vconst(int16_t) = delete;
  74. explicit Vconst(ullong i) : kind(Quad), val(i) {}
  75. explicit Vconst(long long i) : Vconst(ullong(i)) {}
  76. explicit Vconst(ulong i) : Vconst(ullong(i)) {}
  77. explicit Vconst(long i) : Vconst(ullong(i)) {}
  78. explicit Vconst(const void* p) : Vconst(uintptr_t(p)) {}
  79. explicit Vconst(double d) : kind(Double), doubleVal(d) {}
  80. explicit Vconst(Vptr tl) : kind(ThreadLocal), disp(tl.disp) {
  81. assertx(!tl.base.isValid() && !tl.index.isValid() && tl.seg == Vptr::FS);
  82. }
  83. template<
  84. class E,
  85. class Enable = typename std::enable_if<std::is_enum<E>::value>::type
  86. >
  87. explicit Vconst(E e) : Vconst(typename std::underlying_type<E>::type(e)) {}
  88. template<class R, class... Args>
  89. explicit Vconst(R (*fn)(Args...)) : Vconst(uintptr_t(fn)) {}
  90. bool operator==(Vconst other) const {
  91. return kind == other.kind &&
  92. ((isUndef && other.isUndef) || val == other.val);
  93. }
  94. struct Hash {
  95. size_t operator()(Vconst c) const {
  96. return
  97. std::hash<uint64_t>()(c.val) ^ std::hash<int>()(c.kind) ^ c.isUndef;
  98. }
  99. };
  100. /////////////////////////////////////////////////////////////////////////////
  101. // Data members.
  102. Kind kind;
  103. bool isUndef{false};
  104. union {
  105. uint64_t val;
  106. double doubleVal;
  107. int64_t disp; // really, int32 offset from %fs
  108. };
  109. };
  110. ///////////////////////////////////////////////////////////////////////////////
  111. /*
  112. * A Vunit contains all the assets that make up a vasm compilation unit. It is
  113. * responsible for allocating new blocks, Vregs, and tuples.
  114. */
  115. struct Vunit {
  116. /*
  117. * Create a new block in the given area, returning its id.
  118. */
  119. Vlabel makeBlock(AreaIndex area);
  120. /*
  121. * Create a block intended to be used temporarily, as part of modifying
  122. * existing code.
  123. *
  124. * Although not necessary for correctness, the block may be freed with
  125. * freeScratchBlock when finished.
  126. */
  127. Vlabel makeScratchBlock();
  128. /*
  129. * Free a scratch block when finished with it. There must be no references
  130. * to this block in reachable code.
  131. */
  132. void freeScratchBlock(Vlabel);
  133. /*
  134. * Make various Vunit-managed vasm structures.
  135. */
  136. Vreg makeReg() { return Vreg{next_vr++}; }
  137. Vtuple makeTuple(VregList&& regs);
  138. Vtuple makeTuple(const VregList& regs);
  139. VcallArgsId makeVcallArgs(VcallArgs&& args);
  140. /*
  141. * Create or return a register representing the given constant value.
  142. */
  143. Vreg makeConst(Vconst);
  144. template<typename T> Vreg makeConst(T v) { return makeConst(Vconst{v}); }
  145. /*
  146. * Return true iff this Vunit needs register allocation before it can be
  147. * emitted, either because it uses virtual registers or contains instructions
  148. * that must be lowered by xls.
  149. */
  150. bool needsRegAlloc() const;
  151. /////////////////////////////////////////////////////////////////////////////
  152. // Data members.
  153. unsigned next_vr{Vreg::V0};
  154. unsigned next_point{0};
  155. Vlabel entry;
  156. jit::vector<Vblock> blocks;
  157. jit::hash_map<Vconst,Vreg,Vconst::Hash> constToReg;
  158. jit::hash_map<size_t,Vconst> regToConst;
  159. jit::vector<VregList> tuples;
  160. jit::vector<VcallArgs> vcallArgs;
  161. bool padding{false};
  162. };
  163. ///////////////////////////////////////////////////////////////////////////////
  164. }}
  165. #endif