2 +----------------------------------------------------------------------+
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-2014 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 +----------------------------------------------------------------------+
16 #include "hphp/runtime/vm/jit/analysis.h"
18 #include "hphp/util/assertions.h"
19 #include "hphp/runtime/vm/jit/ssa-tmp.h"
20 #include "hphp/runtime/vm/jit/ir-instruction.h"
21 #include "hphp/runtime/vm/jit/block.h"
22 #include "hphp/runtime/vm/jit/id-set.h"
24 namespace HPHP
{ namespace jit
{
26 //////////////////////////////////////////////////////////////////////
28 const SSATmp
* canonical(const SSATmp
* val
) {
29 return canonical(const_cast<SSATmp
*>(val
));
32 SSATmp
* canonical(SSATmp
* value
) {
33 if (value
== nullptr) return nullptr;
35 auto inst
= value
->inst();
37 while (inst
->isPassthrough()) {
38 value
= inst
->getPassthroughValue();
44 //////////////////////////////////////////////////////////////////////
46 Block
* findDefiningBlock(const SSATmp
* t
, const IdomVector
& idoms
) {
47 assertx(!t
->inst()->is(DefConst
));
48 auto const srcInst
= t
->inst();
50 if (srcInst
->hasEdges()) {
51 auto const next
= srcInst
->next();
52 UNUSED
auto const taken
= srcInst
->taken();
55 "hasEdges instruction defining a dst had no edges:\n {}\n",
58 for (const auto& arc
: next
->preds()) {
59 auto pred
= arc
.from();
60 if (pred
!= srcInst
->block() && !dominates(next
, pred
, idoms
)) {
67 return srcInst
->block();
70 //////////////////////////////////////////////////////////////////////
72 bool is_tmp_usable(const IdomVector
& idoms
,
75 if (tmp
->inst()->is(DefConst
)) return true;
76 auto const definingBlock
= findDefiningBlock(tmp
, idoms
);
77 if (!definingBlock
) return false;
78 return dominates(definingBlock
, where
, idoms
);
81 //////////////////////////////////////////////////////////////////////
83 SSATmp
* least_common_ancestor(SSATmp
* s1
, SSATmp
* s2
) {
84 if (s1
== s2
) return s1
;
85 if (s1
== nullptr || s2
== nullptr) return nullptr;
89 auto const step
= [] (SSATmp
* v
) {
90 assertx(v
!= nullptr);
91 return v
->inst()->isPassthrough() ?
92 v
->inst()->getPassthroughValue() :
96 auto const process
= [&] (SSATmp
*& v
) {
97 if (v
== nullptr) return false;
98 if (seen
[v
]) return true;
104 while (s1
!= nullptr || s2
!= nullptr) {
105 if (process(s1
)) return s1
;
106 if (process(s2
)) return s2
;
112 //////////////////////////////////////////////////////////////////////