OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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/globals.h" // Needed here to get TARGET_ARCH_XXX. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_XXX. |
6 | 6 |
7 #include "vm/flow_graph_compiler.h" | 7 #include "vm/flow_graph_compiler.h" |
8 | 8 |
9 #include "vm/bit_vector.h" | 9 #include "vm/bit_vector.h" |
10 #include "vm/cha.h" | 10 #include "vm/cha.h" |
(...skipping 1242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1253 UNREACHABLE(); | 1253 UNREACHABLE(); |
1254 return kNoRegister; | 1254 return kNoRegister; |
1255 } | 1255 } |
1256 | 1256 |
1257 | 1257 |
1258 static uword RegMaskBit(Register reg) { | 1258 static uword RegMaskBit(Register reg) { |
1259 return ((reg) != kNoRegister) ? (1 << (reg)) : 0; | 1259 return ((reg) != kNoRegister) ? (1 << (reg)) : 0; |
1260 } | 1260 } |
1261 | 1261 |
1262 | 1262 |
1263 // Mask of globally reserved registers. Some other registers are only reserved | |
1264 // in particular code (e.g., ARGS_DESC_REG in intrinsics). | |
1265 static const uword kReservedCpuRegisters = RegMaskBit(SPREG) | |
1266 | RegMaskBit(FPREG) | |
1267 | RegMaskBit(TMP) | |
1268 | RegMaskBit(TMP2) | |
1269 | RegMaskBit(PP) | |
1270 | RegMaskBit(THR); | |
1271 | |
1272 | |
1273 void FlowGraphCompiler::AllocateRegistersLocally(Instruction* instr) { | 1263 void FlowGraphCompiler::AllocateRegistersLocally(Instruction* instr) { |
1274 ASSERT(!is_optimizing()); | 1264 ASSERT(!is_optimizing()); |
1275 | 1265 |
1276 instr->InitializeLocationSummary(zone(), | 1266 instr->InitializeLocationSummary(zone(), |
1277 false); // Not optimizing. | 1267 false); // Not optimizing. |
1278 LocationSummary* locs = instr->locs(); | 1268 LocationSummary* locs = instr->locs(); |
1279 | 1269 |
1280 bool blocked_registers[kNumberOfCpuRegisters]; | 1270 bool blocked_registers[kNumberOfCpuRegisters]; |
1281 | 1271 |
1282 // Mark all available registers free. | 1272 // Block all registers globally reserved by the assembler, etc and mark |
| 1273 // the rest as free. |
1283 for (intptr_t i = 0; i < kNumberOfCpuRegisters; i++) { | 1274 for (intptr_t i = 0; i < kNumberOfCpuRegisters; i++) { |
1284 blocked_registers[i] = false; | 1275 blocked_registers[i] = (kDartAvailableCpuRegs & (1 << i)) == 0; |
1285 } | |
1286 | |
1287 // Block all registers globally reserved by the assembler, etc. | |
1288 for (intptr_t i = 0; i < kNumberOfCpuRegisters; i++) { | |
1289 if ((kReservedCpuRegisters & (1 << i)) != 0) { | |
1290 blocked_registers[i] = true; | |
1291 } | |
1292 } | 1276 } |
1293 | 1277 |
1294 // Mark all fixed input, temp and output registers as used. | 1278 // Mark all fixed input, temp and output registers as used. |
1295 for (intptr_t i = 0; i < locs->input_count(); i++) { | 1279 for (intptr_t i = 0; i < locs->input_count(); i++) { |
1296 Location loc = locs->in(i); | 1280 Location loc = locs->in(i); |
1297 if (loc.IsRegister()) { | 1281 if (loc.IsRegister()) { |
1298 // Check that a register is not specified twice in the summary. | 1282 // Check that a register is not specified twice in the summary. |
1299 ASSERT(!blocked_registers[loc.reg()]); | 1283 ASSERT(!blocked_registers[loc.reg()]); |
1300 blocked_registers[loc.reg()] = true; | 1284 blocked_registers[loc.reg()] = true; |
1301 } | 1285 } |
1302 } | 1286 } |
1303 | 1287 |
1304 for (intptr_t i = 0; i < locs->temp_count(); i++) { | 1288 for (intptr_t i = 0; i < locs->temp_count(); i++) { |
1305 Location loc = locs->temp(i); | 1289 Location loc = locs->temp(i); |
1306 if (loc.IsRegister()) { | 1290 if (loc.IsRegister()) { |
1307 // Check that a register is not specified twice in the summary. | 1291 // Check that a register is not specified twice in the summary. |
1308 ASSERT(!blocked_registers[loc.reg()]); | 1292 ASSERT(!blocked_registers[loc.reg()]); |
1309 blocked_registers[loc.reg()] = true; | 1293 blocked_registers[loc.reg()] = true; |
1310 } | 1294 } |
1311 } | 1295 } |
1312 | 1296 |
1313 if (locs->out(0).IsRegister()) { | 1297 if (locs->out(0).IsRegister()) { |
1314 // Fixed output registers are allowed to overlap with | 1298 // Fixed output registers are allowed to overlap with |
1315 // temps and inputs. | 1299 // temps and inputs. |
1316 blocked_registers[locs->out(0).reg()] = true; | 1300 blocked_registers[locs->out(0).reg()] = true; |
1317 } | 1301 } |
1318 | 1302 |
1319 // Block all non-free registers. | |
1320 for (intptr_t i = 0; i < kFirstFreeCpuRegister; i++) { | |
1321 blocked_registers[i] = true; | |
1322 } | |
1323 for (intptr_t i = kLastFreeCpuRegister + 1; i < kNumberOfCpuRegisters; i++) { | |
1324 blocked_registers[i] = true; | |
1325 } | |
1326 | |
1327 // Allocate all unallocated input locations. | 1303 // Allocate all unallocated input locations. |
1328 const bool should_pop = !instr->IsPushArgument() && !instr->IsPushTemp(); | 1304 const bool should_pop = !instr->IsPushArgument() && !instr->IsPushTemp(); |
1329 for (intptr_t i = locs->input_count() - 1; i >= 0; i--) { | 1305 for (intptr_t i = locs->input_count() - 1; i >= 0; i--) { |
1330 Location loc = locs->in(i); | 1306 Location loc = locs->in(i); |
1331 Register reg = kNoRegister; | 1307 Register reg = kNoRegister; |
1332 if (loc.IsRegister()) { | 1308 if (loc.IsRegister()) { |
1333 reg = loc.reg(); | 1309 reg = loc.reg(); |
1334 } else if (loc.IsUnallocated() || loc.IsConstant()) { | 1310 } else if (loc.IsUnallocated() || loc.IsConstant()) { |
1335 ASSERT(loc.IsConstant() || | 1311 ASSERT(loc.IsConstant() || |
1336 ((loc.policy() == Location::kRequiresRegister) || | 1312 ((loc.policy() == Location::kRequiresRegister) || |
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1575 reg_(kNoRegister), | 1551 reg_(kNoRegister), |
1576 spilled_(false) { | 1552 spilled_(false) { |
1577 uword blocked_mask = RegMaskBit(blocked) | kReservedCpuRegisters; | 1553 uword blocked_mask = RegMaskBit(blocked) | kReservedCpuRegisters; |
1578 if (resolver->compiler_->intrinsic_mode()) { | 1554 if (resolver->compiler_->intrinsic_mode()) { |
1579 // Block additional registers that must be preserved for intrinsics. | 1555 // Block additional registers that must be preserved for intrinsics. |
1580 blocked_mask |= RegMaskBit(ARGS_DESC_REG); | 1556 blocked_mask |= RegMaskBit(ARGS_DESC_REG); |
1581 } | 1557 } |
1582 reg_ = static_cast<Register>( | 1558 reg_ = static_cast<Register>( |
1583 resolver_->AllocateScratchRegister(Location::kRegister, | 1559 resolver_->AllocateScratchRegister(Location::kRegister, |
1584 blocked_mask, | 1560 blocked_mask, |
1585 kFirstFreeCpuRegister, | 1561 0, |
1586 kLastFreeCpuRegister, | 1562 kNumberOfCpuRegisters - 1, |
1587 &spilled_)); | 1563 &spilled_)); |
1588 | 1564 |
1589 if (spilled_) { | 1565 if (spilled_) { |
1590 resolver->SpillScratch(reg_); | 1566 resolver->SpillScratch(reg_); |
1591 } | 1567 } |
1592 } | 1568 } |
1593 | 1569 |
1594 | 1570 |
1595 ParallelMoveResolver::ScratchRegisterScope::~ScratchRegisterScope() { | 1571 ParallelMoveResolver::ScratchRegisterScope::~ScratchRegisterScope() { |
1596 if (spilled_) { | 1572 if (spilled_) { |
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1840 | 1816 |
1841 | 1817 |
1842 void FlowGraphCompiler::FrameStateClear() { | 1818 void FlowGraphCompiler::FrameStateClear() { |
1843 ASSERT(!is_optimizing()); | 1819 ASSERT(!is_optimizing()); |
1844 frame_state_.TruncateTo(0); | 1820 frame_state_.TruncateTo(0); |
1845 } | 1821 } |
1846 #endif | 1822 #endif |
1847 | 1823 |
1848 | 1824 |
1849 } // namespace dart | 1825 } // namespace dart |
OLD | NEW |