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

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

Issue 10201017: Introduce Definition and Use types. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 8 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
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 #ifndef VM_INTERMEDIATE_LANGUAGE_H_ 5 #ifndef VM_INTERMEDIATE_LANGUAGE_H_
6 #define VM_INTERMEDIATE_LANGUAGE_H_ 6 #define VM_INTERMEDIATE_LANGUAGE_H_
7 7
8 #include "vm/allocation.h" 8 #include "vm/allocation.h"
9 #include "vm/ast.h" 9 #include "vm/ast.h"
10 #include "vm/growable_array.h" 10 #include "vm/growable_array.h"
11 #include "vm/handles_impl.h" 11 #include "vm/handles_impl.h"
12 #include "vm/object.h" 12 #include "vm/object.h"
13 13
14 namespace dart { 14 namespace dart {
15 15
16 class FlowGraphVisitor; 16 class FlowGraphVisitor;
17 class LocalVariable; 17 class LocalVariable;
18 18
19 // M is a two argument macro. It is applied to each concrete value's 19 // M is a two argument macro. It is applied to each concrete value's
20 // typename and classname. 20 // typename and classname.
21 #define FOR_EACH_VALUE(M) \ 21 #define FOR_EACH_VALUE(M) \
22 M(Temp, TempVal) \ 22 M(Temp, TempVal) \
23 M(Use, UseVal) \
23 M(Constant, ConstantVal) \ 24 M(Constant, ConstantVal) \
24 25
25 26
26 // M is a two argument macro. It is applied to each concrete instruction's 27 // M is a two argument macro. It is applied to each concrete instruction's
27 // (including the values) typename and classname. 28 // (including the values) typename and classname.
28 #define FOR_EACH_COMPUTATION(M) \ 29 #define FOR_EACH_COMPUTATION(M) \
29 FOR_EACH_VALUE(M) \ 30 FOR_EACH_VALUE(M) \
30 M(AssertAssignable, AssertAssignableComp) \ 31 M(AssertAssignable, AssertAssignableComp) \
31 M(AssertBoolean, AssertBooleanComp) \ 32 M(AssertBoolean, AssertBooleanComp) \
32 M(CurrentContext, CurrentContextComp) \ 33 M(CurrentContext, CurrentContextComp) \
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
111 112
112 intptr_t index() const { return index_; } 113 intptr_t index() const { return index_; }
113 114
114 private: 115 private:
115 const intptr_t index_; 116 const intptr_t index_;
116 117
117 DISALLOW_COPY_AND_ASSIGN(TempVal); 118 DISALLOW_COPY_AND_ASSIGN(TempVal);
118 }; 119 };
119 120
120 121
122 // Definitions and uses are mutually recursive.
123 class Definition;
124
125 class UseVal : public Value {
126 public:
127 explicit UseVal(Definition* definition) : definition_(definition) { }
128
129 DECLARE_VALUE(Use)
130
131 Definition* definition() const { return definition_; }
132
133 private:
134 Definition* const definition_;
135
136 DISALLOW_COPY_AND_ASSIGN(UseVal);
137 };
138
139
121 class ConstantVal: public Value { 140 class ConstantVal: public Value {
122 public: 141 public:
123 explicit ConstantVal(const Object& value) : value_(value) { 142 explicit ConstantVal(const Object& value) : value_(value) {
124 ASSERT(value.IsZoneHandle()); 143 ASSERT(value.IsZoneHandle());
125 } 144 }
126 145
127 DECLARE_VALUE(Constant) 146 DECLARE_VALUE(Constant)
128 147
129 const Object& value() const { return value_; } 148 const Object& value() const { return value_; }
130 149
(...skipping 890 matching lines...) Expand 10 before | Expand all | Expand 10 after
1021 }; 1040 };
1022 1041
1023 1042
1024 #undef DECLARE_COMPUTATION 1043 #undef DECLARE_COMPUTATION
1025 1044
1026 1045
1027 // Instructions. 1046 // Instructions.
1028 // 1047 //
1029 // <Instruction> ::= JoinEntry <Instruction> 1048 // <Instruction> ::= JoinEntry <Instruction>
1030 // | TargetEntry <Instruction> 1049 // | TargetEntry <Instruction>
1031 // | PickTemp <int> <int> <Instruction>
1032 // | TuckTemp <int> <int> <Instruction>
1033 // | Do <Computation> <Instruction> 1050 // | Do <Computation> <Instruction>
1034 // | Bind <int> <Computation> <Instruction>
1035 // | Return <Value> 1051 // | Return <Value>
1036 // | Branch <Value> <Instruction> <Instruction> 1052 // | Branch <Value> <Instruction> <Instruction>
1053 // <Definition> ::= PickTemp <int> <int> <Instruction>
1054 // | TuckTemp <int> <int> <Instruction>
1055 // | Bind <int> <Computation> <Instruction>
1037 1056
1038 // M is a single argument macro. It is applied to each concrete instruction 1057 // M is a single argument macro. It is applied to each concrete instruction
1039 // type name. The concrete instruction classes are the name with Instr 1058 // type name. The concrete instruction classes are the name with Instr
1040 // concatenated. 1059 // concatenated.
1041 #define FOR_EACH_INSTRUCTION(M) \ 1060 #define FOR_EACH_INSTRUCTION(M) \
1042 M(JoinEntry) \ 1061 M(JoinEntry) \
1043 M(TargetEntry) \ 1062 M(TargetEntry) \
1063 M(Do) \
1064 M(Bind) \
1044 M(PickTemp) \ 1065 M(PickTemp) \
1045 M(TuckTemp) \ 1066 M(TuckTemp) \
1046 M(Do) \
1047 M(Bind) \
1048 M(Return) \ 1067 M(Return) \
1049 M(Throw) \ 1068 M(Throw) \
1050 M(ReThrow) \ 1069 M(ReThrow) \
1051 M(Branch) \ 1070 M(Branch) \
1052 1071
1053 1072
1054 // Forward declarations for Instruction classes. 1073 // Forward declarations for Instruction classes.
1055 class BlockEntryInstr; 1074 class BlockEntryInstr;
1056 #define FORWARD_DECLARATION(type) class type##Instr; 1075 #define FORWARD_DECLARATION(type) class type##Instr;
1057 FOR_EACH_INSTRUCTION(FORWARD_DECLARATION) 1076 FOR_EACH_INSTRUCTION(FORWARD_DECLARATION)
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
1237 1256
1238 private: 1257 private:
1239 BlockEntryInstr* predecessor_; 1258 BlockEntryInstr* predecessor_;
1240 Instruction* successor_; 1259 Instruction* successor_;
1241 const intptr_t try_index_; 1260 const intptr_t try_index_;
1242 1261
1243 DISALLOW_COPY_AND_ASSIGN(TargetEntryInstr); 1262 DISALLOW_COPY_AND_ASSIGN(TargetEntryInstr);
1244 }; 1263 };
1245 1264
1246 1265
1247 // The non-optimizing compiler assumes that there is exactly one use of
1248 // every temporary so they can be deallocated at their use. Some AST nodes,
1249 // e.g., expr0[expr1]++, violate this assumption (there are two uses of each
1250 // of the values expr0 and expr1).
1251 //
1252 // PickTemp is used to name (with 'destination') a copy of a live temporary
1253 // (named 'source') without counting as the use of the source.
1254 class PickTempInstr : public Instruction {
1255 public:
1256 PickTempInstr(intptr_t dst, intptr_t src)
1257 : destination_(dst), source_(src), successor_(NULL) { }
1258
1259 DECLARE_INSTRUCTION(PickTemp)
1260
1261 intptr_t destination() const { return destination_; }
1262 intptr_t source() const { return source_; }
1263
1264 virtual Instruction* StraightLineSuccessor() const {
1265 return successor_;
1266 }
1267 virtual void SetSuccessor(Instruction* instr) {
1268 ASSERT(successor_ == NULL && instr != NULL);
1269 successor_ = instr;
1270 }
1271
1272 private:
1273 const intptr_t destination_;
1274 const intptr_t source_;
1275 Instruction* successor_;
1276
1277 DISALLOW_COPY_AND_ASSIGN(PickTempInstr);
1278 };
1279
1280
1281 // The non-optimizing compiler assumes that temporary definitions and uses
1282 // obey a stack discipline, so they can be allocated and deallocated with
1283 // push and pop. Some Some AST nodes, e.g., expr++, violate this assumption
1284 // (the value expr+1 is produced after the value of expr, and also consumed
1285 // after it).
1286 //
1287 // We 'preallocate' temporaries (named with 'destination') such as the one
1288 // for expr+1 and use TuckTemp to mutate them by overwriting them with a
1289 // copy of a temporary (named with 'source').
1290 class TuckTempInstr : public Instruction {
1291 public:
1292 TuckTempInstr(intptr_t dst, intptr_t src)
1293 : destination_(dst), source_(src), successor_(NULL) { }
1294
1295 DECLARE_INSTRUCTION(TuckTemp)
1296
1297 intptr_t destination() const { return destination_; }
1298 intptr_t source() const { return source_; }
1299
1300 virtual Instruction* StraightLineSuccessor() const {
1301 return successor_;
1302 }
1303 virtual void SetSuccessor(Instruction* instr) {
1304 ASSERT(successor_ == NULL && instr != NULL);
1305 successor_ = instr;
1306 }
1307
1308 private:
1309 const intptr_t destination_;
1310 const intptr_t source_;
1311 Instruction* successor_;
1312
1313 DISALLOW_COPY_AND_ASSIGN(TuckTempInstr);
1314 };
1315
1316
1317 class DoInstr : public Instruction { 1266 class DoInstr : public Instruction {
1318 public: 1267 public:
1319 explicit DoInstr(Computation* comp) 1268 explicit DoInstr(Computation* comp)
1320 : computation_(comp), successor_(NULL) { } 1269 : computation_(comp), successor_(NULL) { }
1321 1270
1322 DECLARE_INSTRUCTION(Do) 1271 DECLARE_INSTRUCTION(Do)
1323 1272
1324 Computation* computation() const { return computation_; } 1273 Computation* computation() const { return computation_; }
1325 1274
1326 virtual Instruction* StraightLineSuccessor() const { 1275 virtual Instruction* StraightLineSuccessor() const {
1327 return successor_; 1276 return successor_;
1328 } 1277 }
1329 virtual void SetSuccessor(Instruction* instr) { 1278 virtual void SetSuccessor(Instruction* instr) {
1330 ASSERT(successor_ == NULL); 1279 ASSERT(successor_ == NULL);
1331 successor_ = instr; 1280 successor_ = instr;
1332 } 1281 }
1333 1282
1334 private: 1283 private:
1335 Computation* computation_; 1284 Computation* computation_;
1336 Instruction* successor_; 1285 Instruction* successor_;
1337 1286
1338 DISALLOW_COPY_AND_ASSIGN(DoInstr); 1287 DISALLOW_COPY_AND_ASSIGN(DoInstr);
1339 }; 1288 };
1340 1289
1341 1290
1342 class BindInstr : public Instruction { 1291 class Definition : public Instruction {
1292 public:
1293 explicit Definition(intptr_t temp_index) : temp_index_(temp_index) { }
1294
1295 intptr_t temp_index() const { return temp_index_; }
srdjan 2012/04/24 22:02:18 Why don't you need DECLARE_INSTRUCTION(Definition)
Kevin Millikin (Google) 2012/04/25 08:50:51 Because it's an abstract, not concrete, instructio
1296
1297 private:
1298 const intptr_t temp_index_;
1299
1300 DISALLOW_COPY_AND_ASSIGN(Definition);
1301 };
1302
1303
1304 class BindInstr : public Definition {
1343 public: 1305 public:
1344 BindInstr(intptr_t temp_index, Computation* computation) 1306 BindInstr(intptr_t temp_index, Computation* computation)
1345 : temp_index_(temp_index), computation_(computation), successor_(NULL) { } 1307 : Definition(temp_index), computation_(computation), successor_(NULL) { }
1346 1308
1347 DECLARE_INSTRUCTION(Bind) 1309 DECLARE_INSTRUCTION(Bind)
1348 1310
1349 intptr_t temp_index() const { return temp_index_; }
1350 Computation* computation() const { return computation_; } 1311 Computation* computation() const { return computation_; }
1351 1312
1352 virtual Instruction* StraightLineSuccessor() const { 1313 virtual Instruction* StraightLineSuccessor() const {
1353 return successor_; 1314 return successor_;
1354 } 1315 }
1355 virtual void SetSuccessor(Instruction* instr) { 1316 virtual void SetSuccessor(Instruction* instr) {
1356 ASSERT(successor_ == NULL); 1317 ASSERT(successor_ == NULL);
1357 successor_ = instr; 1318 successor_ = instr;
1358 } 1319 }
1359 1320
1360 private: 1321 private:
1361 const intptr_t temp_index_;
1362 Computation* computation_; 1322 Computation* computation_;
1363 Instruction* successor_; 1323 Instruction* successor_;
1364 1324
1365 DISALLOW_COPY_AND_ASSIGN(BindInstr); 1325 DISALLOW_COPY_AND_ASSIGN(BindInstr);
1366 }; 1326 };
1367 1327
1368 1328
1329 // The non-optimizing compiler assumes that there is exactly one use of
1330 // every temporary so they can be deallocated at their use. Some AST nodes,
1331 // e.g., expr0[expr1]++, violate this assumption (there are two uses of each
1332 // of the values expr0 and expr1).
1333 //
1334 // PickTemp is used to name (with 'destination') a copy of a live temporary
1335 // (named 'source') without counting as the use of the source.
1336 class PickTempInstr : public Definition {
1337 public:
1338 PickTempInstr(intptr_t temp_index, intptr_t source)
1339 : Definition(temp_index), source_(source), successor_(NULL) { }
1340
1341 DECLARE_INSTRUCTION(PickTemp)
1342
1343 intptr_t source() const { return source_; }
1344
1345 virtual Instruction* StraightLineSuccessor() const {
1346 return successor_;
1347 }
1348 virtual void SetSuccessor(Instruction* instr) {
1349 ASSERT(successor_ == NULL && instr != NULL);
1350 successor_ = instr;
1351 }
1352
1353 private:
1354 const intptr_t source_;
1355 Instruction* successor_;
1356
1357 DISALLOW_COPY_AND_ASSIGN(PickTempInstr);
1358 };
1359
1360
1361 // The non-optimizing compiler assumes that temporary definitions and uses
1362 // obey a stack discipline, so they can be allocated and deallocated with
1363 // push and pop. Some Some AST nodes, e.g., expr++, violate this assumption
1364 // (the value expr+1 is produced after the value of expr, and also consumed
1365 // after it).
1366 //
1367 // We 'preallocate' temporaries (named with 'destination') such as the one
1368 // for expr+1 and use TuckTemp to mutate them by overwriting them with a
1369 // copy of a temporary (named with 'source').
1370 class TuckTempInstr : public Instruction {
1371 public:
1372 TuckTempInstr(intptr_t destination, intptr_t source)
1373 : destination_(destination), source_(source), successor_(NULL) { }
1374
1375 DECLARE_INSTRUCTION(TuckTemp)
1376
1377 intptr_t destination() const { return destination_; }
1378 intptr_t source() const { return source_; }
1379
1380 virtual Instruction* StraightLineSuccessor() const {
1381 return successor_;
1382 }
1383 virtual void SetSuccessor(Instruction* instr) {
1384 ASSERT(successor_ == NULL && instr != NULL);
1385 successor_ = instr;
1386 }
1387
1388 private:
1389 const intptr_t destination_;
1390 const intptr_t source_;
1391 Instruction* successor_;
1392
1393 DISALLOW_COPY_AND_ASSIGN(TuckTempInstr);
1394 };
1395
1396
1369 class ReturnInstr : public Instruction { 1397 class ReturnInstr : public Instruction {
1370 public: 1398 public:
1371 ReturnInstr(intptr_t node_id, intptr_t token_index, Value* value) 1399 ReturnInstr(intptr_t node_id, intptr_t token_index, Value* value)
1372 : node_id_(node_id), token_index_(token_index), value_(value) { 1400 : node_id_(node_id), token_index_(token_index), value_(value) {
1373 ASSERT(value_ != NULL); 1401 ASSERT(value_ != NULL);
1374 } 1402 }
1375 1403
1376 DECLARE_INSTRUCTION(Return) 1404 DECLARE_INSTRUCTION(Return)
1377 1405
1378 Value* value() const { return value_; } 1406 Value* value() const { return value_; }
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
1551 const GrowableArray<BlockEntryInstr*>& block_order_; 1579 const GrowableArray<BlockEntryInstr*>& block_order_;
1552 1580
1553 private: 1581 private:
1554 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); 1582 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor);
1555 }; 1583 };
1556 1584
1557 1585
1558 } // namespace dart 1586 } // namespace dart
1559 1587
1560 #endif // VM_INTERMEDIATE_LANGUAGE_H_ 1588 #endif // VM_INTERMEDIATE_LANGUAGE_H_
OLDNEW
« runtime/vm/flow_graph_compiler_x64.cc ('K') | « runtime/vm/flow_graph_compiler_x64.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698