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

Side by Side Diff: runtime/vm/intermediate_language.cc

Issue 10802025: Fuse compare with branch at graph building time. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 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 | Annotate | Revision Log
« no previous file with comments | « runtime/vm/intermediate_language.h ('k') | runtime/vm/intermediate_language_ia32.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/intermediate_language.h" 5 #include "vm/intermediate_language.h"
6 6
7 #include "vm/bit_vector.h" 7 #include "vm/bit_vector.h"
8 #include "vm/dart_entry.h" 8 #include "vm/dart_entry.h"
9 #include "vm/flow_graph_builder.h" 9 #include "vm/flow_graph_builder.h"
10 #include "vm/flow_graph_compiler.h" 10 #include "vm/flow_graph_compiler.h"
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
163 void CreateArrayComp::SetInputAt(intptr_t i, Value* value) { 163 void CreateArrayComp::SetInputAt(intptr_t i, Value* value) {
164 if (i == 0) { 164 if (i == 0) {
165 inputs_[0] = value; 165 inputs_[0] = value;
166 } else { 166 } else {
167 (*elements_)[i - 1] = value; 167 (*elements_)[i - 1] = value;
168 } 168 }
169 } 169 }
170 170
171 171
172 intptr_t BranchInstr::InputCount() const { 172 intptr_t BranchInstr::InputCount() const {
173 return is_fused_with_comparison() ? fused_with_comparison_->InputCount() : 1; 173 return 2;
174 } 174 }
175 175
176 176
177 Value* BranchInstr::InputAt(intptr_t i) const { 177 Value* BranchInstr::InputAt(intptr_t i) const {
178 if (is_fused_with_comparison()) { 178 if (i == 0) return left();
179 return fused_with_comparison_->InputAt(i); 179 if (i == 1) return right();
180 }
181 if (i == 0) return value();
182 UNREACHABLE(); 180 UNREACHABLE();
183 return NULL; 181 return NULL;
184 } 182 }
185 183
186 184
187 void BranchInstr::SetInputAt(intptr_t i, Value* value) { 185 void BranchInstr::SetInputAt(intptr_t i, Value* value) {
188 ASSERT(!is_fused_with_comparison());
189 if (i == 0) { 186 if (i == 0) {
190 value_ = value; 187 left_ = value;
191 return; 188 } else if (i == 1) {
189 right_ = value;
190 } else {
191 UNREACHABLE();
192 } 192 }
193 UNREACHABLE();
194 } 193 }
195 194
196 195
197 intptr_t ParallelMoveInstr::InputCount() const { 196 intptr_t ParallelMoveInstr::InputCount() const {
198 UNREACHABLE(); 197 UNREACHABLE();
199 return 0; 198 return 0;
200 } 199 }
201 200
202 201
203 Value* ParallelMoveInstr::InputAt(intptr_t i) const { 202 Value* ParallelMoveInstr::InputAt(intptr_t i) const {
(...skipping 826 matching lines...) Expand 10 before | Expand all | Expand 10 after
1030 1029
1031 void GotoInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1030 void GotoInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1032 // We can fall through if the successor is the next block in the list. 1031 // We can fall through if the successor is the next block in the list.
1033 // Otherwise, we need a jump. 1032 // Otherwise, we need a jump.
1034 if (!compiler->IsNextBlock(successor())) { 1033 if (!compiler->IsNextBlock(successor())) {
1035 __ jmp(compiler->GetBlockLabel(successor())); 1034 __ jmp(compiler->GetBlockLabel(successor()));
1036 } 1035 }
1037 } 1036 }
1038 1037
1039 1038
1040 LocationSummary* BranchInstr::MakeLocationSummary() const {
1041 if (is_fused_with_comparison()) {
1042 return fused_with_comparison_->locs();
1043 } else {
1044 const int kNumInputs = 1;
1045 const int kNumTemps = 0;
1046 LocationSummary* locs = new LocationSummary(kNumInputs,
1047 kNumTemps,
1048 LocationSummary::kNoCall);
1049 locs->set_in(0, Location::RequiresRegister());
1050 return locs;
1051 }
1052 }
1053
1054
1055 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1056 if (is_fused_with_comparison()) {
1057 fused_with_comparison_->EmitNativeCode(compiler);
1058 } else {
1059 Register value = locs()->in(0).reg();
1060 __ CompareObject(value, compiler->bool_true());
1061 EmitBranchOnCondition(compiler, EQUAL);
1062 }
1063 }
1064
1065
1066 static Condition NegateCondition(Condition condition) { 1039 static Condition NegateCondition(Condition condition) {
1067 switch (condition) { 1040 switch (condition) {
1068 case EQUAL: return NOT_EQUAL; 1041 case EQUAL: return NOT_EQUAL;
1069 case NOT_EQUAL: return EQUAL; 1042 case NOT_EQUAL: return EQUAL;
1070 case LESS: return GREATER_EQUAL; 1043 case LESS: return GREATER_EQUAL;
1071 case LESS_EQUAL: return GREATER; 1044 case LESS_EQUAL: return GREATER;
1072 case GREATER: return LESS_EQUAL; 1045 case GREATER: return LESS_EQUAL;
1073 case GREATER_EQUAL: return LESS; 1046 case GREATER_EQUAL: return LESS;
1074 case BELOW: return ABOVE_EQUAL; 1047 case BELOW: return ABOVE_EQUAL;
1075 case BELOW_EQUAL: return ABOVE; 1048 case BELOW_EQUAL: return ABOVE;
1076 case ABOVE: return BELOW_EQUAL; 1049 case ABOVE: return BELOW_EQUAL;
1077 case ABOVE_EQUAL: return BELOW; 1050 case ABOVE_EQUAL: return BELOW;
1078 default: 1051 default:
1079 OS::Print("Error %d\n", condition); 1052 OS::Print("Error %d\n", condition);
1080 UNIMPLEMENTED(); 1053 UNIMPLEMENTED();
1081 return EQUAL; 1054 return EQUAL;
1082 } 1055 }
1083 } 1056 }
1084 1057
1085 1058
1086 void BranchInstr::EmitBranchOnCondition(FlowGraphCompiler* compiler, 1059 void BranchInstr::EmitBranchOnCondition(FlowGraphCompiler* compiler,
1087 Condition true_condition) { 1060 Condition true_condition) {
1088 if (is_negated()) {
1089 true_condition = NegateCondition(true_condition);
1090 }
1091 if (compiler->IsNextBlock(false_successor())) { 1061 if (compiler->IsNextBlock(false_successor())) {
1092 // If the next block is the false successor we will fall through to it. 1062 // If the next block is the false successor we will fall through to it.
1093 __ j(true_condition, compiler->GetBlockLabel(true_successor())); 1063 __ j(true_condition, compiler->GetBlockLabel(true_successor()));
1094 } else { 1064 } else {
1095 // If the next block is the true successor we negate comparison and fall 1065 // If the next block is the true successor we negate comparison and fall
1096 // through to it. 1066 // through to it.
1097 ASSERT(compiler->IsNextBlock(true_successor())); 1067 ASSERT(compiler->IsNextBlock(true_successor()));
1098 Condition false_condition = NegateCondition(true_condition); 1068 Condition false_condition = NegateCondition(true_condition);
1099 __ j(false_condition, compiler->GetBlockLabel(false_successor())); 1069 __ j(false_condition, compiler->GetBlockLabel(false_successor()));
1100 } 1070 }
(...skipping 19 matching lines...) Expand all
1120 } 1090 }
1121 1091
1122 1092
1123 void StoreContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1093 void StoreContextComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1124 // Nothing to do. Context register were loaded by register allocator. 1094 // Nothing to do. Context register were loaded by register allocator.
1125 ASSERT(locs()->in(0).reg() == CTX); 1095 ASSERT(locs()->in(0).reg() == CTX);
1126 } 1096 }
1127 1097
1128 1098
1129 LocationSummary* StrictCompareComp::MakeLocationSummary() const { 1099 LocationSummary* StrictCompareComp::MakeLocationSummary() const {
1130 if (is_fused_with_branch()) { 1100 return LocationSummary::Make(2, Location::SameAsFirstInput());
1131 const intptr_t kNumInputs = 2;
1132 const intptr_t kNumTemps = 0;
1133 LocationSummary* locs = new LocationSummary(kNumInputs,
1134 kNumTemps,
1135 LocationSummary::kNoCall);
1136 locs->set_in(0, Location::RequiresRegister());
1137 locs->set_in(1, Location::RequiresRegister());
1138 return locs;
1139 } else {
1140 return LocationSummary::Make(2, Location::SameAsFirstInput());
1141 }
1142 } 1101 }
1143 1102
1144 1103
1145 void StrictCompareComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1104 void StrictCompareComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1146 Register left = locs()->in(0).reg(); 1105 Register left = locs()->in(0).reg();
1147 Register right = locs()->in(1).reg(); 1106 Register right = locs()->in(1).reg();
1148 1107
1149 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT); 1108 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT);
1150 Condition true_condition = (kind() == Token::kEQ_STRICT) ? EQUAL : NOT_EQUAL; 1109 Condition true_condition = (kind() == Token::kEQ_STRICT) ? EQUAL : NOT_EQUAL;
1151 __ CompareRegisters(left, right); 1110 __ CompareRegisters(left, right);
1152 1111
1153 if (is_fused_with_branch()) { 1112 Register result = locs()->out().reg();
1154 fused_with_branch()->EmitBranchOnCondition(compiler, true_condition); 1113 Label load_true, done;
1155 } else { 1114 __ j(true_condition, &load_true, Assembler::kNearJump);
1156 Register result = locs()->out().reg(); 1115 __ LoadObject(result, compiler->bool_false());
1157 Label load_true, done; 1116 __ jmp(&done, Assembler::kNearJump);
1158 __ j(true_condition, &load_true, Assembler::kNearJump); 1117 __ Bind(&load_true);
1159 __ LoadObject(result, compiler->bool_false()); 1118 __ LoadObject(result, compiler->bool_true());
1160 __ jmp(&done, Assembler::kNearJump); 1119 __ Bind(&done);
1161 __ Bind(&load_true);
1162 __ LoadObject(result, compiler->bool_true());
1163 __ Bind(&done);
1164 }
1165 } 1120 }
1166 1121
1167 1122
1168 void ClosureCallComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1123 void ClosureCallComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1169 ASSERT(VerifyCallComputation(this)); 1124 ASSERT(VerifyCallComputation(this));
1170 // The arguments to the stub include the closure. The arguments 1125 // The arguments to the stub include the closure. The arguments
1171 // descriptor describes the closure's arguments (and so does not include 1126 // descriptor describes the closure's arguments (and so does not include
1172 // the closure). 1127 // the closure).
1173 Register temp_reg = locs()->temp(0).reg(); 1128 Register temp_reg = locs()->temp(0).reg();
1174 int argument_count = ArgumentCount(); 1129 int argument_count = ArgumentCount();
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
1358 const ExternalLabel label(closure_function.ToCString(), stub.EntryPoint()); 1313 const ExternalLabel label(closure_function.ToCString(), stub.EntryPoint());
1359 compiler->GenerateCall(token_pos(), try_index(), &label, 1314 compiler->GenerateCall(token_pos(), try_index(), &label,
1360 PcDescriptors::kOther); 1315 PcDescriptors::kOther);
1361 __ Drop(2); // Discard type arguments and receiver. 1316 __ Drop(2); // Discard type arguments and receiver.
1362 } 1317 }
1363 1318
1364 1319
1365 #undef __ 1320 #undef __
1366 1321
1367 } // namespace dart 1322 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language.h ('k') | runtime/vm/intermediate_language_ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698