Break tracelets after CGetS
[hiphop-php.git] / hphp / runtime / vm / jit / translator-inl.h
blobd9bc3bb116031d9dd96c05053b90f3df3643c11f
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-present 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_TRANSLATOR_INL_H_
18 #error "translator-inl.h should only be included by translator.h"
19 #endif
21 namespace HPHP { namespace jit {
23 ///////////////////////////////////////////////////////////////////////////////
24 // TransContext.
26 inline TransContext::TransContext(
27 TransID id, TransKind kind, TransFlags flags,
28 SrcKey sk, FPInvOffset spOff, int optIndex, Op fpushOff)
29 : transID(id)
30 , optIndex(optIndex)
31 , kind(kind)
32 , flags(flags)
33 , initSpOffset(spOff)
34 , callerFPushOp(fpushOff)
35 , func(sk.valid() ? sk.func() : nullptr)
36 , initBcOffset(sk.offset())
37 , hasThis(sk.hasThis())
38 , prologue(sk.prologue())
39 , resumeMode(sk.resumeMode())
42 inline SrcKey TransContext::srcKey() const {
43 if (prologue) {
44 assertx(resumeMode == ResumeMode::None);
45 return SrcKey { func, initBcOffset, SrcKey::PrologueTag{} };
47 return SrcKey { func, initBcOffset, resumeMode, hasThis };
50 ///////////////////////////////////////////////////////////////////////////////
51 // Control flow information.
53 inline ControlFlowInfo opcodeControlFlowInfo(const Op op, bool inlining) {
54 switch (op) {
55 case Op::Jmp:
56 case Op::JmpNS:
57 case Op::JmpZ:
58 case Op::JmpNZ:
59 case Op::Switch:
60 case Op::SSwitch:
61 case Op::CreateCont:
62 case Op::Yield:
63 case Op::YieldK:
64 case Op::YieldFromDelegate:
65 case Op::RetC:
66 case Op::RetM:
67 case Op::RetCSuspended:
68 case Op::Exit:
69 case Op::Fatal:
70 case Op::IterNext:
71 case Op::IterNextK:
72 case Op::LIterNext:
73 case Op::LIterNextK:
74 case Op::IterInit: // May branch to fail case.
75 case Op::IterInitK: // Ditto
76 case Op::LIterInit: // Ditto
77 case Op::LIterInitK: // Ditto
78 case Op::IterBreak:
79 case Op::Throw:
80 case Op::Eval:
81 case Op::NativeImpl:
82 case Op::BreakTraceHint:
83 case Op::MemoGet:
84 case Op::MemoGetEager:
85 return ControlFlowInfo::BreaksBB;
86 case Op::Await:
87 case Op::AwaitAll:
88 return inlining ? ControlFlowInfo::ChangesPC : ControlFlowInfo::BreaksBB;
89 case Op::FCall:
90 case Op::ContEnter:
91 case Op::ContRaise:
92 case Op::ContEnterDelegate:
93 case Op::Incl:
94 case Op::InclOnce:
95 case Op::Req:
96 case Op::ReqOnce:
97 case Op::ReqDoc:
98 return ControlFlowInfo::ChangesPC;
99 default:
100 return ControlFlowInfo::None;
104 inline bool opcodeChangesPC(const Op op) {
105 return opcodeControlFlowInfo(op, false) >= ControlFlowInfo::ChangesPC;
108 inline bool opcodeBreaksBB(const Op op, bool inlining) {
109 if (op == Op::ClsCns || op == Op::CGetS) {
110 // side exits if it misses in the RDS, and may produce an overly
111 // specific type without guarding if the class comes from an
112 // object (during form_region, the class will appear to be a
113 // specific type, but during irgen, it will probably be a generic
114 // type).
116 // We can't mark it BreaksBB because BreaksBB => opcodeChangesPC
117 return true;
119 return opcodeControlFlowInfo(op, inlining) == ControlFlowInfo::BreaksBB;
122 inline bool opcodeIgnoresInnerType(const Op op) {
123 switch (op) {
124 case Op::PopV:
125 case Op::RetC:
126 case Op::RetCSuspended:
127 case Op::RetM:
128 return true;
129 default:
130 return false;
134 ///////////////////////////////////////////////////////////////////////////////
135 // Input and output information.
137 inline std::string InputInfo::pretty() const {
138 std::string p = show(loc);
139 if (dontBreak) p += ":dc";
140 if (dontGuard) p += ":dg";
141 if (dontGuardInner) p += ":dgi";
142 return p;
145 inline std::string InputInfoVec::pretty() const {
146 std::string retval;
147 for (size_t i = 0; i < size(); i++) {
148 retval += (*this)[i].pretty();
149 if (i != size() - 1) {
150 retval += std::string(" ");
153 return retval;
156 ///////////////////////////////////////////////////////////////////////////////
157 // InstrFlags.
159 namespace InstrFlags {
161 inline Operands operator|(const Operands& l, const Operands& r) {
162 return Operands(int(r) | int(l));
167 ///////////////////////////////////////////////////////////////////////////////