Quick assembler fix
This CL re-instates the select pattern optimization disabled by
CL 374310, and fixes the underlying problem: improper handling of
the kPseudoBarrier LIR opcode. The bug was introduced in the
recent assembler restructuring. In short, LIR pseudo opcodes (which
have values < 0), should always have size 0 - and thus cause no
bits to be emitted during assembly. In this case, bad logic caused
us to set the size of a kPseudoBarrier opcode via lookup through the
EncodingMap.
Because all pseudo ops are < 0, this meant we did an array underflow
load, picking up whatever garbage was located before the EncodingMap.
This explains why this error showed up recently - we'd previuosly just
gotten a lucky layout.
This CL corrects the faulty logic, and adds DCHECKs to uses of
the EncodingMap to ensure that we don't try to access w/ a
pseudo op. Additionally, the existing is_pseudo_op() macro is
replaced with IsPseudoLirOp(), named similar to the existing
IsPseudoMirOp().
Change-Id: I46761a0275a923d85b545664cadf052e1ab120dc
diff --git a/compiler/dex/quick/mir_to_lir-inl.h b/compiler/dex/quick/mir_to_lir-inl.h
index 314c57e..f293700 100644
--- a/compiler/dex/quick/mir_to_lir-inl.h
+++ b/compiler/dex/quick/mir_to_lir-inl.h
@@ -69,7 +69,7 @@
* operands.
*/
inline LIR* Mir2Lir::NewLIR0(int opcode) {
- DCHECK(is_pseudo_opcode(opcode) || (GetTargetInstFlags(opcode) & NO_OPERAND))
+ DCHECK(IsPseudoLirOp(opcode) || (GetTargetInstFlags(opcode) & NO_OPERAND))
<< GetTargetInstName(opcode) << " " << opcode << " "
<< PrettyMethod(cu_->method_idx, *cu_->dex_file) << " "
<< current_dalvik_offset_;
@@ -79,7 +79,7 @@
}
inline LIR* Mir2Lir::NewLIR1(int opcode, int dest) {
- DCHECK(is_pseudo_opcode(opcode) || (GetTargetInstFlags(opcode) & IS_UNARY_OP))
+ DCHECK(IsPseudoLirOp(opcode) || (GetTargetInstFlags(opcode) & IS_UNARY_OP))
<< GetTargetInstName(opcode) << " " << opcode << " "
<< PrettyMethod(cu_->method_idx, *cu_->dex_file) << " "
<< current_dalvik_offset_;
@@ -89,7 +89,7 @@
}
inline LIR* Mir2Lir::NewLIR2(int opcode, int dest, int src1) {
- DCHECK(is_pseudo_opcode(opcode) || (GetTargetInstFlags(opcode) & IS_BINARY_OP))
+ DCHECK(IsPseudoLirOp(opcode) || (GetTargetInstFlags(opcode) & IS_BINARY_OP))
<< GetTargetInstName(opcode) << " " << opcode << " "
<< PrettyMethod(cu_->method_idx, *cu_->dex_file) << " "
<< current_dalvik_offset_;
@@ -99,7 +99,7 @@
}
inline LIR* Mir2Lir::NewLIR3(int opcode, int dest, int src1, int src2) {
- DCHECK(is_pseudo_opcode(opcode) || (GetTargetInstFlags(opcode) & IS_TERTIARY_OP))
+ DCHECK(IsPseudoLirOp(opcode) || (GetTargetInstFlags(opcode) & IS_TERTIARY_OP))
<< GetTargetInstName(opcode) << " " << opcode << " "
<< PrettyMethod(cu_->method_idx, *cu_->dex_file) << " "
<< current_dalvik_offset_;
@@ -109,7 +109,7 @@
}
inline LIR* Mir2Lir::NewLIR4(int opcode, int dest, int src1, int src2, int info) {
- DCHECK(is_pseudo_opcode(opcode) || (GetTargetInstFlags(opcode) & IS_QUAD_OP))
+ DCHECK(IsPseudoLirOp(opcode) || (GetTargetInstFlags(opcode) & IS_QUAD_OP))
<< GetTargetInstName(opcode) << " " << opcode << " "
<< PrettyMethod(cu_->method_idx, *cu_->dex_file) << " "
<< current_dalvik_offset_;
@@ -120,7 +120,7 @@
inline LIR* Mir2Lir::NewLIR5(int opcode, int dest, int src1, int src2, int info1,
int info2) {
- DCHECK(is_pseudo_opcode(opcode) || (GetTargetInstFlags(opcode) & IS_QUIN_OP))
+ DCHECK(IsPseudoLirOp(opcode) || (GetTargetInstFlags(opcode) & IS_QUIN_OP))
<< GetTargetInstName(opcode) << " " << opcode << " "
<< PrettyMethod(cu_->method_idx, *cu_->dex_file) << " "
<< current_dalvik_offset_;
@@ -142,8 +142,10 @@
inline void Mir2Lir::SetupResourceMasks(LIR* lir) {
int opcode = lir->opcode;
- if ((opcode < 0) && (opcode != kPseudoBarrier)) {
- lir->flags.fixup = kFixupLabel;
+ if (IsPseudoLirOp(opcode)) {
+ if (opcode != kPseudoBarrier) {
+ lir->flags.fixup = kFixupLabel;
+ }
return;
}