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

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

Issue 1158943002: Block THR also in ParallelMoveResolver, by sharing list of globally reserved regs. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 6 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 (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 1172 matching lines...) Expand 10 before | Expand all | Expand 10 after
1183 if (!blocked_registers[regno]) { 1183 if (!blocked_registers[regno]) {
1184 blocked_registers[regno] = true; 1184 blocked_registers[regno] = true;
1185 return static_cast<Register>(regno); 1185 return static_cast<Register>(regno);
1186 } 1186 }
1187 } 1187 }
1188 UNREACHABLE(); 1188 UNREACHABLE();
1189 return kNoRegister; 1189 return kNoRegister;
1190 } 1190 }
1191 1191
1192 1192
1193 #define REG_MASK_BIT(reg) ((reg) != kNoRegister) ? (1 << (reg)) : 0
1194 // Mask of globally reserved registers. Some other registers are only reserved
1195 // in particular code (e.g., ARGS_DESC_REG in intrinsics).
1196 static const uword kReservedCpuRegisters = REG_MASK_BIT(SPREG)
1197 | REG_MASK_BIT(FPREG)
1198 | REG_MASK_BIT(TMP)
1199 | REG_MASK_BIT(TMP2)
1200 | REG_MASK_BIT(PP)
1201 | REG_MASK_BIT(THR);
1202
1203
1193 void FlowGraphCompiler::AllocateRegistersLocally(Instruction* instr) { 1204 void FlowGraphCompiler::AllocateRegistersLocally(Instruction* instr) {
1194 ASSERT(!is_optimizing()); 1205 ASSERT(!is_optimizing());
1195 1206
1196 instr->InitializeLocationSummary(zone(), 1207 instr->InitializeLocationSummary(zone(),
1197 false); // Not optimizing. 1208 false); // Not optimizing.
1198 LocationSummary* locs = instr->locs(); 1209 LocationSummary* locs = instr->locs();
1199 1210
1200 bool blocked_registers[kNumberOfCpuRegisters]; 1211 bool blocked_registers[kNumberOfCpuRegisters];
1201 1212
1202 // Mark all available registers free. 1213 // Mark all available registers free.
1203 for (intptr_t i = 0; i < kNumberOfCpuRegisters; i++) { 1214 for (intptr_t i = 0; i < kNumberOfCpuRegisters; i++) {
1204 blocked_registers[i] = false; 1215 blocked_registers[i] = false;
1205 } 1216 }
1206 1217
1218 // Block all registers globally reserved by the assembler, etc.
1219 for (intptr_t i = 0; i < kNumberOfCpuRegisters; i++) {
1220 if ((kReservedCpuRegisters & (1 << i)) != 0) {
1221 blocked_registers[i] = true;
1222 }
1223 }
1224
1207 // Mark all fixed input, temp and output registers as used. 1225 // Mark all fixed input, temp and output registers as used.
1208 for (intptr_t i = 0; i < locs->input_count(); i++) { 1226 for (intptr_t i = 0; i < locs->input_count(); i++) {
1209 Location loc = locs->in(i); 1227 Location loc = locs->in(i);
1210 if (loc.IsRegister()) { 1228 if (loc.IsRegister()) {
1211 // Check that a register is not specified twice in the summary. 1229 // Check that a register is not specified twice in the summary.
1212 ASSERT(!blocked_registers[loc.reg()]); 1230 ASSERT(!blocked_registers[loc.reg()]);
1213 blocked_registers[loc.reg()] = true; 1231 blocked_registers[loc.reg()] = true;
1214 } 1232 }
1215 } 1233 }
1216 1234
1217 for (intptr_t i = 0; i < locs->temp_count(); i++) { 1235 for (intptr_t i = 0; i < locs->temp_count(); i++) {
1218 Location loc = locs->temp(i); 1236 Location loc = locs->temp(i);
1219 if (loc.IsRegister()) { 1237 if (loc.IsRegister()) {
1220 // Check that a register is not specified twice in the summary. 1238 // Check that a register is not specified twice in the summary.
1221 ASSERT(!blocked_registers[loc.reg()]); 1239 ASSERT(!blocked_registers[loc.reg()]);
1222 blocked_registers[loc.reg()] = true; 1240 blocked_registers[loc.reg()] = true;
1223 } 1241 }
1224 } 1242 }
1225 1243
1226 if (locs->out(0).IsRegister()) { 1244 if (locs->out(0).IsRegister()) {
1227 // Fixed output registers are allowed to overlap with 1245 // Fixed output registers are allowed to overlap with
1228 // temps and inputs. 1246 // temps and inputs.
1229 blocked_registers[locs->out(0).reg()] = true; 1247 blocked_registers[locs->out(0).reg()] = true;
1230 } 1248 }
1231 1249
1232 // Do not allocate known registers.
1233 blocked_registers[SPREG] = true;
1234 blocked_registers[FPREG] = true;
1235 if (TMP != kNoRegister) {
1236 blocked_registers[TMP] = true;
1237 }
1238 if (TMP2 != kNoRegister) {
1239 blocked_registers[TMP2] = true;
1240 }
1241 if (PP != kNoRegister) {
1242 blocked_registers[PP] = true;
1243 }
1244 blocked_registers[THR] = true;
1245
1246 // Block all non-free registers. 1250 // Block all non-free registers.
1247 for (intptr_t i = 0; i < kFirstFreeCpuRegister; i++) { 1251 for (intptr_t i = 0; i < kFirstFreeCpuRegister; i++) {
1248 blocked_registers[i] = true; 1252 blocked_registers[i] = true;
1249 } 1253 }
1250 for (intptr_t i = kLastFreeCpuRegister + 1; i < kNumberOfCpuRegisters; i++) { 1254 for (intptr_t i = kLastFreeCpuRegister + 1; i < kNumberOfCpuRegisters; i++) {
1251 blocked_registers[i] = true; 1255 blocked_registers[i] = true;
1252 } 1256 }
1253 1257
1254 // Allocate all unallocated input locations. 1258 // Allocate all unallocated input locations.
1255 const bool should_pop = !instr->IsPushArgument() && !instr->IsPushTemp(); 1259 const bool should_pop = !instr->IsPushArgument() && !instr->IsPushTemp();
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after
1489 } 1493 }
1490 1494
1491 1495
1492 ParallelMoveResolver::ScratchFpuRegisterScope::~ScratchFpuRegisterScope() { 1496 ParallelMoveResolver::ScratchFpuRegisterScope::~ScratchFpuRegisterScope() {
1493 if (spilled_) { 1497 if (spilled_) {
1494 resolver_->RestoreFpuScratch(reg_); 1498 resolver_->RestoreFpuScratch(reg_);
1495 } 1499 }
1496 } 1500 }
1497 1501
1498 1502
1499 static inline intptr_t MaskBit(Register reg) {
1500 return (reg != kNoRegister) ? (1 << reg) : 0;
1501 }
1502
1503
1504 ParallelMoveResolver::ScratchRegisterScope::ScratchRegisterScope( 1503 ParallelMoveResolver::ScratchRegisterScope::ScratchRegisterScope(
1505 ParallelMoveResolver* resolver, Register blocked) 1504 ParallelMoveResolver* resolver, Register blocked)
1506 : resolver_(resolver), 1505 : resolver_(resolver),
1507 reg_(kNoRegister), 1506 reg_(kNoRegister),
1508 spilled_(false) { 1507 spilled_(false) {
1509 uword blocked_mask = MaskBit(blocked) 1508 uword blocked_mask = REG_MASK_BIT(blocked) | kReservedCpuRegisters;
1510 | MaskBit(SPREG)
1511 | MaskBit(FPREG)
1512 | MaskBit(TMP)
1513 | MaskBit(TMP2)
1514 | MaskBit(PP);
1515 if (resolver->compiler_->intrinsic_mode()) { 1509 if (resolver->compiler_->intrinsic_mode()) {
1516 // Block additional registers that must be preserved for intrinsics. 1510 // Block additional registers that must be preserved for intrinsics.
1517 blocked_mask |= MaskBit(ARGS_DESC_REG); 1511 blocked_mask |= REG_MASK_BIT(ARGS_DESC_REG);
1518 } 1512 }
1519 reg_ = static_cast<Register>( 1513 reg_ = static_cast<Register>(
1520 resolver_->AllocateScratchRegister(Location::kRegister, 1514 resolver_->AllocateScratchRegister(Location::kRegister,
1521 blocked_mask, 1515 blocked_mask,
1522 kFirstFreeCpuRegister, 1516 kFirstFreeCpuRegister,
1523 kLastFreeCpuRegister, 1517 kLastFreeCpuRegister,
1524 &spilled_)); 1518 &spilled_));
1525 1519
1526 if (spilled_) { 1520 if (spilled_) {
1527 resolver->SpillScratch(reg_); 1521 resolver->SpillScratch(reg_);
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
1728 1722
1729 1723
1730 void FlowGraphCompiler::FrameStateClear() { 1724 void FlowGraphCompiler::FrameStateClear() {
1731 ASSERT(!is_optimizing()); 1725 ASSERT(!is_optimizing());
1732 frame_state_.TruncateTo(0); 1726 frame_state_.TruncateTo(0);
1733 } 1727 }
1734 #endif 1728 #endif
1735 1729
1736 1730
1737 } // namespace dart 1731 } // namespace dart
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