summaryrefslogtreecommitdiff
path: root/compiler/optimizing/code_generator.cc
diff options
context:
space:
mode:
author Nicolas Geoffray <ngeoffray@google.com> 2015-03-05 11:22:00 +0000
committer Gerrit Code Review <noreply-gerritcodereview@google.com> 2015-03-05 11:22:01 +0000
commitaf8db2ea18135588b267fe9a0b2f7af734b906cc (patch)
treeb8bdb820be33317f23ef1d3e43d13b2b6bfb3ba5 /compiler/optimizing/code_generator.cc
parent65b50272a15c52d753f68df2468fe1792f2516ea (diff)
parent5f8741860d465410bfed495dbb5f794590d338da (diff)
Merge "[optimizing] Use callee-save registers for x86"
Diffstat (limited to 'compiler/optimizing/code_generator.cc')
-rw-r--r--compiler/optimizing/code_generator.cc65
1 files changed, 30 insertions, 35 deletions
diff --git a/compiler/optimizing/code_generator.cc b/compiler/optimizing/code_generator.cc
index ba5f7d8fab..ed3f949afe 100644
--- a/compiler/optimizing/code_generator.cc
+++ b/compiler/optimizing/code_generator.cc
@@ -216,6 +216,29 @@ int32_t CodeGenerator::GetStackSlot(HLocal* local) const {
}
}
+void CodeGenerator::BlockIfInRegister(Location location, bool is_out) const {
+ // The DCHECKS below check that a register is not specified twice in
+ // the summary. The out location can overlap with an input, so we need
+ // to special case it.
+ if (location.IsRegister()) {
+ DCHECK(is_out || !blocked_core_registers_[location.reg()]);
+ blocked_core_registers_[location.reg()] = true;
+ } else if (location.IsFpuRegister()) {
+ DCHECK(is_out || !blocked_fpu_registers_[location.reg()]);
+ blocked_fpu_registers_[location.reg()] = true;
+ } else if (location.IsFpuRegisterPair()) {
+ DCHECK(is_out || !blocked_fpu_registers_[location.AsFpuRegisterPairLow<int>()]);
+ blocked_fpu_registers_[location.AsFpuRegisterPairLow<int>()] = true;
+ DCHECK(is_out || !blocked_fpu_registers_[location.AsFpuRegisterPairHigh<int>()]);
+ blocked_fpu_registers_[location.AsFpuRegisterPairHigh<int>()] = true;
+ } else if (location.IsRegisterPair()) {
+ DCHECK(is_out || !blocked_core_registers_[location.AsRegisterPairLow<int>()]);
+ blocked_core_registers_[location.AsRegisterPairLow<int>()] = true;
+ DCHECK(is_out || !blocked_core_registers_[location.AsRegisterPairHigh<int>()]);
+ blocked_core_registers_[location.AsRegisterPairHigh<int>()] = true;
+ }
+}
+
void CodeGenerator::AllocateRegistersLocally(HInstruction* instruction) const {
LocationSummary* locations = instruction->GetLocations();
if (locations == nullptr) return;
@@ -234,46 +257,19 @@ void CodeGenerator::AllocateRegistersLocally(HInstruction* instruction) const {
// Mark all fixed input, temp and output registers as used.
for (size_t i = 0, e = locations->GetInputCount(); i < e; ++i) {
- Location loc = locations->InAt(i);
- // The DCHECKS below check that a register is not specified twice in
- // the summary.
- if (loc.IsRegister()) {
- DCHECK(!blocked_core_registers_[loc.reg()]);
- blocked_core_registers_[loc.reg()] = true;
- } else if (loc.IsFpuRegister()) {
- DCHECK(!blocked_fpu_registers_[loc.reg()]);
- blocked_fpu_registers_[loc.reg()] = true;
- } else if (loc.IsFpuRegisterPair()) {
- DCHECK(!blocked_fpu_registers_[loc.AsFpuRegisterPairLow<int>()]);
- blocked_fpu_registers_[loc.AsFpuRegisterPairLow<int>()] = true;
- DCHECK(!blocked_fpu_registers_[loc.AsFpuRegisterPairHigh<int>()]);
- blocked_fpu_registers_[loc.AsFpuRegisterPairHigh<int>()] = true;
- } else if (loc.IsRegisterPair()) {
- DCHECK(!blocked_core_registers_[loc.AsRegisterPairLow<int>()]);
- blocked_core_registers_[loc.AsRegisterPairLow<int>()] = true;
- DCHECK(!blocked_core_registers_[loc.AsRegisterPairHigh<int>()]);
- blocked_core_registers_[loc.AsRegisterPairHigh<int>()] = true;
- }
+ BlockIfInRegister(locations->InAt(i));
}
for (size_t i = 0, e = locations->GetTempCount(); i < e; ++i) {
Location loc = locations->GetTemp(i);
- // The DCHECKS below check that a register is not specified twice in
- // the summary.
- if (loc.IsRegister()) {
- DCHECK(!blocked_core_registers_[loc.reg()]);
- blocked_core_registers_[loc.reg()] = true;
- } else if (loc.IsFpuRegister()) {
- DCHECK(!blocked_fpu_registers_[loc.reg()]);
- blocked_fpu_registers_[loc.reg()] = true;
- } else {
- DCHECK(loc.GetPolicy() == Location::kRequiresRegister
- || loc.GetPolicy() == Location::kRequiresFpuRegister);
- }
+ BlockIfInRegister(loc);
+ }
+ Location result_location = locations->Out();
+ if (locations->OutputCanOverlapWithInputs()) {
+ BlockIfInRegister(result_location, /* is_out */ true);
}
- static constexpr bool kBaseline = true;
- SetupBlockedRegisters(kBaseline);
+ SetupBlockedRegisters(/* is_baseline */ true);
// Allocate all unallocated input locations.
for (size_t i = 0, e = locations->GetInputCount(); i < e; ++i) {
@@ -318,7 +314,6 @@ void CodeGenerator::AllocateRegistersLocally(HInstruction* instruction) const {
locations->SetTempAt(i, loc);
}
}
- Location result_location = locations->Out();
if (result_location.IsUnallocated()) {
switch (result_location.GetPolicy()) {
case Location::kAny: