1 | /*
|
---|
2 | * Copyright (C) 2015-2018 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 |
|
---|
26 | #include "config.h"
|
---|
27 | #include "DFGCombinedLiveness.h"
|
---|
28 |
|
---|
29 | #if ENABLE(DFG_JIT)
|
---|
30 |
|
---|
31 | #include "DFGAvailabilityMap.h"
|
---|
32 | #include "DFGBlockMapInlines.h"
|
---|
33 | #include "JSCJSValueInlines.h"
|
---|
34 |
|
---|
35 | namespace JSC { namespace DFG {
|
---|
36 |
|
---|
37 | static void addBytecodeLiveness(Graph& graph, AvailabilityMap& availabilityMap, NodeSet& seen, Node* node)
|
---|
38 | {
|
---|
39 | graph.forAllLiveInBytecode(
|
---|
40 | node->origin.forExit,
|
---|
41 | [&] (Operand reg) {
|
---|
42 | availabilityMap.closeStartingWithLocal(
|
---|
43 | reg,
|
---|
44 | [&] (Node* node) -> bool {
|
---|
45 | return seen.contains(node);
|
---|
46 | },
|
---|
47 | [&] (Node* node) -> bool {
|
---|
48 | return seen.add(node).isNewEntry;
|
---|
49 | });
|
---|
50 | });
|
---|
51 | }
|
---|
52 |
|
---|
53 | NodeSet liveNodesAtHead(Graph& graph, BasicBlock* block)
|
---|
54 | {
|
---|
55 | NodeSet seen;
|
---|
56 | for (NodeFlowProjection node : block->ssa->liveAtHead) {
|
---|
57 | if (node.kind() == NodeFlowProjection::Primary)
|
---|
58 | seen.addVoid(node.node());
|
---|
59 | }
|
---|
60 |
|
---|
61 | addBytecodeLiveness(graph, block->ssa->availabilityAtHead, seen, block->at(0));
|
---|
62 | return seen;
|
---|
63 | }
|
---|
64 |
|
---|
65 | CombinedLiveness::CombinedLiveness(Graph& graph)
|
---|
66 | : liveAtHead(graph)
|
---|
67 | , liveAtTail(graph)
|
---|
68 | {
|
---|
69 | // First compute
|
---|
70 | // - The liveAtHead for each block.
|
---|
71 | // - The liveAtTail for blocks that won't properly propagate
|
---|
72 | // the information based on their empty successor list.
|
---|
73 | for (BasicBlock* block : graph.blocksInNaturalOrder()) {
|
---|
74 | liveAtHead[block] = liveNodesAtHead(graph, block);
|
---|
75 |
|
---|
76 | // If we don't have successors, we can't rely on the propagation below. This doesn't usually
|
---|
77 | // do anything for terminal blocks, since the last node is usually a return, so nothing is live
|
---|
78 | // after it. However, we may also have the end of the basic block be:
|
---|
79 | //
|
---|
80 | // ForceOSRExit
|
---|
81 | // Unreachable
|
---|
82 | //
|
---|
83 | // And things may definitely be live in bytecode at that point in the program.
|
---|
84 | if (!block->numSuccessors()) {
|
---|
85 | NodeSet seen;
|
---|
86 | addBytecodeLiveness(graph, block->ssa->availabilityAtTail, seen, block->last());
|
---|
87 | liveAtTail[block] = seen;
|
---|
88 | }
|
---|
89 | }
|
---|
90 |
|
---|
91 | // Now compute the liveAtTail by unifying the liveAtHead of the successors.
|
---|
92 | for (BasicBlock* block : graph.blocksInNaturalOrder()) {
|
---|
93 | for (BasicBlock* successor : block->successors()) {
|
---|
94 | for (Node* node : liveAtHead[successor])
|
---|
95 | liveAtTail[block].addVoid(node);
|
---|
96 | }
|
---|
97 | }
|
---|
98 | }
|
---|
99 |
|
---|
100 | } } // namespace JSC::DFG
|
---|
101 |
|
---|
102 | #endif // ENABLE(DFG_JIT)
|
---|
103 |
|
---|