ART: Extending FlagsOf
Modified FlagsOf to handle extended flags.
Change-Id: I9e47e0c42816136b2b53512c914200dd9dd11376
Signed-off-by: Jean Christophe Beyler <jean.christophe.beyler@intel.com>
diff --git a/compiler/dex/local_value_numbering.cc b/compiler/dex/local_value_numbering.cc
index 8b02269..4279955 100644
--- a/compiler/dex/local_value_numbering.cc
+++ b/compiler/dex/local_value_numbering.cc
@@ -464,7 +464,7 @@
const MIR* mir = fall_through_bb->first_mir_insn;
DCHECK(mir != nullptr);
// Only INVOKEs can leak and clobber non-aliasing references if they throw.
- if ((Instruction::FlagsOf(mir->dalvikInsn.opcode) & Instruction::kInvoke) != 0) {
+ if ((mir->dalvikInsn.FlagsOf() & Instruction::kInvoke) != 0) {
for (uint16_t i = 0u; i != mir->ssa_rep->num_uses; ++i) {
uint16_t value_name = lvn->GetOperandValue(mir->ssa_rep->uses[i]);
non_aliasing_refs_.erase(value_name);
diff --git a/compiler/dex/mir_dataflow.cc b/compiler/dex/mir_dataflow.cc
index 7d356a4..55ccf64 100644
--- a/compiler/dex/mir_dataflow.cc
+++ b/compiler/dex/mir_dataflow.cc
@@ -1085,7 +1085,7 @@
// If not a pseudo-op, note non-leaf or can throw
if (!MIR::DecodedInstruction::IsPseudoMirOp(mir->dalvikInsn.opcode)) {
- int flags = Instruction::FlagsOf(mir->dalvikInsn.opcode);
+ int flags = mir->dalvikInsn.FlagsOf();
if ((flags & Instruction::kInvoke) != 0 && (mir->optimization_flags & MIR_INLINED) == 0) {
attributes_ &= ~METHOD_IS_LEAF;
diff --git a/compiler/dex/mir_graph.cc b/compiler/dex/mir_graph.cc
index 574b6ea..776f304 100644
--- a/compiler/dex/mir_graph.cc
+++ b/compiler/dex/mir_graph.cc
@@ -739,7 +739,7 @@
opcode_count_[static_cast<int>(opcode)]++;
}
- int flags = Instruction::FlagsOf(insn->dalvikInsn.opcode);
+ int flags = insn->dalvikInsn.FlagsOf();
int verify_flags = Instruction::VerifyFlagsOf(insn->dalvikInsn.opcode);
uint64_t df_flags = GetDataFlowAttributes(insn);
@@ -1251,7 +1251,7 @@
str.append(extended_mir_op_names_[opcode - kMirOpFirst]);
} else {
dalvik_format = Instruction::FormatOf(insn.opcode);
- flags = Instruction::FlagsOf(insn.opcode);
+ flags = insn.FlagsOf();
str.append(Instruction::Name(insn.opcode));
}
@@ -2191,4 +2191,80 @@
num_blocks_ = block_list_.Size();
}
+int MIR::DecodedInstruction::FlagsOf() const {
+ // Calculate new index.
+ int idx = static_cast<int>(opcode) - kNumPackedOpcodes;
+
+ // Check if it is an extended or not.
+ if (idx < 0) {
+ return Instruction::FlagsOf(opcode);
+ }
+
+ // For extended, we use a switch.
+ switch (static_cast<int>(opcode)) {
+ case kMirOpPhi:
+ return Instruction::kContinue;
+ case kMirOpCopy:
+ return Instruction::kContinue;
+ case kMirOpFusedCmplFloat:
+ return Instruction::kContinue | Instruction::kBranch;
+ case kMirOpFusedCmpgFloat:
+ return Instruction::kContinue | Instruction::kBranch;
+ case kMirOpFusedCmplDouble:
+ return Instruction::kContinue | Instruction::kBranch;
+ case kMirOpFusedCmpgDouble:
+ return Instruction::kContinue | Instruction::kBranch;
+ case kMirOpFusedCmpLong:
+ return Instruction::kContinue | Instruction::kBranch;
+ case kMirOpNop:
+ return Instruction::kContinue;
+ case kMirOpNullCheck:
+ return Instruction::kContinue | Instruction::kThrow;
+ case kMirOpRangeCheck:
+ return Instruction::kContinue | Instruction::kThrow;
+ case kMirOpDivZeroCheck:
+ return Instruction::kContinue | Instruction::kThrow;
+ case kMirOpCheck:
+ return 0;
+ case kMirOpCheckPart2:
+ return 0;
+ case kMirOpSelect:
+ return Instruction::kContinue;
+ case kMirOpConstVector:
+ return Instruction::kContinue;
+ case kMirOpMoveVector:
+ return Instruction::kContinue;
+ case kMirOpPackedMultiply:
+ return Instruction::kContinue;
+ case kMirOpPackedAddition:
+ return Instruction::kContinue;
+ case kMirOpPackedSubtract:
+ return Instruction::kContinue;
+ case kMirOpPackedShiftLeft:
+ return Instruction::kContinue;
+ case kMirOpPackedSignedShiftRight:
+ return Instruction::kContinue;
+ case kMirOpPackedUnsignedShiftRight:
+ return Instruction::kContinue;
+ case kMirOpPackedAnd:
+ return Instruction::kContinue;
+ case kMirOpPackedOr:
+ return Instruction::kContinue;
+ case kMirOpPackedXor:
+ return Instruction::kContinue;
+ case kMirOpPackedAddReduce:
+ return Instruction::kContinue;
+ case kMirOpPackedReduce:
+ return Instruction::kContinue;
+ case kMirOpPackedSet:
+ return Instruction::kContinue;
+ case kMirOpReserveVectorRegisters:
+ return Instruction::kContinue;
+ case kMirOpReturnVectorRegisters:
+ return Instruction::kContinue;
+ default:
+ LOG(WARNING) << "ExtendedFlagsOf: Unhandled case: " << static_cast<int> (opcode);
+ return 0;
+ }
+}
} // namespace art
diff --git a/compiler/dex/mir_graph.h b/compiler/dex/mir_graph.h
index 491d72e..08b3ca4 100644
--- a/compiler/dex/mir_graph.h
+++ b/compiler/dex/mir_graph.h
@@ -297,37 +297,37 @@
}
bool IsInvoke() const {
- return !IsPseudoMirOp(opcode) && ((Instruction::FlagsOf(opcode) & Instruction::kInvoke) == Instruction::kInvoke);
+ return ((FlagsOf() & Instruction::kInvoke) == Instruction::kInvoke);
}
bool IsStore() const {
- return !IsPseudoMirOp(opcode) && ((Instruction::FlagsOf(opcode) & Instruction::kStore) == Instruction::kStore);
+ return ((FlagsOf() & Instruction::kStore) == Instruction::kStore);
}
bool IsLoad() const {
- return !IsPseudoMirOp(opcode) && ((Instruction::FlagsOf(opcode) & Instruction::kLoad) == Instruction::kLoad);
+ return ((FlagsOf() & Instruction::kLoad) == Instruction::kLoad);
}
bool IsConditionalBranch() const {
- return !IsPseudoMirOp(opcode) && (Instruction::FlagsOf(opcode) == (Instruction::kContinue | Instruction::kBranch));
+ return (FlagsOf() == (Instruction::kContinue | Instruction::kBranch));
}
/**
* @brief Is the register C component of the decoded instruction a constant?
*/
bool IsCFieldOrConstant() const {
- return !IsPseudoMirOp(opcode) && ((Instruction::FlagsOf(opcode) & Instruction::kRegCFieldOrConstant) == Instruction::kRegCFieldOrConstant);
+ return ((FlagsOf() & Instruction::kRegCFieldOrConstant) == Instruction::kRegCFieldOrConstant);
}
/**
* @brief Is the register C component of the decoded instruction a constant?
*/
bool IsBFieldOrConstant() const {
- return !IsPseudoMirOp(opcode) && ((Instruction::FlagsOf(opcode) & Instruction::kRegBFieldOrConstant) == Instruction::kRegBFieldOrConstant);
+ return ((FlagsOf() & Instruction::kRegBFieldOrConstant) == Instruction::kRegBFieldOrConstant);
}
bool IsCast() const {
- return !IsPseudoMirOp(opcode) && ((Instruction::FlagsOf(opcode) & Instruction::kCast) == Instruction::kCast);
+ return ((FlagsOf() & Instruction::kCast) == Instruction::kCast);
}
/**
@@ -337,12 +337,14 @@
* when crossing such an instruction.
*/
bool Clobbers() const {
- return !IsPseudoMirOp(opcode) && ((Instruction::FlagsOf(opcode) & Instruction::kClobber) == Instruction::kClobber);
+ return ((FlagsOf() & Instruction::kClobber) == Instruction::kClobber);
}
bool IsLinear() const {
- return !IsPseudoMirOp(opcode) && (Instruction::FlagsOf(opcode) & (Instruction::kAdd | Instruction::kSubtract)) != 0;
+ return (FlagsOf() & (Instruction::kAdd | Instruction::kSubtract)) != 0;
}
+
+ int FlagsOf() const;
} dalvikInsn;
NarrowDexOffset offset; // Offset of the instruction in code units.
diff --git a/compiler/dex/mir_optimization.cc b/compiler/dex/mir_optimization.cc
index 6658848..4e7358f 100644
--- a/compiler/dex/mir_optimization.cc
+++ b/compiler/dex/mir_optimization.cc
@@ -1254,7 +1254,7 @@
if (MIR::DecodedInstruction::IsPseudoMirOp(mir->dalvikInsn.opcode)) {
continue;
}
- if (!(Instruction::FlagsOf(mir->dalvikInsn.opcode) & Instruction::kInvoke)) {
+ if (!(mir->dalvikInsn.FlagsOf() & Instruction::kInvoke)) {
continue;
}
const MirMethodLoweringInfo& method_info = GetMethodLoweringInfo(mir);
diff --git a/compiler/dex/vreg_analysis.cc b/compiler/dex/vreg_analysis.cc
index 4a3e071..69535a4 100644
--- a/compiler/dex/vreg_analysis.cc
+++ b/compiler/dex/vreg_analysis.cc
@@ -252,7 +252,7 @@
// Special-case handling for format 35c/3rc invokes
Instruction::Code opcode = mir->dalvikInsn.opcode;
int flags = MIR::DecodedInstruction::IsPseudoMirOp(opcode) ?
- 0 : Instruction::FlagsOf(mir->dalvikInsn.opcode);
+ 0 : mir->dalvikInsn.FlagsOf();
if ((flags & Instruction::kInvoke) &&
(attrs & (DF_FORMAT_35C | DF_FORMAT_3RC))) {
DCHECK_EQ(next, 0);