Add a profile-guided code layout pass
[hiphop-php.git] / hphp / runtime / vm / jit / vasm.h
blobad83d079560044b0bb3e5c2408f48365f7cab268
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
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>
29 #include <iosfwd>
31 namespace HPHP { namespace jit {
32 ///////////////////////////////////////////////////////////////////////////////
34 struct Vunit;
35 struct Vinstr;
36 struct Vblock;
37 struct Vreg;
38 struct Abi;
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) \
53 struct Vnum { \
54 Vnum() {} \
55 explicit Vnum(size_t n) : n(safe_cast<uint32_t>(n)) {} \
57 /* implicit */ operator size_t() const { \
58 if (check) assertx(n != kInvalidId); \
59 return n; \
60 } \
62 bool isValid() const { \
63 return n != kInvalidId; \
64 } \
66 std::string toString() const { \
67 if (n == kInvalidId) return prefix "?"; \
68 return folly::to<std::string>(prefix, n); \
69 } \
71 private: \
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");
96 #undef DECLARE_VNUM
99 * Vreg discriminator.
101 enum class VregKind : uint8_t { Any, Gpr, Simd, Sf };
103 ///////////////////////////////////////////////////////////////////////////////
106 * Assert invariants on a Vunit.
108 bool check(Vunit&);
111 * Check that each block has exactly one terminal instruction at the end.
113 bool checkBlockEnd(const Vunit& v, Vlabel b);
116 * Passes.
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
145 * with each section.
147 jit::vector<Vlabel> layoutBlocks(const Vunit& unit);
150 * Return a bitset, keyed by Vlabel, indicating which blocks are targets of
151 * backedges.
153 boost::dynamic_bitset<> backedgeTargets(const Vunit& unit,
154 const jit::vector<Vlabel>& rpoBlocks);
156 ///////////////////////////////////////////////////////////////////////////////
159 #endif