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

Side by Side Diff: src/data-flow.cc

Issue 805005: Revert changes 4088 and 4087 to fix build. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 10 years, 9 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 | « src/data-flow.h ('k') | src/ia32/codegen-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 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 10 matching lines...) Expand all
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 #include "v8.h" 28 #include "v8.h"
29 29
30 #include "data-flow.h" 30 #include "data-flow.h"
31 #include "scopes.h"
32 31
33 namespace v8 { 32 namespace v8 {
34 namespace internal { 33 namespace internal {
35 34
36 35
37 void FlowGraph::AppendInstruction(AstNode* instruction) { 36 void FlowGraph::AppendInstruction(AstNode* instruction) {
38 // Add a (non-null) AstNode to the end of the graph fragment. 37 // Add a (non-null) AstNode to the end of the graph fragment.
39 ASSERT(instruction != NULL); 38 ASSERT(instruction != NULL);
40 if (exit()->IsExitNode()) return; 39 if (exit()->IsExitNode()) return;
41 if (!exit()->IsBlockNode()) AppendNode(new BlockNode()); 40 if (!exit()->IsBlockNode()) AppendNode(new BlockNode());
(...skipping 987 matching lines...) Expand 10 before | Expand all | Expand 10 after
1029 void LivenessAnalyzer::VisitCompareOperation(CompareOperation* expr) { 1028 void LivenessAnalyzer::VisitCompareOperation(CompareOperation* expr) {
1030 UNREACHABLE(); 1029 UNREACHABLE();
1031 } 1030 }
1032 1031
1033 1032
1034 void LivenessAnalyzer::VisitThisFunction(ThisFunction* expr) { 1033 void LivenessAnalyzer::VisitThisFunction(ThisFunction* expr) {
1035 UNREACHABLE(); 1034 UNREACHABLE();
1036 } 1035 }
1037 1036
1038 1037
1039 AssignedVariablesAnalyzer::AssignedVariablesAnalyzer(FunctionLiteral* fun)
1040 : fun_(fun),
1041 av_(fun->scope()->num_parameters() + fun->scope()->num_stack_slots()) {}
1042
1043
1044 void AssignedVariablesAnalyzer::Analyze() {
1045 ASSERT(av_.length() > 0);
1046 VisitStatements(fun_->body());
1047 }
1048
1049
1050 Variable* AssignedVariablesAnalyzer::FindSmiLoopVariable(ForStatement* stmt) {
1051 // The loop must have all necessary parts.
1052 if (stmt->init() == NULL || stmt->cond() == NULL || stmt->next() == NULL) {
1053 return NULL;
1054 }
1055 // The initialization statement has to be a simple assignment.
1056 Assignment* init = stmt->init()->StatementAsSimpleAssignment();
1057 if (init == NULL) return NULL;
1058
1059 // We only deal with local variables.
1060 Variable* loop_var = init->target()->AsVariableProxy()->AsVariable();
1061 if (!loop_var->IsStackAllocated()) return NULL;
1062
1063 // The initial value has to be a smi.
1064 Literal* init_lit = init->value()->AsLiteral();
1065 if (init_lit == NULL || !init_lit->handle()->IsSmi()) return NULL;
1066 int init_value = Smi::cast(*init_lit->handle())->value();
1067
1068 // The condition must be a compare of variable with <, <=, >, or >=.
1069 CompareOperation* cond = stmt->cond()->AsCompareOperation();
1070 if (cond == NULL) return NULL;
1071 if (cond->op() != Token::LT
1072 && cond->op() != Token::LTE
1073 && cond->op() != Token::GT
1074 && cond->op() != Token::GTE) return NULL;
1075
1076 // The lhs must be the same variable as in the init expression.
1077 if (cond->left()->AsVariableProxy()->AsVariable() != loop_var) return NULL;
1078
1079 // The rhs must be a smi.
1080 Literal* term_lit = cond->right()->AsLiteral();
1081 if (term_lit == NULL || !term_lit->handle()->IsSmi()) return NULL;
1082 int term_value = Smi::cast(*term_lit->handle())->value();
1083
1084 // The count operation updates the same variable as in the init expression.
1085 CountOperation* update = stmt->next()->StatementAsCountOperation();
1086 if (update == NULL) return NULL;
1087 if (update->expression()->AsVariableProxy()->AsVariable() != loop_var) {
1088 return NULL;
1089 }
1090
1091 // The direction of the count operation must agree with the start and the end
1092 // value. We currently do not allow the initial value to be the same as the
1093 // terminal value. This _would_ be ok as long as the loop body never executes
1094 // or executes exactly one time.
1095 if (init_value == term_value) return NULL;
1096 if (init_value < term_value && update->op() != Token::INC) return NULL;
1097 if (init_value > term_value && update->op() != Token::DEC) return NULL;
1098
1099 // Found a smi loop variable.
1100 return loop_var;
1101 }
1102
1103 int AssignedVariablesAnalyzer::BitIndex(Variable* var) {
1104 ASSERT(var != NULL);
1105 ASSERT(var->IsStackAllocated());
1106 Slot* slot = var->slot();
1107 if (slot->type() == Slot::PARAMETER) {
1108 return slot->index();
1109 } else {
1110 return fun_->scope()->num_parameters() + slot->index();
1111 }
1112 }
1113
1114
1115 void AssignedVariablesAnalyzer::RecordAssignedVar(Variable* var) {
1116 ASSERT(var != NULL);
1117 if (var->IsStackAllocated()) {
1118 av_.Add(BitIndex(var));
1119 }
1120 }
1121
1122
1123 void AssignedVariablesAnalyzer::MarkIfTrivial(Expression* expr) {
1124 Variable* var = expr->AsVariableProxy()->AsVariable();
1125 if (var != NULL &&
1126 var->IsStackAllocated() &&
1127 (var->is_this() || !av_.Contains(BitIndex(var)))) {
1128 expr->AsVariableProxy()->set_is_trivial(true);
1129 }
1130 }
1131
1132
1133 void AssignedVariablesAnalyzer::ProcessExpression(Expression* expr) {
1134 BitVector saved_av(av_);
1135 av_.Clear();
1136 Visit(expr);
1137 av_.Union(saved_av);
1138 }
1139
1140 void AssignedVariablesAnalyzer::VisitBlock(Block* stmt) {
1141 VisitStatements(stmt->statements());
1142 }
1143
1144
1145 void AssignedVariablesAnalyzer::VisitExpressionStatement(
1146 ExpressionStatement* stmt) {
1147 ProcessExpression(stmt->expression());
1148 }
1149
1150
1151 void AssignedVariablesAnalyzer::VisitEmptyStatement(EmptyStatement* stmt) {
1152 // Do nothing.
1153 }
1154
1155
1156 void AssignedVariablesAnalyzer::VisitIfStatement(IfStatement* stmt) {
1157 ProcessExpression(stmt->condition());
1158 Visit(stmt->then_statement());
1159 Visit(stmt->else_statement());
1160 }
1161
1162
1163 void AssignedVariablesAnalyzer::VisitContinueStatement(
1164 ContinueStatement* stmt) {
1165 // Nothing to do.
1166 }
1167
1168
1169 void AssignedVariablesAnalyzer::VisitBreakStatement(BreakStatement* stmt) {
1170 // Nothing to do.
1171 }
1172
1173
1174 void AssignedVariablesAnalyzer::VisitReturnStatement(ReturnStatement* stmt) {
1175 ProcessExpression(stmt->expression());
1176 }
1177
1178
1179 void AssignedVariablesAnalyzer::VisitWithEnterStatement(
1180 WithEnterStatement* stmt) {
1181 ProcessExpression(stmt->expression());
1182 }
1183
1184
1185 void AssignedVariablesAnalyzer::VisitWithExitStatement(
1186 WithExitStatement* stmt) {
1187 // Nothing to do.
1188 }
1189
1190
1191 void AssignedVariablesAnalyzer::VisitSwitchStatement(SwitchStatement* stmt) {
1192 BitVector result(av_);
1193 av_.Clear();
1194 Visit(stmt->tag());
1195 result.Union(av_);
1196 for (int i = 0; i < stmt->cases()->length(); i++) {
1197 CaseClause* clause = stmt->cases()->at(i);
1198 if (!clause->is_default()) {
1199 av_.Clear();
1200 Visit(clause->label());
1201 result.Union(av_);
1202 }
1203 VisitStatements(clause->statements());
1204 }
1205 av_.Union(result);
1206 }
1207
1208
1209 void AssignedVariablesAnalyzer::VisitDoWhileStatement(DoWhileStatement* stmt) {
1210 ProcessExpression(stmt->cond());
1211 Visit(stmt->body());
1212 }
1213
1214
1215 void AssignedVariablesAnalyzer::VisitWhileStatement(WhileStatement* stmt) {
1216 ProcessExpression(stmt->cond());
1217 Visit(stmt->body());
1218 }
1219
1220
1221 void AssignedVariablesAnalyzer::VisitForStatement(ForStatement* stmt) {
1222 if (stmt->init() != NULL) Visit(stmt->init());
1223
1224 if (stmt->cond() != NULL) ProcessExpression(stmt->cond());
1225
1226 if (stmt->next() != NULL) Visit(stmt->next());
1227
1228 // Process loop body. After visiting the loop body av_ contains
1229 // the assigned variables of the loop body.
1230 BitVector saved_av(av_);
1231 av_.Clear();
1232 Visit(stmt->body());
1233
1234 Variable* var = FindSmiLoopVariable(stmt);
1235 if (var != NULL && !av_.Contains(BitIndex(var))) {
1236 stmt->set_loop_variable(var);
1237 }
1238
1239 av_.Union(saved_av);
1240 }
1241
1242
1243 void AssignedVariablesAnalyzer::VisitForInStatement(ForInStatement* stmt) {
1244 ProcessExpression(stmt->each());
1245 ProcessExpression(stmt->enumerable());
1246 Visit(stmt->body());
1247 }
1248
1249
1250 void AssignedVariablesAnalyzer::VisitTryCatchStatement(
1251 TryCatchStatement* stmt) {
1252 Visit(stmt->try_block());
1253 Visit(stmt->catch_block());
1254 }
1255
1256
1257 void AssignedVariablesAnalyzer::VisitTryFinallyStatement(
1258 TryFinallyStatement* stmt) {
1259 Visit(stmt->try_block());
1260 Visit(stmt->finally_block());
1261 }
1262
1263
1264 void AssignedVariablesAnalyzer::VisitDebuggerStatement(
1265 DebuggerStatement* stmt) {
1266 // Nothing to do.
1267 }
1268
1269
1270 void AssignedVariablesAnalyzer::VisitFunctionLiteral(FunctionLiteral* expr) {
1271 // Nothing to do.
1272 ASSERT(av_.IsEmpty());
1273 }
1274
1275
1276 void AssignedVariablesAnalyzer::VisitFunctionBoilerplateLiteral(
1277 FunctionBoilerplateLiteral* expr) {
1278 // Nothing to do.
1279 ASSERT(av_.IsEmpty());
1280 }
1281
1282
1283 void AssignedVariablesAnalyzer::VisitConditional(Conditional* expr) {
1284 ASSERT(av_.IsEmpty());
1285
1286 Visit(expr->condition());
1287
1288 BitVector result(av_);
1289 av_.Clear();
1290 Visit(expr->then_expression());
1291 result.Union(av_);
1292
1293 av_.Clear();
1294 Visit(expr->else_expression());
1295 av_.Union(result);
1296 }
1297
1298
1299 void AssignedVariablesAnalyzer::VisitSlot(Slot* expr) {
1300 UNREACHABLE();
1301 }
1302
1303
1304 void AssignedVariablesAnalyzer::VisitVariableProxy(VariableProxy* expr) {
1305 // Nothing to do.
1306 ASSERT(av_.IsEmpty());
1307 }
1308
1309
1310 void AssignedVariablesAnalyzer::VisitLiteral(Literal* expr) {
1311 // Nothing to do.
1312 ASSERT(av_.IsEmpty());
1313 }
1314
1315
1316 void AssignedVariablesAnalyzer::VisitRegExpLiteral(RegExpLiteral* expr) {
1317 // Nothing to do.
1318 ASSERT(av_.IsEmpty());
1319 }
1320
1321
1322 void AssignedVariablesAnalyzer::VisitObjectLiteral(ObjectLiteral* expr) {
1323 ASSERT(av_.IsEmpty());
1324 BitVector result(av_.length());
1325 for (int i = 0; i < expr->properties()->length(); i++) {
1326 Visit(expr->properties()->at(i)->value());
1327 result.Union(av_);
1328 av_.Clear();
1329 }
1330 av_.CopyFrom(result);
1331 }
1332
1333
1334 void AssignedVariablesAnalyzer::VisitArrayLiteral(ArrayLiteral* expr) {
1335 ASSERT(av_.IsEmpty());
1336 BitVector result(av_.length());
1337 for (int i = 0; i < expr->values()->length(); i++) {
1338 Visit(expr->values()->at(i));
1339 result.Union(av_);
1340 av_.Clear();
1341 }
1342 av_.CopyFrom(result);
1343 }
1344
1345
1346 void AssignedVariablesAnalyzer::VisitCatchExtensionObject(
1347 CatchExtensionObject* expr) {
1348 ASSERT(av_.IsEmpty());
1349 Visit(expr->key());
1350 ProcessExpression(expr->value());
1351 }
1352
1353
1354 void AssignedVariablesAnalyzer::VisitAssignment(Assignment* expr) {
1355 ASSERT(av_.IsEmpty());
1356
1357 Visit(expr->target());
1358
1359 ProcessExpression(expr->value());
1360
1361 Variable* var = expr->target()->AsVariableProxy()->AsVariable();
1362 if (var != NULL) RecordAssignedVar(var);
1363
1364 // If we have a variable as a receiver in a property store, check if
1365 // we can mark it as trivial.
1366 if (expr->target()->AsProperty() != NULL) {
1367 MarkIfTrivial(expr->target()->AsProperty()->obj());
1368 }
1369 }
1370
1371
1372 void AssignedVariablesAnalyzer::VisitThrow(Throw* expr) {
1373 ASSERT(av_.IsEmpty());
1374 Visit(expr->exception());
1375 }
1376
1377
1378 void AssignedVariablesAnalyzer::VisitProperty(Property* expr) {
1379 ASSERT(av_.IsEmpty());
1380 Visit(expr->obj());
1381 ProcessExpression(expr->key());
1382
1383 // In case we have a variable as a receiver, check if we can mark
1384 // it as trivial.
1385 MarkIfTrivial(expr->obj());
1386 }
1387
1388
1389 void AssignedVariablesAnalyzer::VisitCall(Call* expr) {
1390 ASSERT(av_.IsEmpty());
1391 Visit(expr->expression());
1392 BitVector result(av_);
1393 for (int i = 0; i < expr->arguments()->length(); i++) {
1394 av_.Clear();
1395 Visit(expr->arguments()->at(i));
1396 result.Union(av_);
1397 }
1398 av_.CopyFrom(result);
1399 }
1400
1401
1402 void AssignedVariablesAnalyzer::VisitCallNew(CallNew* expr) {
1403 ASSERT(av_.IsEmpty());
1404 Visit(expr->expression());
1405 BitVector result(av_);
1406 for (int i = 0; i < expr->arguments()->length(); i++) {
1407 av_.Clear();
1408 Visit(expr->arguments()->at(i));
1409 result.Union(av_);
1410 }
1411 av_.CopyFrom(result);
1412 }
1413
1414
1415 void AssignedVariablesAnalyzer::VisitCallRuntime(CallRuntime* expr) {
1416 ASSERT(av_.IsEmpty());
1417 BitVector result(av_);
1418 for (int i = 0; i < expr->arguments()->length(); i++) {
1419 av_.Clear();
1420 Visit(expr->arguments()->at(i));
1421 result.Union(av_);
1422 }
1423 av_.CopyFrom(result);
1424 }
1425
1426
1427 void AssignedVariablesAnalyzer::VisitUnaryOperation(UnaryOperation* expr) {
1428 ASSERT(av_.IsEmpty());
1429 Visit(expr->expression());
1430 }
1431
1432
1433 void AssignedVariablesAnalyzer::VisitCountOperation(CountOperation* expr) {
1434 ASSERT(av_.IsEmpty());
1435
1436 Visit(expr->expression());
1437
1438 Variable* var = expr->expression()->AsVariableProxy()->AsVariable();
1439 if (var != NULL) RecordAssignedVar(var);
1440 }
1441
1442
1443 void AssignedVariablesAnalyzer::VisitBinaryOperation(BinaryOperation* expr) {
1444 ASSERT(av_.IsEmpty());
1445 Visit(expr->left());
1446
1447 ProcessExpression(expr->right());
1448
1449 // In case we have a variable on the left side, check if we can mark
1450 // it as trivial.
1451 MarkIfTrivial(expr->left());
1452 }
1453
1454
1455 void AssignedVariablesAnalyzer::VisitCompareOperation(CompareOperation* expr) {
1456 ASSERT(av_.IsEmpty());
1457 Visit(expr->left());
1458
1459 ProcessExpression(expr->right());
1460
1461 // In case we have a variable on the left side, check if we can mark
1462 // it as trivial.
1463 MarkIfTrivial(expr->left());
1464 }
1465
1466
1467 void AssignedVariablesAnalyzer::VisitThisFunction(ThisFunction* expr) {
1468 // Nothing to do.
1469 ASSERT(av_.IsEmpty());
1470 }
1471
1472
1473 void AssignedVariablesAnalyzer::VisitDeclaration(Declaration* decl) {
1474 UNREACHABLE();
1475 }
1476
1477
1478 #ifdef DEBUG 1038 #ifdef DEBUG
1479 1039
1480 // Print a textual representation of an instruction in a flow graph. Using 1040 // Print a textual representation of an instruction in a flow graph. Using
1481 // the AstVisitor is overkill because there is no recursion here. It is 1041 // the AstVisitor is overkill because there is no recursion here. It is
1482 // only used for printing in debug mode. 1042 // only used for printing in debug mode.
1483 class TextInstructionPrinter: public AstVisitor { 1043 class TextInstructionPrinter: public AstVisitor {
1484 public: 1044 public:
1485 TextInstructionPrinter() {} 1045 TextInstructionPrinter() {}
1486 1046
1487 private: 1047 private:
(...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after
1830 for (int i = postorder->length() - 1; i >= 0; i--) { 1390 for (int i = postorder->length() - 1; i >= 0; i--) {
1831 postorder->at(i)->PrintText(); 1391 postorder->at(i)->PrintText();
1832 } 1392 }
1833 } 1393 }
1834 1394
1835 1395
1836 #endif // defined(DEBUG) 1396 #endif // defined(DEBUG)
1837 1397
1838 1398
1839 } } // namespace v8::internal 1399 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/data-flow.h ('k') | src/ia32/codegen-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698