DFGCommon.h 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. /*
  2. * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions
  6. * are met:
  7. * 1. Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * 2. Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. *
  13. * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
  14. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  15. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  16. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
  17. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  18. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  19. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  20. * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  21. * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  22. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  23. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  24. */
  25. #ifndef DFGCommon_h
  26. #define DFGCommon_h
  27. #include <wtf/Platform.h>
  28. #if ENABLE(DFG_JIT)
  29. #include "CodeOrigin.h"
  30. #include "Options.h"
  31. #include "VirtualRegister.h"
  32. /* DFG_ENABLE() - turn on a specific features in the DFG JIT */
  33. #define DFG_ENABLE(DFG_FEATURE) (defined DFG_ENABLE_##DFG_FEATURE && DFG_ENABLE_##DFG_FEATURE)
  34. // Emit various logging information for debugging, including dumping the dataflow graphs.
  35. #define DFG_ENABLE_DEBUG_VERBOSE 0
  36. // Emit dumps during propagation, in addition to just after.
  37. #define DFG_ENABLE_DEBUG_PROPAGATION_VERBOSE 0
  38. // Emit logging for OSR exit value recoveries at every node, not just nodes that
  39. // actually has speculation checks.
  40. #define DFG_ENABLE_VERBOSE_VALUE_RECOVERIES 0
  41. // Enable generation of dynamic checks into the instruction stream.
  42. #if !ASSERT_DISABLED
  43. #define DFG_ENABLE_JIT_ASSERT 1
  44. #else
  45. #define DFG_ENABLE_JIT_ASSERT 0
  46. #endif
  47. // Consistency check contents compiler data structures.
  48. #define DFG_ENABLE_CONSISTENCY_CHECK 0
  49. // Emit a breakpoint into the head of every generated function, to aid debugging in GDB.
  50. #define DFG_ENABLE_JIT_BREAK_ON_EVERY_FUNCTION 0
  51. // Emit a breakpoint into the head of every generated block, to aid debugging in GDB.
  52. #define DFG_ENABLE_JIT_BREAK_ON_EVERY_BLOCK 0
  53. // Emit a breakpoint into the head of every generated node, to aid debugging in GDB.
  54. #define DFG_ENABLE_JIT_BREAK_ON_EVERY_NODE 0
  55. // Emit a pair of xorPtr()'s on regT0 with the node index to make it easy to spot node boundaries in disassembled code.
  56. #define DFG_ENABLE_XOR_DEBUG_AID 0
  57. // Emit a breakpoint into the speculation failure code.
  58. #define DFG_ENABLE_JIT_BREAK_ON_SPECULATION_FAILURE 0
  59. // Disable the DFG JIT without having to touch Platform.h
  60. #define DFG_DEBUG_LOCAL_DISBALE 0
  61. // Enable OSR entry from baseline JIT.
  62. #define DFG_ENABLE_OSR_ENTRY ENABLE(DFG_JIT)
  63. // Generate stats on how successful we were in making use of the DFG jit, and remaining on the hot path.
  64. #define DFG_ENABLE_SUCCESS_STATS 0
  65. // Enable verification that the DFG is able to insert code for control flow edges.
  66. #define DFG_ENABLE_EDGE_CODE_VERIFICATION 0
  67. namespace JSC { namespace DFG {
  68. struct Node;
  69. typedef uint32_t BlockIndex;
  70. static const BlockIndex NoBlock = UINT_MAX;
  71. struct NodePointerTraits {
  72. static Node* defaultValue() { return 0; }
  73. static void dump(Node* value, PrintStream& out);
  74. };
  75. // Use RefChildren if the child ref counts haven't already been adjusted using
  76. // other means and either of the following is true:
  77. // - The node you're creating is MustGenerate.
  78. // - The place where you're inserting a reference to the node you're creating
  79. // will not also do RefChildren.
  80. enum RefChildrenMode {
  81. RefChildren,
  82. DontRefChildren
  83. };
  84. // Use RefNode if you know that the node will be used from another node, and you
  85. // will not already be ref'ing the node to account for that use.
  86. enum RefNodeMode {
  87. RefNode,
  88. DontRefNode
  89. };
  90. inline bool verboseCompilationEnabled()
  91. {
  92. #if DFG_ENABLE(DEBUG_VERBOSE)
  93. return true;
  94. #else
  95. return Options::verboseCompilation() || Options::dumpGraphAtEachPhase();
  96. #endif
  97. }
  98. inline bool logCompilationChanges()
  99. {
  100. #if DFG_ENABLE(DEBUG_VERBOSE)
  101. return true;
  102. #else
  103. return verboseCompilationEnabled() || Options::logCompilationChanges();
  104. #endif
  105. }
  106. inline bool shouldDumpGraphAtEachPhase()
  107. {
  108. #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
  109. return true;
  110. #else
  111. return Options::dumpGraphAtEachPhase();
  112. #endif
  113. }
  114. inline bool validationEnabled()
  115. {
  116. #if !ASSERT_DISABLED
  117. return true;
  118. #else
  119. return Options::validateGraph() || Options::validateGraphAtEachPhase();
  120. #endif
  121. }
  122. enum SpillRegistersMode { NeedToSpill, DontSpill };
  123. enum NoResultTag { NoResult };
  124. enum OptimizationFixpointState { BeforeFixpoint, FixpointNotConverged, FixpointConverged };
  125. // Describes the form you can expect the entire graph to be in.
  126. enum GraphForm {
  127. // LoadStore form means that basic blocks may freely use GetLocal, SetLocal,
  128. // GetLocalUnlinked, and Flush for accessing local variables and indicating
  129. // where their live ranges ought to be. Data flow between local accesses is
  130. // implicit. Liveness is only explicit at block heads (variablesAtHead).
  131. // This is only used by the DFG simplifier and is only preserved by same.
  132. //
  133. // For example, LoadStore form gives no easy way to determine which SetLocal's
  134. // flow into a GetLocal. As well, LoadStore form implies no restrictions on
  135. // redundancy: you can freely emit multiple GetLocals, or multiple SetLocals
  136. // (or any combination thereof) to the same local in the same block. LoadStore
  137. // form does not require basic blocks to declare how they affect or use locals,
  138. // other than implicitly by using the local ops and by preserving
  139. // variablesAtHead. Finally, LoadStore allows flexibility in how liveness of
  140. // locals is extended; for example you can replace a GetLocal with a Phantom
  141. // and so long as the Phantom retains the GetLocal's children (i.e. the Phi
  142. // most likely) then it implies that the local is still live but that it need
  143. // not be stored to the stack necessarily. This implies that Phantom can
  144. // reference nodes that have no result, as long as those nodes are valid
  145. // GetLocal children (i.e. Phi, SetLocal, SetArgument).
  146. //
  147. // LoadStore form also implies that Phis need not have children. By default,
  148. // they end up having no children if you enter LoadStore using the canonical
  149. // way (call Graph::dethread).
  150. //
  151. // LoadStore form is suitable for CFG transformations, as well as strength
  152. // reduction, folding, and CSE.
  153. LoadStore,
  154. // ThreadedCPS form means that basic blocks list up-front which locals they
  155. // expect to be live at the head, and which locals they make available at the
  156. // tail. ThreadedCPS form also implies that:
  157. //
  158. // - GetLocals and SetLocals to uncaptured variables are not redundant within
  159. // a basic block.
  160. //
  161. // - All GetLocals and Flushes are linked directly to the last access point
  162. // of the variable, which must not be another GetLocal if the variable is
  163. // uncaptured.
  164. //
  165. // - Phantom(Phi) is not legal, but PhantomLocal is.
  166. //
  167. // ThreadedCPS form is suitable for data flow analysis (CFA, prediction
  168. // propagation), register allocation, and code generation.
  169. ThreadedCPS
  170. };
  171. // Describes the state of the UnionFind structure of VariableAccessData's.
  172. enum UnificationState {
  173. // BasicBlock-local accesses to variables are appropriately unified with each other.
  174. LocallyUnified,
  175. // Unification has been performed globally.
  176. GloballyUnified
  177. };
  178. // Describes how reference counts in the graph behave.
  179. enum RefCountState {
  180. // Everything has refCount() == 1.
  181. EverythingIsLive,
  182. // Set after DCE has run.
  183. ExactRefCount
  184. };
  185. enum OperandSpeculationMode { AutomaticOperandSpeculation, ManualOperandSpeculation };
  186. enum SpeculationDirection { ForwardSpeculation, BackwardSpeculation };
  187. enum ProofStatus { NeedsCheck, IsProved };
  188. inline bool isProved(ProofStatus proofStatus)
  189. {
  190. ASSERT(proofStatus == IsProved || proofStatus == NeedsCheck);
  191. return proofStatus == IsProved;
  192. }
  193. inline ProofStatus proofStatusForIsProved(bool isProved)
  194. {
  195. return isProved ? IsProved : NeedsCheck;
  196. }
  197. template<typename T, typename U>
  198. bool checkAndSet(T& left, U right)
  199. {
  200. if (left == right)
  201. return false;
  202. left = right;
  203. return true;
  204. }
  205. } } // namespace JSC::DFG
  206. namespace WTF {
  207. void printInternal(PrintStream&, JSC::DFG::OptimizationFixpointState);
  208. void printInternal(PrintStream&, JSC::DFG::GraphForm);
  209. void printInternal(PrintStream&, JSC::DFG::UnificationState);
  210. void printInternal(PrintStream&, JSC::DFG::RefCountState);
  211. void printInternal(PrintStream&, JSC::DFG::ProofStatus);
  212. } // namespace WTF
  213. #endif // ENABLE(DFG_JIT)
  214. namespace JSC { namespace DFG {
  215. // Put things here that must be defined even if ENABLE(DFG_JIT) is false.
  216. enum CapabilityLevel { CannotCompile, MayInline, CanCompile, CapabilityLevelNotSet };
  217. // Unconditionally disable DFG disassembly support if the DFG is not compiled in.
  218. inline bool shouldShowDisassembly()
  219. {
  220. #if ENABLE(DFG_JIT)
  221. return Options::showDisassembly() || Options::showDFGDisassembly();
  222. #else
  223. return false;
  224. #endif
  225. }
  226. } } // namespace JSC::DFG
  227. #endif // DFGCommon_h