summaryrefslogtreecommitdiff
path: root/compiler/optimizing
diff options
context:
space:
mode:
author Vladimir Marko <vmarko@google.com> 2015-11-23 19:49:34 +0000
committer Vladimir Marko <vmarko@google.com> 2015-12-23 09:59:07 +0000
commit5f7b58ea1adfc0639dd605b65f59198d3763f801 (patch)
tree04556e673cdd3967cc967ff79931eab49e523956 /compiler/optimizing
parent1201804d1813d7db0accead9721d67c40b3de564 (diff)
Rewrite HInstruction::Is/As<type>().
Make Is<type>() and As<type>() non-virtual for concrete instruction types, relying on GetKind(), and mark GetKind() as PURE to improve optimization opportunities. This reduces the number of relocations in libart-compiler.so's .rel.dyn section by ~4K, or ~44%, and in .data.rel.ro by ~18K, or ~65%. The file is 96KiB smaller for Nexus 5, including 8KiB reduction of the .text section. Unfortunately, the g++/clang++ __attribute__((pure)) is not strong enough to avoid duplicated virtual calls and we would need the C++ [[pure]] attribute proposed in n3744 instead. To work around this deficiency, we introduce an extra non-virtual indirection for GetKind(), so that the compiler can optimize common expressions such as instruction->IsAdd() || instruction->IsSub() or instruction->IsAdd() && instruction->AsAdd()->... which contain two virtual calls to GetKind() after inlining. Change-Id: I83787de0671a5cb9f5b0a5f4a536cef239d5b401
Diffstat (limited to 'compiler/optimizing')
-rw-r--r--compiler/optimizing/code_generator_arm.cc44
-rw-r--r--compiler/optimizing/code_generator_arm.h2
-rw-r--r--compiler/optimizing/code_generator_arm64.cc8
-rw-r--r--compiler/optimizing/code_generator_arm64.h2
-rw-r--r--compiler/optimizing/code_generator_mips.cc44
-rw-r--r--compiler/optimizing/code_generator_mips.h2
-rw-r--r--compiler/optimizing/code_generator_mips64.cc44
-rw-r--r--compiler/optimizing/code_generator_mips64.h2
-rw-r--r--compiler/optimizing/code_generator_x86.cc46
-rw-r--r--compiler/optimizing/code_generator_x86.h2
-rw-r--r--compiler/optimizing/code_generator_x86_64.cc44
-rw-r--r--compiler/optimizing/code_generator_x86_64.h2
-rw-r--r--compiler/optimizing/nodes.cc6
-rw-r--r--compiler/optimizing/nodes.h58
14 files changed, 176 insertions, 130 deletions
diff --git a/compiler/optimizing/code_generator_arm.cc b/compiler/optimizing/code_generator_arm.cc
index 9fda83840c..07cc059983 100644
--- a/compiler/optimizing/code_generator_arm.cc
+++ b/compiler/optimizing/code_generator_arm.cc
@@ -1618,7 +1618,7 @@ void InstructionCodeGeneratorARM::VisitDeoptimize(HDeoptimize* deoptimize) {
/* false_target */ nullptr);
}
-void LocationsBuilderARM::VisitCondition(HCondition* cond) {
+void LocationsBuilderARM::HandleCondition(HCondition* cond) {
LocationSummary* locations =
new (GetGraph()->GetArena()) LocationSummary(cond, LocationSummary::kNoCall);
// Handle the long/FP comparisons made in instruction simplification.
@@ -1649,7 +1649,7 @@ void LocationsBuilderARM::VisitCondition(HCondition* cond) {
}
}
-void InstructionCodeGeneratorARM::VisitCondition(HCondition* cond) {
+void InstructionCodeGeneratorARM::HandleCondition(HCondition* cond) {
if (!cond->NeedsMaterialization()) {
return;
}
@@ -1706,83 +1706,83 @@ void InstructionCodeGeneratorARM::VisitCondition(HCondition* cond) {
}
void LocationsBuilderARM::VisitEqual(HEqual* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void InstructionCodeGeneratorARM::VisitEqual(HEqual* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void LocationsBuilderARM::VisitNotEqual(HNotEqual* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void InstructionCodeGeneratorARM::VisitNotEqual(HNotEqual* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void LocationsBuilderARM::VisitLessThan(HLessThan* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void InstructionCodeGeneratorARM::VisitLessThan(HLessThan* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void LocationsBuilderARM::VisitLessThanOrEqual(HLessThanOrEqual* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void InstructionCodeGeneratorARM::VisitLessThanOrEqual(HLessThanOrEqual* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void LocationsBuilderARM::VisitGreaterThan(HGreaterThan* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void InstructionCodeGeneratorARM::VisitGreaterThan(HGreaterThan* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void LocationsBuilderARM::VisitGreaterThanOrEqual(HGreaterThanOrEqual* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void InstructionCodeGeneratorARM::VisitGreaterThanOrEqual(HGreaterThanOrEqual* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void LocationsBuilderARM::VisitBelow(HBelow* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void InstructionCodeGeneratorARM::VisitBelow(HBelow* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void LocationsBuilderARM::VisitBelowOrEqual(HBelowOrEqual* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void InstructionCodeGeneratorARM::VisitBelowOrEqual(HBelowOrEqual* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void LocationsBuilderARM::VisitAbove(HAbove* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void InstructionCodeGeneratorARM::VisitAbove(HAbove* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void LocationsBuilderARM::VisitAboveOrEqual(HAboveOrEqual* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void InstructionCodeGeneratorARM::VisitAboveOrEqual(HAboveOrEqual* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void LocationsBuilderARM::VisitLocal(HLocal* local) {
diff --git a/compiler/optimizing/code_generator_arm.h b/compiler/optimizing/code_generator_arm.h
index 8193c2808c..b7c58e1248 100644
--- a/compiler/optimizing/code_generator_arm.h
+++ b/compiler/optimizing/code_generator_arm.h
@@ -170,6 +170,7 @@ class LocationsBuilderARM : public HGraphVisitor {
private:
void HandleInvoke(HInvoke* invoke);
void HandleBitwiseOperation(HBinaryOperation* operation, Opcode opcode);
+ void HandleCondition(HCondition* condition);
void HandleIntegerRotate(LocationSummary* locations);
void HandleLongRotate(LocationSummary* locations);
void HandleRotate(HRor* ror);
@@ -216,6 +217,7 @@ class InstructionCodeGeneratorARM : public HGraphVisitor {
void GenerateOrrConst(Register out, Register first, uint32_t value);
void GenerateEorConst(Register out, Register first, uint32_t value);
void HandleBitwiseOperation(HBinaryOperation* operation);
+ void HandleCondition(HCondition* condition);
void HandleIntegerRotate(LocationSummary* locations);
void HandleLongRotate(LocationSummary* locations);
void HandleRotate(HRor* ror);
diff --git a/compiler/optimizing/code_generator_arm64.cc b/compiler/optimizing/code_generator_arm64.cc
index 52058302be..068676da0e 100644
--- a/compiler/optimizing/code_generator_arm64.cc
+++ b/compiler/optimizing/code_generator_arm64.cc
@@ -2427,7 +2427,7 @@ void InstructionCodeGeneratorARM64::VisitCompare(HCompare* compare) {
}
}
-void LocationsBuilderARM64::VisitCondition(HCondition* instruction) {
+void LocationsBuilderARM64::HandleCondition(HCondition* instruction) {
LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(instruction);
if (Primitive::IsFloatingPointType(instruction->InputAt(0)->GetType())) {
@@ -2447,7 +2447,7 @@ void LocationsBuilderARM64::VisitCondition(HCondition* instruction) {
}
}
-void InstructionCodeGeneratorARM64::VisitCondition(HCondition* instruction) {
+void InstructionCodeGeneratorARM64::HandleCondition(HCondition* instruction) {
if (!instruction->NeedsMaterialization()) {
return;
}
@@ -2495,8 +2495,8 @@ void InstructionCodeGeneratorARM64::VisitCondition(HCondition* instruction) {
M(Above) \
M(AboveOrEqual)
#define DEFINE_CONDITION_VISITORS(Name) \
-void LocationsBuilderARM64::Visit##Name(H##Name* comp) { VisitCondition(comp); } \
-void InstructionCodeGeneratorARM64::Visit##Name(H##Name* comp) { VisitCondition(comp); }
+void LocationsBuilderARM64::Visit##Name(H##Name* comp) { HandleCondition(comp); } \
+void InstructionCodeGeneratorARM64::Visit##Name(H##Name* comp) { HandleCondition(comp); }
FOR_EACH_CONDITION_INSTRUCTION(DEFINE_CONDITION_VISITORS)
#undef DEFINE_CONDITION_VISITORS
#undef FOR_EACH_CONDITION_INSTRUCTION
diff --git a/compiler/optimizing/code_generator_arm64.h b/compiler/optimizing/code_generator_arm64.h
index 7950f078ad..0e90ac6345 100644
--- a/compiler/optimizing/code_generator_arm64.h
+++ b/compiler/optimizing/code_generator_arm64.h
@@ -215,6 +215,7 @@ class InstructionCodeGeneratorARM64 : public HGraphVisitor {
const FieldInfo& field_info,
bool value_can_be_null);
void HandleFieldGet(HInstruction* instruction, const FieldInfo& field_info);
+ void HandleCondition(HCondition* instruction);
void HandleShift(HBinaryOperation* instr);
void GenerateImplicitNullCheck(HNullCheck* instruction);
void GenerateExplicitNullCheck(HNullCheck* instruction);
@@ -257,6 +258,7 @@ class LocationsBuilderARM64 : public HGraphVisitor {
void HandleFieldSet(HInstruction* instruction);
void HandleFieldGet(HInstruction* instruction);
void HandleInvoke(HInvoke* instr);
+ void HandleCondition(HCondition* instruction);
void HandleShift(HBinaryOperation* instr);
CodeGeneratorARM64* const codegen_;
diff --git a/compiler/optimizing/code_generator_mips.cc b/compiler/optimizing/code_generator_mips.cc
index ae0f2c8935..ef6b403eea 100644
--- a/compiler/optimizing/code_generator_mips.cc
+++ b/compiler/optimizing/code_generator_mips.cc
@@ -2092,7 +2092,7 @@ void InstructionCodeGeneratorMIPS::VisitCompare(HCompare* instruction) {
}
}
-void LocationsBuilderMIPS::VisitCondition(HCondition* instruction) {
+void LocationsBuilderMIPS::HandleCondition(HCondition* instruction) {
LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(instruction);
switch (instruction->InputAt(0)->GetType()) {
default:
@@ -2112,7 +2112,7 @@ void LocationsBuilderMIPS::VisitCondition(HCondition* instruction) {
}
}
-void InstructionCodeGeneratorMIPS::VisitCondition(HCondition* instruction) {
+void InstructionCodeGeneratorMIPS::HandleCondition(HCondition* instruction) {
if (!instruction->NeedsMaterialization()) {
return;
}
@@ -4792,83 +4792,83 @@ void InstructionCodeGeneratorMIPS::VisitBoundType(HBoundType* instruction ATTRIB
}
void LocationsBuilderMIPS::VisitEqual(HEqual* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void InstructionCodeGeneratorMIPS::VisitEqual(HEqual* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void LocationsBuilderMIPS::VisitNotEqual(HNotEqual* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void InstructionCodeGeneratorMIPS::VisitNotEqual(HNotEqual* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void LocationsBuilderMIPS::VisitLessThan(HLessThan* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void InstructionCodeGeneratorMIPS::VisitLessThan(HLessThan* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void LocationsBuilderMIPS::VisitLessThanOrEqual(HLessThanOrEqual* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void InstructionCodeGeneratorMIPS::VisitLessThanOrEqual(HLessThanOrEqual* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void LocationsBuilderMIPS::VisitGreaterThan(HGreaterThan* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void InstructionCodeGeneratorMIPS::VisitGreaterThan(HGreaterThan* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void LocationsBuilderMIPS::VisitGreaterThanOrEqual(HGreaterThanOrEqual* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void InstructionCodeGeneratorMIPS::VisitGreaterThanOrEqual(HGreaterThanOrEqual* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void LocationsBuilderMIPS::VisitBelow(HBelow* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void InstructionCodeGeneratorMIPS::VisitBelow(HBelow* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void LocationsBuilderMIPS::VisitBelowOrEqual(HBelowOrEqual* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void InstructionCodeGeneratorMIPS::VisitBelowOrEqual(HBelowOrEqual* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void LocationsBuilderMIPS::VisitAbove(HAbove* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void InstructionCodeGeneratorMIPS::VisitAbove(HAbove* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void LocationsBuilderMIPS::VisitAboveOrEqual(HAboveOrEqual* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void InstructionCodeGeneratorMIPS::VisitAboveOrEqual(HAboveOrEqual* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void LocationsBuilderMIPS::VisitFakeString(HFakeString* instruction) {
diff --git a/compiler/optimizing/code_generator_mips.h b/compiler/optimizing/code_generator_mips.h
index 1ee6bdef8e..38302ad315 100644
--- a/compiler/optimizing/code_generator_mips.h
+++ b/compiler/optimizing/code_generator_mips.h
@@ -185,6 +185,7 @@ class LocationsBuilderMIPS : public HGraphVisitor {
private:
void HandleInvoke(HInvoke* invoke);
void HandleBinaryOp(HBinaryOperation* operation);
+ void HandleCondition(HCondition* instruction);
void HandleShift(HBinaryOperation* operation);
void HandleFieldSet(HInstruction* instruction, const FieldInfo& field_info);
void HandleFieldGet(HInstruction* instruction, const FieldInfo& field_info);
@@ -220,6 +221,7 @@ class InstructionCodeGeneratorMIPS : public HGraphVisitor {
void GenerateMemoryBarrier(MemBarrierKind kind);
void GenerateSuspendCheck(HSuspendCheck* check, HBasicBlock* successor);
void HandleBinaryOp(HBinaryOperation* operation);
+ void HandleCondition(HCondition* instruction);
void HandleShift(HBinaryOperation* operation);
void HandleFieldSet(HInstruction* instruction, const FieldInfo& field_info, uint32_t dex_pc);
void HandleFieldGet(HInstruction* instruction, const FieldInfo& field_info, uint32_t dex_pc);
diff --git a/compiler/optimizing/code_generator_mips64.cc b/compiler/optimizing/code_generator_mips64.cc
index 1e428a06e1..0f340a9a15 100644
--- a/compiler/optimizing/code_generator_mips64.cc
+++ b/compiler/optimizing/code_generator_mips64.cc
@@ -1852,7 +1852,7 @@ void InstructionCodeGeneratorMIPS64::VisitCompare(HCompare* instruction) {
}
}
-void LocationsBuilderMIPS64::VisitCondition(HCondition* instruction) {
+void LocationsBuilderMIPS64::HandleCondition(HCondition* instruction) {
LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(instruction);
switch (instruction->InputAt(0)->GetType()) {
default:
@@ -1872,7 +1872,7 @@ void LocationsBuilderMIPS64::VisitCondition(HCondition* instruction) {
}
}
-void InstructionCodeGeneratorMIPS64::VisitCondition(HCondition* instruction) {
+void InstructionCodeGeneratorMIPS64::HandleCondition(HCondition* instruction) {
if (!instruction->NeedsMaterialization()) {
return;
}
@@ -4075,83 +4075,83 @@ void InstructionCodeGeneratorMIPS64::VisitBoundType(HBoundType* instruction ATTR
}
void LocationsBuilderMIPS64::VisitEqual(HEqual* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void InstructionCodeGeneratorMIPS64::VisitEqual(HEqual* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void LocationsBuilderMIPS64::VisitNotEqual(HNotEqual* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void InstructionCodeGeneratorMIPS64::VisitNotEqual(HNotEqual* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void LocationsBuilderMIPS64::VisitLessThan(HLessThan* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void InstructionCodeGeneratorMIPS64::VisitLessThan(HLessThan* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void LocationsBuilderMIPS64::VisitLessThanOrEqual(HLessThanOrEqual* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void InstructionCodeGeneratorMIPS64::VisitLessThanOrEqual(HLessThanOrEqual* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void LocationsBuilderMIPS64::VisitGreaterThan(HGreaterThan* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void InstructionCodeGeneratorMIPS64::VisitGreaterThan(HGreaterThan* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void LocationsBuilderMIPS64::VisitGreaterThanOrEqual(HGreaterThanOrEqual* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void InstructionCodeGeneratorMIPS64::VisitGreaterThanOrEqual(HGreaterThanOrEqual* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void LocationsBuilderMIPS64::VisitBelow(HBelow* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void InstructionCodeGeneratorMIPS64::VisitBelow(HBelow* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void LocationsBuilderMIPS64::VisitBelowOrEqual(HBelowOrEqual* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void InstructionCodeGeneratorMIPS64::VisitBelowOrEqual(HBelowOrEqual* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void LocationsBuilderMIPS64::VisitAbove(HAbove* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void InstructionCodeGeneratorMIPS64::VisitAbove(HAbove* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void LocationsBuilderMIPS64::VisitAboveOrEqual(HAboveOrEqual* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void InstructionCodeGeneratorMIPS64::VisitAboveOrEqual(HAboveOrEqual* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void LocationsBuilderMIPS64::VisitFakeString(HFakeString* instruction) {
diff --git a/compiler/optimizing/code_generator_mips64.h b/compiler/optimizing/code_generator_mips64.h
index 1593cec2a6..60ff96dc43 100644
--- a/compiler/optimizing/code_generator_mips64.h
+++ b/compiler/optimizing/code_generator_mips64.h
@@ -189,6 +189,7 @@ class LocationsBuilderMIPS64 : public HGraphVisitor {
private:
void HandleInvoke(HInvoke* invoke);
void HandleBinaryOp(HBinaryOperation* operation);
+ void HandleCondition(HCondition* instruction);
void HandleShift(HBinaryOperation* operation);
void HandleFieldSet(HInstruction* instruction, const FieldInfo& field_info);
void HandleFieldGet(HInstruction* instruction, const FieldInfo& field_info);
@@ -224,6 +225,7 @@ class InstructionCodeGeneratorMIPS64 : public HGraphVisitor {
void GenerateMemoryBarrier(MemBarrierKind kind);
void GenerateSuspendCheck(HSuspendCheck* check, HBasicBlock* successor);
void HandleBinaryOp(HBinaryOperation* operation);
+ void HandleCondition(HCondition* instruction);
void HandleShift(HBinaryOperation* operation);
void HandleFieldSet(HInstruction* instruction, const FieldInfo& field_info);
void HandleFieldGet(HInstruction* instruction, const FieldInfo& field_info);
diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc
index 7a5b8dbe46..313610975b 100644
--- a/compiler/optimizing/code_generator_x86.cc
+++ b/compiler/optimizing/code_generator_x86.cc
@@ -1554,7 +1554,7 @@ void InstructionCodeGeneratorX86::GenerateTestAndBranch(HInstruction* instructio
Location lhs = condition->GetLocations()->InAt(0);
Location rhs = condition->GetLocations()->InAt(1);
- // LHS is guaranteed to be in a register (see LocationsBuilderX86::VisitCondition).
+ // LHS is guaranteed to be in a register (see LocationsBuilderX86::HandleCondition).
if (rhs.IsRegister()) {
__ cmpl(lhs.AsRegister<Register>(), rhs.AsRegister<Register>());
} else if (rhs.IsConstant()) {
@@ -1659,7 +1659,7 @@ void LocationsBuilderX86::VisitStoreLocal(HStoreLocal* store) {
void InstructionCodeGeneratorX86::VisitStoreLocal(HStoreLocal* store ATTRIBUTE_UNUSED) {
}
-void LocationsBuilderX86::VisitCondition(HCondition* cond) {
+void LocationsBuilderX86::HandleCondition(HCondition* cond) {
LocationSummary* locations =
new (GetGraph()->GetArena()) LocationSummary(cond, LocationSummary::kNoCall);
// Handle the long/FP comparisons made in instruction simplification.
@@ -1692,7 +1692,7 @@ void LocationsBuilderX86::VisitCondition(HCondition* cond) {
}
}
-void InstructionCodeGeneratorX86::VisitCondition(HCondition* cond) {
+void InstructionCodeGeneratorX86::HandleCondition(HCondition* cond) {
if (!cond->NeedsMaterialization()) {
return;
}
@@ -1753,83 +1753,83 @@ void InstructionCodeGeneratorX86::VisitCondition(HCondition* cond) {
}
void LocationsBuilderX86::VisitEqual(HEqual* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void InstructionCodeGeneratorX86::VisitEqual(HEqual* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void LocationsBuilderX86::VisitNotEqual(HNotEqual* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void InstructionCodeGeneratorX86::VisitNotEqual(HNotEqual* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void LocationsBuilderX86::VisitLessThan(HLessThan* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void InstructionCodeGeneratorX86::VisitLessThan(HLessThan* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void LocationsBuilderX86::VisitLessThanOrEqual(HLessThanOrEqual* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void InstructionCodeGeneratorX86::VisitLessThanOrEqual(HLessThanOrEqual* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void LocationsBuilderX86::VisitGreaterThan(HGreaterThan* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void InstructionCodeGeneratorX86::VisitGreaterThan(HGreaterThan* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void LocationsBuilderX86::VisitGreaterThanOrEqual(HGreaterThanOrEqual* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void InstructionCodeGeneratorX86::VisitGreaterThanOrEqual(HGreaterThanOrEqual* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void LocationsBuilderX86::VisitBelow(HBelow* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void InstructionCodeGeneratorX86::VisitBelow(HBelow* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void LocationsBuilderX86::VisitBelowOrEqual(HBelowOrEqual* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void InstructionCodeGeneratorX86::VisitBelowOrEqual(HBelowOrEqual* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void LocationsBuilderX86::VisitAbove(HAbove* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void InstructionCodeGeneratorX86::VisitAbove(HAbove* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void LocationsBuilderX86::VisitAboveOrEqual(HAboveOrEqual* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void InstructionCodeGeneratorX86::VisitAboveOrEqual(HAboveOrEqual* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void LocationsBuilderX86::VisitIntConstant(HIntConstant* constant) {
diff --git a/compiler/optimizing/code_generator_x86.h b/compiler/optimizing/code_generator_x86.h
index f0ead0356d..3d343177d0 100644
--- a/compiler/optimizing/code_generator_x86.h
+++ b/compiler/optimizing/code_generator_x86.h
@@ -167,6 +167,7 @@ class LocationsBuilderX86 : public HGraphVisitor {
private:
void HandleBitwiseOperation(HBinaryOperation* instruction);
void HandleInvoke(HInvoke* invoke);
+ void HandleCondition(HCondition* condition);
void HandleShift(HBinaryOperation* instruction);
void HandleFieldSet(HInstruction* instruction, const FieldInfo& field_info);
void HandleFieldGet(HInstruction* instruction, const FieldInfo& field_info);
@@ -213,6 +214,7 @@ class InstructionCodeGeneratorX86 : public HGraphVisitor {
void DivByPowerOfTwo(HDiv* instruction);
void GenerateDivRemWithAnyConstant(HBinaryOperation* instruction);
void GenerateRemFP(HRem* rem);
+ void HandleCondition(HCondition* condition);
void HandleShift(HBinaryOperation* instruction);
void GenerateShlLong(const Location& loc, Register shifter);
void GenerateShrLong(const Location& loc, Register shifter);
diff --git a/compiler/optimizing/code_generator_x86_64.cc b/compiler/optimizing/code_generator_x86_64.cc
index 1e6d50610b..0de616cbd2 100644
--- a/compiler/optimizing/code_generator_x86_64.cc
+++ b/compiler/optimizing/code_generator_x86_64.cc
@@ -1643,7 +1643,7 @@ void LocationsBuilderX86_64::VisitStoreLocal(HStoreLocal* store) {
void InstructionCodeGeneratorX86_64::VisitStoreLocal(HStoreLocal* store ATTRIBUTE_UNUSED) {
}
-void LocationsBuilderX86_64::VisitCondition(HCondition* cond) {
+void LocationsBuilderX86_64::HandleCondition(HCondition* cond) {
LocationSummary* locations =
new (GetGraph()->GetArena()) LocationSummary(cond, LocationSummary::kNoCall);
// Handle the long/FP comparisons made in instruction simplification.
@@ -1667,7 +1667,7 @@ void LocationsBuilderX86_64::VisitCondition(HCondition* cond) {
}
}
-void InstructionCodeGeneratorX86_64::VisitCondition(HCondition* cond) {
+void InstructionCodeGeneratorX86_64::HandleCondition(HCondition* cond) {
if (!cond->NeedsMaterialization()) {
return;
}
@@ -1765,83 +1765,83 @@ void InstructionCodeGeneratorX86_64::VisitCondition(HCondition* cond) {
}
void LocationsBuilderX86_64::VisitEqual(HEqual* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void InstructionCodeGeneratorX86_64::VisitEqual(HEqual* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void LocationsBuilderX86_64::VisitNotEqual(HNotEqual* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void InstructionCodeGeneratorX86_64::VisitNotEqual(HNotEqual* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void LocationsBuilderX86_64::VisitLessThan(HLessThan* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void InstructionCodeGeneratorX86_64::VisitLessThan(HLessThan* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void LocationsBuilderX86_64::VisitLessThanOrEqual(HLessThanOrEqual* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void InstructionCodeGeneratorX86_64::VisitLessThanOrEqual(HLessThanOrEqual* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void LocationsBuilderX86_64::VisitGreaterThan(HGreaterThan* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void InstructionCodeGeneratorX86_64::VisitGreaterThan(HGreaterThan* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void LocationsBuilderX86_64::VisitGreaterThanOrEqual(HGreaterThanOrEqual* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void InstructionCodeGeneratorX86_64::VisitGreaterThanOrEqual(HGreaterThanOrEqual* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void LocationsBuilderX86_64::VisitBelow(HBelow* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void InstructionCodeGeneratorX86_64::VisitBelow(HBelow* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void LocationsBuilderX86_64::VisitBelowOrEqual(HBelowOrEqual* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void InstructionCodeGeneratorX86_64::VisitBelowOrEqual(HBelowOrEqual* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void LocationsBuilderX86_64::VisitAbove(HAbove* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void InstructionCodeGeneratorX86_64::VisitAbove(HAbove* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void LocationsBuilderX86_64::VisitAboveOrEqual(HAboveOrEqual* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void InstructionCodeGeneratorX86_64::VisitAboveOrEqual(HAboveOrEqual* comp) {
- VisitCondition(comp);
+ HandleCondition(comp);
}
void LocationsBuilderX86_64::VisitCompare(HCompare* compare) {
diff --git a/compiler/optimizing/code_generator_x86_64.h b/compiler/optimizing/code_generator_x86_64.h
index e5a487c761..9995416138 100644
--- a/compiler/optimizing/code_generator_x86_64.h
+++ b/compiler/optimizing/code_generator_x86_64.h
@@ -172,6 +172,7 @@ class LocationsBuilderX86_64 : public HGraphVisitor {
private:
void HandleInvoke(HInvoke* invoke);
void HandleBitwiseOperation(HBinaryOperation* operation);
+ void HandleCondition(HCondition* condition);
void HandleShift(HBinaryOperation* operation);
void HandleFieldSet(HInstruction* instruction, const FieldInfo& field_info);
void HandleFieldGet(HInstruction* instruction);
@@ -213,6 +214,7 @@ class InstructionCodeGeneratorX86_64 : public HGraphVisitor {
void DivByPowerOfTwo(HDiv* instruction);
void GenerateDivRemWithAnyConstant(HBinaryOperation* instruction);
void GenerateDivRemIntegral(HBinaryOperation* instruction);
+ void HandleCondition(HCondition* condition);
void HandleShift(HBinaryOperation* operation);
void HandleFieldSet(HInstruction* instruction,
diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc
index 926bc156cf..a37298c76e 100644
--- a/compiler/optimizing/nodes.cc
+++ b/compiler/optimizing/nodes.cc
@@ -777,6 +777,10 @@ void HEnvironment::RemoveAsUserOfInput(size_t index) const {
user_record.GetInstruction()->RemoveEnvironmentUser(user_record.GetUseNode());
}
+HInstruction::InstructionKind HInstruction::GetKind() const {
+ return GetKindInternal();
+}
+
HInstruction* HInstruction::GetNextDisregardingMoves() const {
HInstruction* next = GetNext();
while (next != nullptr && next->IsParallelMove()) {
@@ -960,7 +964,7 @@ void H##name::Accept(HGraphVisitor* visitor) { \
visitor->Visit##name(this); \
}
-FOR_EACH_INSTRUCTION(DEFINE_ACCEPT)
+FOR_EACH_CONCRETE_INSTRUCTION(DEFINE_ACCEPT)
#undef DEFINE_ACCEPT
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index 1f8ef4717c..00820a66e7 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -1034,7 +1034,6 @@ class HLoopInformationOutwardIterator : public ValueObject {
M(ClearException, Instruction) \
M(ClinitCheck, Instruction) \
M(Compare, BinaryOperation) \
- M(Condition, BinaryOperation) \
M(CurrentMethod, Instruction) \
M(Deoptimize, Instruction) \
M(Div, BinaryOperation) \
@@ -1141,27 +1140,34 @@ class HLoopInformationOutwardIterator : public ValueObject {
FOR_EACH_CONCRETE_INSTRUCTION_X86(M) \
FOR_EACH_CONCRETE_INSTRUCTION_X86_64(M)
-#define FOR_EACH_INSTRUCTION(M) \
- FOR_EACH_CONCRETE_INSTRUCTION(M) \
+#define FOR_EACH_ABSTRACT_INSTRUCTION(M) \
+ M(Condition, BinaryOperation) \
M(Constant, Instruction) \
M(UnaryOperation, Instruction) \
M(BinaryOperation, Instruction) \
M(Invoke, Instruction)
+#define FOR_EACH_INSTRUCTION(M) \
+ FOR_EACH_CONCRETE_INSTRUCTION(M) \
+ FOR_EACH_ABSTRACT_INSTRUCTION(M)
+
#define FORWARD_DECLARATION(type, super) class H##type;
FOR_EACH_INSTRUCTION(FORWARD_DECLARATION)
#undef FORWARD_DECLARATION
#define DECLARE_INSTRUCTION(type) \
- InstructionKind GetKind() const OVERRIDE { return k##type; } \
+ InstructionKind GetKindInternal() const OVERRIDE { return k##type; } \
const char* DebugName() const OVERRIDE { return #type; } \
- const H##type* As##type() const OVERRIDE { return this; } \
- H##type* As##type() OVERRIDE { return this; } \
bool InstructionTypeEquals(HInstruction* other) const OVERRIDE { \
return other->Is##type(); \
} \
void Accept(HGraphVisitor* visitor) OVERRIDE
+#define DECLARE_ABSTRACT_INSTRUCTION(type) \
+ bool Is##type() const { return As##type() != nullptr; } \
+ const H##type* As##type() const { return this; } \
+ H##type* As##type() { return this; }
+
template <typename T> class HUseList;
template <typename T>
@@ -1972,11 +1978,18 @@ class HInstruction : public ArenaObject<kArenaAllocInstruction> {
void MoveBeforeFirstUserAndOutOfLoops();
#define INSTRUCTION_TYPE_CHECK(type, super) \
+ bool Is##type() const; \
+ const H##type* As##type() const; \
+ H##type* As##type();
+
+ FOR_EACH_CONCRETE_INSTRUCTION(INSTRUCTION_TYPE_CHECK)
+#undef INSTRUCTION_TYPE_CHECK
+
+#define INSTRUCTION_TYPE_CHECK(type, super) \
bool Is##type() const { return (As##type() != nullptr); } \
virtual const H##type* As##type() const { return nullptr; } \
virtual H##type* As##type() { return nullptr; }
-
- FOR_EACH_INSTRUCTION(INSTRUCTION_TYPE_CHECK)
+ FOR_EACH_ABSTRACT_INSTRUCTION(INSTRUCTION_TYPE_CHECK)
#undef INSTRUCTION_TYPE_CHECK
// Returns whether the instruction can be moved within the graph.
@@ -1999,7 +2012,12 @@ class HInstruction : public ArenaObject<kArenaAllocInstruction> {
// 2) Their inputs are identical.
bool Equals(HInstruction* other) const;
- virtual InstructionKind GetKind() const = 0;
+ // TODO: Remove this indirection when the [[pure]] attribute proposal (n3744)
+ // is adopted and implemented by our C++ compiler(s). Fow now, we need to hide
+ // the virtual function because the __attribute__((__pure__)) doesn't really
+ // apply the strong requirement for virtual functions, preventing optimizations.
+ InstructionKind GetKind() const PURE;
+ virtual InstructionKind GetKindInternal() const = 0;
virtual size_t ComputeHashCode() const {
size_t result = GetKind();
@@ -2297,7 +2315,7 @@ class HConstant : public HExpression<0> {
virtual uint64_t GetValueAsUint64() const = 0;
- DECLARE_INSTRUCTION(Constant);
+ DECLARE_ABSTRACT_INSTRUCTION(Constant);
private:
DISALLOW_COPY_AND_ASSIGN(HConstant);
@@ -2558,7 +2576,7 @@ class HUnaryOperation : public HExpression<1> {
virtual HConstant* Evaluate(HIntConstant* x) const = 0;
virtual HConstant* Evaluate(HLongConstant* x) const = 0;
- DECLARE_INSTRUCTION(UnaryOperation);
+ DECLARE_ABSTRACT_INSTRUCTION(UnaryOperation);
private:
DISALLOW_COPY_AND_ASSIGN(HUnaryOperation);
@@ -2651,7 +2669,7 @@ class HBinaryOperation : public HExpression<2> {
// one. Otherwise it returns null.
HInstruction* GetLeastConstantLeft() const;
- DECLARE_INSTRUCTION(BinaryOperation);
+ DECLARE_ABSTRACT_INSTRUCTION(BinaryOperation);
private:
DISALLOW_COPY_AND_ASSIGN(HBinaryOperation);
@@ -2679,7 +2697,7 @@ class HCondition : public HBinaryOperation {
// `instruction`, and disregard moves in between.
bool IsBeforeWhenDisregardMoves(HInstruction* instruction) const;
- DECLARE_INSTRUCTION(Condition);
+ DECLARE_ABSTRACT_INSTRUCTION(Condition);
virtual IfCondition GetCondition() const = 0;
@@ -3288,7 +3306,7 @@ class HInvoke : public HInstruction {
bool IsIntrinsic() const { return intrinsic_ != Intrinsics::kNone; }
- DECLARE_INSTRUCTION(Invoke);
+ DECLARE_ABSTRACT_INSTRUCTION(Invoke);
protected:
HInvoke(ArenaAllocator* arena,
@@ -5869,6 +5887,18 @@ inline bool IsSameDexFile(const DexFile& lhs, const DexFile& rhs) {
return &lhs == &rhs;
}
+#define INSTRUCTION_TYPE_CHECK(type, super) \
+ inline bool HInstruction::Is##type() const { return GetKind() == k##type; } \
+ inline const H##type* HInstruction::As##type() const { \
+ return Is##type() ? down_cast<const H##type*>(this) : nullptr; \
+ } \
+ inline H##type* HInstruction::As##type() { \
+ return Is##type() ? static_cast<H##type*>(this) : nullptr; \
+ }
+
+ FOR_EACH_CONCRETE_INSTRUCTION(INSTRUCTION_TYPE_CHECK)
+#undef INSTRUCTION_TYPE_CHECK
+
} // namespace art
#endif // ART_COMPILER_OPTIMIZING_NODES_H_