Rewrite kMirOpSelect for all IF_ccZ opcodes.
Also improve special cases for ARM and add tests.
Change-Id: I06f575b9c7b547dbc431dbfadf2b927151fe16b9
diff --git a/compiler/dex/mir_optimization.cc b/compiler/dex/mir_optimization.cc
index 14d03a5..243452e 100644
--- a/compiler/dex/mir_optimization.cc
+++ b/compiler/dex/mir_optimization.cc
@@ -195,6 +195,28 @@
}
}
+static constexpr ConditionCode kIfCcZConditionCodes[] = {
+ kCondEq, kCondNe, kCondLt, kCondGe, kCondGt, kCondLe
+};
+
+COMPILE_ASSERT(arraysize(kIfCcZConditionCodes) == Instruction::IF_LEZ - Instruction::IF_EQZ + 1,
+ if_ccz_ccodes_size1);
+
+static constexpr bool IsInstructionIfCcZ(Instruction::Code opcode) {
+ return Instruction::IF_EQZ <= opcode && opcode <= Instruction::IF_LEZ;
+}
+
+static constexpr ConditionCode ConditionCodeForIfCcZ(Instruction::Code opcode) {
+ return kIfCcZConditionCodes[opcode - Instruction::IF_EQZ];
+}
+
+COMPILE_ASSERT(ConditionCodeForIfCcZ(Instruction::IF_EQZ) == kCondEq, check_if_eqz_ccode);
+COMPILE_ASSERT(ConditionCodeForIfCcZ(Instruction::IF_NEZ) == kCondNe, check_if_nez_ccode);
+COMPILE_ASSERT(ConditionCodeForIfCcZ(Instruction::IF_LTZ) == kCondLt, check_if_ltz_ccode);
+COMPILE_ASSERT(ConditionCodeForIfCcZ(Instruction::IF_GEZ) == kCondGe, check_if_gez_ccode);
+COMPILE_ASSERT(ConditionCodeForIfCcZ(Instruction::IF_GTZ) == kCondGt, check_if_gtz_ccode);
+COMPILE_ASSERT(ConditionCodeForIfCcZ(Instruction::IF_LEZ) == kCondLe, check_if_lez_ccode);
+
int MIRGraph::GetSSAUseCount(int s_reg) {
return raw_use_counts_.Get(s_reg);
}
@@ -313,35 +335,11 @@
}
if (mir->next != NULL) {
MIR* mir_next = mir->next;
- Instruction::Code br_opcode = mir_next->dalvikInsn.opcode;
- ConditionCode ccode = kCondNv;
- switch (br_opcode) {
- case Instruction::IF_EQZ:
- ccode = kCondEq;
- break;
- case Instruction::IF_NEZ:
- ccode = kCondNe;
- break;
- case Instruction::IF_LTZ:
- ccode = kCondLt;
- break;
- case Instruction::IF_GEZ:
- ccode = kCondGe;
- break;
- case Instruction::IF_GTZ:
- ccode = kCondGt;
- break;
- case Instruction::IF_LEZ:
- ccode = kCondLe;
- break;
- default:
- break;
- }
// Make sure result of cmp is used by next insn and nowhere else
- if ((ccode != kCondNv) &&
+ if (IsInstructionIfCcZ(mir->next->dalvikInsn.opcode) &&
(mir->ssa_rep->defs[0] == mir_next->ssa_rep->uses[0]) &&
(GetSSAUseCount(mir->ssa_rep->defs[0]) == 1)) {
- mir_next->meta.ccode = ccode;
+ mir_next->meta.ccode = ConditionCodeForIfCcZ(mir_next->dalvikInsn.opcode);
switch (opcode) {
case Instruction::CMPL_FLOAT:
mir_next->dalvikInsn.opcode =
@@ -409,8 +407,7 @@
// TUNING: expand to support IF_xx compare & branches
if (!cu_->compiler_backend->IsPortable() &&
(cu_->instruction_set == kThumb2 || cu_->instruction_set == kX86) &&
- ((mir->dalvikInsn.opcode == Instruction::IF_EQZ) ||
- (mir->dalvikInsn.opcode == Instruction::IF_NEZ))) {
+ IsInstructionIfCcZ(mir->dalvikInsn.opcode)) {
BasicBlock* ft = GetBasicBlock(bb->fall_through);
DCHECK(ft != NULL);
BasicBlock* ft_ft = GetBasicBlock(ft->fall_through);
@@ -457,12 +454,7 @@
* NOTE: not updating other dataflow info (no longer used at this point).
* If this changes, need to update i_dom, etc. here (and in CombineBlocks).
*/
- if (opcode == Instruction::IF_NEZ) {
- // Normalize.
- MIR* tmp_mir = if_true;
- if_true = if_false;
- if_false = tmp_mir;
- }
+ mir->meta.ccode = ConditionCodeForIfCcZ(mir->dalvikInsn.opcode);
mir->dalvikInsn.opcode = static_cast<Instruction::Code>(kMirOpSelect);
bool const_form = (SelectKind(if_true) == kSelectConst);
if ((SelectKind(if_true) == kSelectMove)) {