2 +----------------------------------------------------------------------+
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-2013 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 +----------------------------------------------------------------------+
17 #ifndef incl_HPHP_JIT_VASM_H_
18 #define incl_HPHP_JIT_VASM_H_
20 #include "hphp/runtime/base/rds.h"
22 #include "hphp/runtime/vm/jit/types.h"
23 #include "hphp/runtime/vm/jit/containers.h"
25 #include "hphp/util/safe-cast.h"
27 #include <boost/dynamic_bitset.hpp>
28 #include <folly/Range.h>
31 namespace HPHP
{ namespace jit
{
32 ///////////////////////////////////////////////////////////////////////////////
40 ///////////////////////////////////////////////////////////////////////////////
43 * If Trace::moduleEnabled(Trace::llvm) || RuntimeOption::EvalJitLLVMCounters,
44 * these two RDS values are used to count the number of bytecodes executed by
45 * code emitted from their respective backends.
47 extern rds::Link
<uint64_t> g_bytecodesLLVM
;
48 extern rds::Link
<uint64_t> g_bytecodesVasm
;
50 ///////////////////////////////////////////////////////////////////////////////
52 #define DECLARE_VNUM(Vnum, check, prefix) \
55 explicit Vnum(size_t n) : n(safe_cast<uint32_t>(n)) {} \
57 /* implicit */ operator size_t() const { \
58 if (check) assertx(n != kInvalidId); \
62 bool isValid() const { \
63 return n != kInvalidId; \
66 std::string toString() const { \
67 if (n == kInvalidId) return prefix "?"; \
68 return folly::to<std::string>(prefix, n); \
72 static constexpr uint32_t kInvalidId = 0xffffffff; \
73 uint32_t n{kInvalidId}; \
77 * Vlabel wraps a block number.
79 DECLARE_VNUM(Vlabel
, true, "B");
82 * Vpoint is a handle to record or retrieve a code address.
84 DECLARE_VNUM(Vpoint
, false, "P");
87 * Vtuple is an index to a tuple in Vunit::tuples.
89 DECLARE_VNUM(Vtuple
, true, "T");
92 * VcallArgsId is an index to a VcallArgs in Vunit::vcallArgs.
94 DECLARE_VNUM(VcallArgsId
, true, "V");
101 enum class VregKind
: uint8_t { Any
, Gpr
, Simd
, Sf
};
103 ///////////////////////////////////////////////////////////////////////////////
106 * Assert invariants on a Vunit.
111 * Check that each block has exactly one terminal instruction at the end.
113 bool checkBlockEnd(const Vunit
& v
, Vlabel b
);
118 void allocateRegisters(Vunit
&, const Abi
&);
119 void fuseBranches(Vunit
&);
120 void optimizeExits(Vunit
&);
121 void optimizeJmps(Vunit
&);
122 void optimizeCopies(Vunit
&, const Abi
&);
123 void removeDeadCode(Vunit
&);
124 void removeTrivialNops(Vunit
&);
125 template<typename Folder
> void foldImms(Vunit
&);
127 ///////////////////////////////////////////////////////////////////////////////
130 * Get the successors of a block or instruction. If given a non-const
131 * reference, the resulting Range will allow mutation of the Vlabels.
133 folly::Range
<Vlabel
*> succs(Vinstr
& inst
);
134 folly::Range
<Vlabel
*> succs(Vblock
& block
);
135 folly::Range
<const Vlabel
*> succs(const Vinstr
& inst
);
136 folly::Range
<const Vlabel
*> succs(const Vblock
& block
);
139 * Sort blocks in reverse-postorder starting from `unit.entry'.
141 jit::vector
<Vlabel
> sortBlocks(const Vunit
& unit
);
144 * Group blocks into main, cold, and frozen while preserving relative order
147 jit::vector
<Vlabel
> layoutBlocks(const Vunit
& unit
);
150 * Return a bitset, keyed by Vlabel, indicating which blocks are targets of
153 boost::dynamic_bitset
<> backedgeTargets(const Vunit
& unit
,
154 const jit::vector
<Vlabel
>& rpoBlocks
);
156 ///////////////////////////////////////////////////////////////////////////////