Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(154)

Side by Side Diff: src/compiler/load-elimination.cc

Issue 2113623002: Revert of [compiler] Load elimination now traverses CheckTaggedPointer. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@p7-base
Patch Set: Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/compiler/load-elimination.h" 5 #include "src/compiler/load-elimination.h"
6 6
7 #include "src/compiler/graph.h" 7 #include "src/compiler/graph.h"
8 #include "src/compiler/node-properties.h" 8 #include "src/compiler/node-properties.h"
9 #include "src/compiler/simplified-operator.h" 9 #include "src/compiler/simplified-operator.h"
10 #include "src/types.h" 10 #include "src/types.h"
11 11
12 namespace v8 { 12 namespace v8 {
13 namespace internal { 13 namespace internal {
14 namespace compiler { 14 namespace compiler {
15 15
16 LoadElimination::~LoadElimination() {} 16 LoadElimination::~LoadElimination() {}
17 17
18 Reduction LoadElimination::Reduce(Node* node) { 18 Reduction LoadElimination::Reduce(Node* node) {
19 switch (node->opcode()) { 19 switch (node->opcode()) {
20 case IrOpcode::kLoadField: 20 case IrOpcode::kLoadField:
21 return ReduceLoadField(node); 21 return ReduceLoadField(node);
22 default: 22 default:
23 break; 23 break;
24 } 24 }
25 return NoChange(); 25 return NoChange();
26 } 26 }
27 27
28 namespace {
29
30 // If {node} is a CheckTaggedPointer, follow its input until {node} is no
31 // longer a CheckTaggedPointer.
32 Node* NormalizeCheckTaggedPointer(Node* node) {
33 while (node->opcode() == IrOpcode::kCheckTaggedPointer) {
34 node = NodeProperties::GetValueInput(node, 0);
35 }
36 return node;
37 }
38
39 } // namespace
40
41 Reduction LoadElimination::ReduceLoadField(Node* node) { 28 Reduction LoadElimination::ReduceLoadField(Node* node) {
42 DCHECK_EQ(IrOpcode::kLoadField, node->opcode()); 29 DCHECK_EQ(IrOpcode::kLoadField, node->opcode());
43 FieldAccess const access = FieldAccessOf(node->op()); 30 FieldAccess const access = FieldAccessOf(node->op());
44 Node* object = NodeProperties::GetValueInput(node, 0); 31 Node* object = NodeProperties::GetValueInput(node, 0);
45 for (Node* effect = NodeProperties::GetEffectInput(node);; 32 for (Node* effect = NodeProperties::GetEffectInput(node);;
46 effect = NodeProperties::GetEffectInput(effect)) { 33 effect = NodeProperties::GetEffectInput(effect)) {
47 switch (effect->opcode()) { 34 switch (effect->opcode()) {
48 case IrOpcode::kLoadField: { 35 case IrOpcode::kLoadField: {
49 FieldAccess const effect_access = FieldAccessOf(effect->op()); 36 FieldAccess const effect_access = FieldAccessOf(effect->op());
50 if (object == NodeProperties::GetValueInput(effect, 0) && 37 if (object == NodeProperties::GetValueInput(effect, 0) &&
51 access == effect_access && effect_access.type->Is(access.type)) { 38 access == effect_access && effect_access.type->Is(access.type)) {
52 Node* const value = effect; 39 Node* const value = effect;
53 ReplaceWithValue(node, value); 40 ReplaceWithValue(node, value);
54 return Replace(value); 41 return Replace(value);
55 } 42 }
56 break; 43 break;
57 } 44 }
58 case IrOpcode::kStoreField: { 45 case IrOpcode::kStoreField: {
59 if (access == FieldAccessOf(effect->op())) { 46 if (access == FieldAccessOf(effect->op())) {
60 Node* value_input = NormalizeCheckTaggedPointer( 47 if (object == NodeProperties::GetValueInput(effect, 0)) {
61 NodeProperties::GetValueInput(effect, 0));
62 if (object == value_input) {
63 Node* const value = NodeProperties::GetValueInput(effect, 1); 48 Node* const value = NodeProperties::GetValueInput(effect, 1);
64 Type* stored_value_type = NodeProperties::GetType(value); 49 Type* stored_value_type = NodeProperties::GetType(value);
65 Type* load_type = NodeProperties::GetType(node); 50 Type* load_type = NodeProperties::GetType(node);
66 // Make sure the replacement's type is a subtype of the node's 51 // Make sure the replacement's type is a subtype of the node's
67 // type. Otherwise we could confuse optimizations that were 52 // type. Otherwise we could confuse optimizations that were
68 // based on the original type. 53 // based on the original type.
69 if (stored_value_type->Is(load_type)) { 54 if (stored_value_type->Is(load_type)) {
70 ReplaceWithValue(node, value); 55 ReplaceWithValue(node, value);
71 return Replace(value); 56 return Replace(value);
72 } else { 57 } else {
73 Node* renamed = graph()->NewNode( 58 Node* renamed = graph()->NewNode(
74 simplified()->TypeGuard(Type::Intersect( 59 simplified()->TypeGuard(Type::Intersect(
75 stored_value_type, load_type, graph()->zone())), 60 stored_value_type, load_type, graph()->zone())),
76 value, NodeProperties::GetControlInput(node)); 61 value, NodeProperties::GetControlInput(node));
77 ReplaceWithValue(node, renamed); 62 ReplaceWithValue(node, renamed);
78 return Replace(renamed); 63 return Replace(renamed);
79 } 64 }
80 } 65 }
81 // TODO(turbofan): Alias analysis to the rescue? 66 // TODO(turbofan): Alias analysis to the rescue?
82 return NoChange(); 67 return NoChange();
83 } 68 }
84 break; 69 break;
85 } 70 }
86 case IrOpcode::kBeginRegion: 71 case IrOpcode::kBeginRegion:
87 case IrOpcode::kStoreBuffer: 72 case IrOpcode::kStoreBuffer:
88 case IrOpcode::kStoreElement: { 73 case IrOpcode::kStoreElement: {
89 // These can never interfere with field loads. 74 // These can never interfere with field loads.
90 break; 75 break;
91 } 76 }
92 case IrOpcode::kFinishRegion: 77 case IrOpcode::kFinishRegion: {
93 case IrOpcode::kCheckTaggedPointer: {
94 // "Look through" FinishRegion nodes to make LoadElimination capable 78 // "Look through" FinishRegion nodes to make LoadElimination capable
95 // of looking into atomic regions. 79 // of looking into atomic regions.
96 if (object == effect) object = NodeProperties::GetValueInput(effect, 0); 80 if (object == effect) object = NodeProperties::GetValueInput(effect, 0);
97 break; 81 break;
98 } 82 }
99 case IrOpcode::kAllocate: { 83 case IrOpcode::kAllocate: {
100 // Allocations don't interfere with field loads. In case we see the 84 // Allocations don't interfere with field loads. In case we see the
101 // actual allocation for the {object} we can abort. 85 // actual allocation for the {object} we can abort.
102 if (object == effect) return NoChange(); 86 if (object == effect) return NoChange();
103 break; 87 break;
104 } 88 }
105 default: { 89 default: {
106 if (!effect->op()->HasProperty(Operator::kNoWrite) || 90 if (!effect->op()->HasProperty(Operator::kNoWrite) ||
107 effect->op()->EffectInputCount() != 1) { 91 effect->op()->EffectInputCount() != 1) {
108 return NoChange(); 92 return NoChange();
109 } 93 }
110 break; 94 break;
111 } 95 }
112 } 96 }
113 } 97 }
114 UNREACHABLE(); 98 UNREACHABLE();
115 return NoChange(); 99 return NoChange();
116 } 100 }
117 101
118 } // namespace compiler 102 } // namespace compiler
119 } // namespace internal 103 } // namespace internal
120 } // namespace v8 104 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698