Add OpEndIT() for marking the end of OpIT blocks
In ARM we need to prevent code motion to the inside of an
IT block. This was done using a GenBarrier() to mark the end, but
it wasn't obvious that this is what was happening. This CL adds
an explicit OpEndIT() that takes the LIR of the OpIT for future
checks.
Bug: 13751744
Change-Id: If41d2adea1f43f11ebb3b72906bd308252ce3d01
diff --git a/compiler/dex/quick/arm/call_arm.cc b/compiler/dex/quick/arm/call_arm.cc
index 8c9f8ea..d0d0e6b 100644
--- a/compiler/dex/quick/arm/call_arm.cc
+++ b/compiler/dex/quick/arm/call_arm.cc
@@ -81,8 +81,9 @@
NewLIR2(kThumb2LdmiaWB, r_base.GetReg(), (1 << r_key.GetReg()) | (1 << r_disp.GetReg()));
OpRegReg(kOpCmp, r_key, rl_src.reg);
// Go if match. NOTE: No instruction set switch here - must stay Thumb2
- OpIT(kCondEq, "");
+ LIR* it = OpIT(kCondEq, "");
LIR* switch_branch = NewLIR1(kThumb2AddPCR, r_disp.GetReg());
+ OpEndIT(it);
tab_rec->anchor = switch_branch;
// Needs to use setflags encoding here
OpRegRegImm(kOpSub, r_idx, r_idx, 1); // For value == 1, this should set flags.
@@ -222,14 +223,16 @@
NewLIR3(kThumb2Ldrex, r1, r0, mirror::Object::MonitorOffset().Int32Value() >> 2);
MarkPossibleNullPointerException(opt_flags);
OpRegImm(kOpCmp, rs_r1, 0);
- OpIT(kCondEq, "");
+ LIR* it = OpIT(kCondEq, "");
NewLIR4(kThumb2Strex/*eq*/, r1, r2, r0, mirror::Object::MonitorOffset().Int32Value() >> 2);
+ OpEndIT(it);
OpRegImm(kOpCmp, rs_r1, 0);
- OpIT(kCondNe, "T");
+ it = OpIT(kCondNe, "T");
// Go expensive route - artLockObjectFromCode(self, obj);
LoadWordDisp/*ne*/(rs_rARM_SELF, QUICK_ENTRYPOINT_OFFSET(4, pLockObject).Int32Value(), rs_rARM_LR);
ClobberCallerSave();
LIR* call_inst = OpReg(kOpBlx/*ne*/, rs_rARM_LR);
+ OpEndIT(it);
MarkSafepointPC(call_inst);
GenMemBarrier(kLoadLoad);
}
@@ -287,13 +290,14 @@
LoadConstantNoClobber(rs_r3, 0);
// Is lock unheld on lock or held by us (==thread_id) on unlock?
OpRegReg(kOpCmp, rs_r1, rs_r2);
- OpIT(kCondEq, "EE");
+ LIR* it = OpIT(kCondEq, "EE");
StoreWordDisp/*eq*/(rs_r0, mirror::Object::MonitorOffset().Int32Value(), rs_r3);
// Go expensive route - UnlockObjectFromCode(obj);
LoadWordDisp/*ne*/(rs_rARM_SELF, QUICK_ENTRYPOINT_OFFSET(4, pUnlockObject).Int32Value(),
rs_rARM_LR);
ClobberCallerSave();
LIR* call_inst = OpReg(kOpBlx/*ne*/, rs_rARM_LR);
+ OpEndIT(it);
MarkSafepointPC(call_inst);
GenMemBarrier(kStoreLoad);
}