Compiler cleanup
o Added slow path for string resolution
o Removed dead throw internal and runtime error
o Restructured debug and optimization disable flags for make it easier
for command-line option support.
o Removed/converted #if 1/0 blocks
Change-Id: I65fc561a55437b3f74d0dfff5af87f938008d70e
diff --git a/src/compiler/codegen/Optimizer.h b/src/compiler/codegen/Optimizer.h
index c946e93..307d401 100644
--- a/src/compiler/codegen/Optimizer.h
+++ b/src/compiler/codegen/Optimizer.h
@@ -22,16 +22,6 @@
#define STACK_ALIGN_WORDS 4
#define STACK_ALIGNMENT (STACK_ALIGN_WORDS * 4)
-/* Supress optimization if corresponding bit set */
-enum optControlVector {
- kLoadStoreElimination = 0,
- kLoadHoisting,
- kSuppressLoads,
- kNullCheckElimination,
- kPromoteRegs,
- kTrackLiveTemps,
-};
-
/* Forward declarations */
struct CompilationUnit;
struct LIR;
diff --git a/src/compiler/codegen/arm/ArmLIR.h b/src/compiler/codegen/arm/ArmLIR.h
index 99b22e7..daa1396 100644
--- a/src/compiler/codegen/arm/ArmLIR.h
+++ b/src/compiler/codegen/arm/ArmLIR.h
@@ -357,8 +357,6 @@
kArmThrowArrayBounds,
kArmThrowVerificationError,
kArmThrowNegArraySize,
- kArmThrowInternalError,
- kArmThrowRuntimeException,
kArmThrowNoSuchMethod,
kArmThrowStackOverflow,
} ArmThrowKind;
diff --git a/src/compiler/codegen/arm/ArmRallocUtil.cc b/src/compiler/codegen/arm/ArmRallocUtil.cc
index 9a7c642..94852e3 100644
--- a/src/compiler/codegen/arm/ArmRallocUtil.cc
+++ b/src/compiler/codegen/arm/ArmRallocUtil.cc
@@ -178,11 +178,6 @@
qsort(coreRegs, numRegs, sizeof(RefCounts), sortCounts);
qsort(fpRegs, numRegs, sizeof(RefCounts), sortCounts);
- if (cUnit->printMeVerbose) {
- dumpCounts(coreRegs, numRegs, "coreRegs");
- dumpCounts(fpRegs, numRegs, "fpRegs");
- }
-
if (!(cUnit->disableOpt & (1 << kPromoteRegs))) {
// Promote fpRegs
for (int i = 0; (fpRegs[i].count > 0) && (i < numRegs); i++) {
diff --git a/src/compiler/codegen/arm/Assemble.cc b/src/compiler/codegen/arm/Assemble.cc
index c42b4b8..bbd97b4 100644
--- a/src/compiler/codegen/arm/Assemble.cc
+++ b/src/compiler/codegen/arm/Assemble.cc
@@ -20,12 +20,6 @@
#include "Codegen.h"
#include <sys/mman.h> /* for protection change */
-//#define TESTMODE
-#ifdef TESTMODE
-#include <cutils/ashmem.h> /* for oat testing */
-#include <unistd.h>
-#endif
-
#define MAX_ASSEMBLER_RETRIES 50
/*
diff --git a/src/compiler/codegen/arm/MethodCodegenDriver.cc b/src/compiler/codegen/arm/MethodCodegenDriver.cc
index 6be9f76..922e25b 100644
--- a/src/compiler/codegen/arm/MethodCodegenDriver.cc
+++ b/src/compiler/codegen/arm/MethodCodegenDriver.cc
@@ -14,7 +14,8 @@
* limitations under the License.
*/
-#define DISPLAY_MISSING_TARGETS 1
+#define DISPLAY_MISSING_TARGETS (cUnit->enableDebug & \
+ (1 << kDebugDisplayMissingTargets))
STATIC const RegLocation badLoc = {kLocDalvikFrame, 0, 0, INVALID_REG,
INVALID_REG, INVALID_SREG, 0,
@@ -922,7 +923,6 @@
return callState;
}
-#ifdef DISPLAY_MISSING_TARGETS
// Debugging routine - if null target, branch to DebugMe
STATIC void genShowTarget(CompilationUnit* cUnit)
{
@@ -933,7 +933,6 @@
target->defMask = -1;
branchOver->generic.target = (LIR*)target;
}
-#endif
STATIC void genInvokeStaticDirect(CompilationUnit* cUnit, MIR* mir,
bool direct, bool range)
@@ -959,9 +958,9 @@
while (callState >= 0) {
callState = nextCallInsn(cUnit, mir, dInsn, callState, NULL);
}
-#ifdef DISPLAY_MISSING_TARGETS
- genShowTarget(cUnit);
-#endif
+ if (DISPLAY_MISSING_TARGETS) {
+ genShowTarget(cUnit);
+ }
opReg(cUnit, kOpBlx, rLR);
oatClobberCalleeSave(cUnit);
}
@@ -992,9 +991,9 @@
while (callState >= 0) {
callState = nextInterfaceCallInsn(cUnit, mir, dInsn, callState, NULL);
}
-#ifdef DISPLAY_MISSING_TARGETS
- genShowTarget(cUnit);
-#endif
+ if (DISPLAY_MISSING_TARGETS) {
+ genShowTarget(cUnit);
+ }
opReg(cUnit, kOpBlx, rLR);
oatClobberCalleeSave(cUnit);
}
@@ -1045,9 +1044,9 @@
while (callState >= 0) {
callState = nextCallInsn(cUnit, mir, dInsn, callState, rollback);
}
-#ifdef DISPLAY_MISSING_TARGETS
- genShowTarget(cUnit);
-#endif
+ if (DISPLAY_MISSING_TARGETS) {
+ genShowTarget(cUnit);
+ }
opReg(cUnit, kOpBlx, rLR);
oatClobberCalleeSave(cUnit);
}
@@ -1085,9 +1084,9 @@
while (callState >= 0) {
callState = nextCallInsn(cUnit, mir, dInsn, callState, rollback);
}
-#ifdef DISPLAY_MISSING_TARGETS
- genShowTarget(cUnit);
-#endif
+ if (DISPLAY_MISSING_TARGETS) {
+ genShowTarget(cUnit);
+ }
opReg(cUnit, kOpBlx, rLR);
oatClobberCalleeSave(cUnit);
}
@@ -2108,16 +2107,6 @@
funcOffset =
OFFSETOF_MEMBER(Thread, pThrowNegArraySizeFromCode);
break;
- case kArmThrowInternalError:
- genRegCopy(cUnit, r0, v1);
- funcOffset =
- OFFSETOF_MEMBER(Thread, pThrowInternalErrorFromCode);
- break;
- case kArmThrowRuntimeException:
- genRegCopy(cUnit, r0, v1);
- funcOffset =
- OFFSETOF_MEMBER(Thread, pThrowRuntimeExceptionFromCode);
- break;
case kArmThrowNoSuchMethod:
genRegCopy(cUnit, r0, v1);
funcOffset =
diff --git a/src/compiler/codegen/arm/Thumb2/Gen.cc b/src/compiler/codegen/arm/Thumb2/Gen.cc
index 3f7a7ae..b63c37f 100644
--- a/src/compiler/codegen/arm/Thumb2/Gen.cc
+++ b/src/compiler/codegen/arm/Thumb2/Gen.cc
@@ -22,9 +22,16 @@
*
*/
-#define SLOW_FIELD_PATH 0
-#define SLOW_INVOKE_PATH 0
-//#define EXERCISE_SLOWEST_FIELD_PATH
+#define SLOW_FIELD_PATH (cUnit->enableDebug & (1 << kDebugSlowFieldPath))
+#define SLOW_INVOKE_PATH (cUnit->enableDebug & (1 << kDebugSlowInvokePath))
+#define SLOW_STRING_PATH (cUnit->enableDebug & (1 << kDebugSlowStringPath))
+#define SLOW_TYPE_PATH (cUnit->enableDebug & (1 << kDebugSlowTypePath))
+#define EXERCISE_SLOWEST_FIELD_PATH (cUnit->enableDebug & \
+ (1 << kDebugSlowestFieldPath))
+#define EXERCISE_SLOWEST_STRING_PATH (cUnit->enableDebug & \
+ (1 << kDebugSlowestStringPath))
+
+STATIC RegLocation getRetLoc(CompilationUnit* cUnit);
std::string fieldNameFromIndex(const Method* method, uint32_t fieldIdx)
{
@@ -427,9 +434,10 @@
* For testing, omit the test for run-time resolution. This will
* force all accesses to go through the runtime resolution path.
*/
-#ifndef EXERCISE_SLOWEST_FIELD_PATH
- ArmLIR* branchOver = genCmpImmBranch(cUnit, kArmCondNe, r0, 0);
-#endif
+ ArmLIR* branchOver = NULL;
+ if (!EXERCISE_SLOWEST_FIELD_PATH) {
+ branchOver = genCmpImmBranch(cUnit, kArmCondNe, r0, 0);
+ }
// Resolve
loadWordDisp(cUnit, rSELF,
OFFSETOF_MEMBER(Thread, pFindInstanceFieldFromCode), rLR);
@@ -437,9 +445,9 @@
callRuntimeHelper(cUnit, rLR); // resolveTypeFromCode(idx, method)
ArmLIR* target = newLIR0(cUnit, kArmPseudoTargetLabel);
target->defMask = ENCODE_ALL;
-#ifndef EXERCISE_SLOWEST_FIELD_PATH
- branchOver->generic.target = (LIR*)target;
-#endif
+ if (!EXERCISE_SLOWEST_FIELD_PATH) {
+ branchOver->generic.target = (LIR*)target;
+ }
// Free temps (except for r0)
oatFreeTemp(cUnit, r1);
oatFreeTemp(cUnit, r2);
@@ -532,7 +540,7 @@
#else
bool isVolatile = false;
#endif
- if ((fieldPtr == NULL) || isVolatile) {
+ if (SLOW_FIELD_PATH || (fieldPtr == NULL) || isVolatile) {
getFieldOffset(cUnit, mir, fieldPtr);
// Field offset in r0
rlObj = loadValue(cUnit, rlObj, kCoreReg);
@@ -570,7 +578,7 @@
#else
bool isVolatile = false;
#endif
- if ((fieldPtr == NULL) || isVolatile) {
+ if (SLOW_FIELD_PATH || (fieldPtr == NULL) || isVolatile) {
getFieldOffset(cUnit, mir, fieldPtr);
// Field offset in r0
rlObj = loadValue(cUnit, rlObj, kCoreReg);
@@ -607,7 +615,7 @@
resReg);
loadWordDisp(cUnit, resReg, Array::DataOffset().Int32Value() +
(sizeof(String*) * mir->dalvikInsn.vB), rlResult.lowReg);
- if (classPtr != NULL) {
+ if (SLOW_TYPE_PATH || (classPtr == NULL)) {
// Fast path, we're done - just store result
storeValue(cUnit, rlDest, rlResult);
} else {
@@ -640,19 +648,41 @@
STATIC void genConstString(CompilationUnit* cUnit, MIR* mir,
RegLocation rlDest, RegLocation rlSrc)
{
- /* All strings should be available at compile time */
+ /* NOTE: Most strings should be available at compile time */
const art::String* str = cUnit->method->GetDexCacheStrings()->
Get(mir->dalvikInsn.vB);
- DCHECK(str != NULL);
-
- int mReg = loadCurrMethod(cUnit);
- int resReg = oatAllocTemp(cUnit);
- RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
- loadWordDisp(cUnit, mReg, Method::DexCacheStringsOffset().Int32Value(),
- resReg);
- loadWordDisp(cUnit, resReg, Array::DataOffset().Int32Value() +
- (sizeof(String*) * mir->dalvikInsn.vB), rlResult.lowReg);
- storeValue(cUnit, rlDest, rlResult);
+ if (SLOW_STRING_PATH || (str == NULL)) {
+ oatFlushAllRegs(cUnit);
+ oatLockCallTemps(cUnit); // Using explicit registers
+ loadCurrMethodDirect(cUnit, r2);
+ loadWordDisp(cUnit, r2, Method::DexCacheStringsOffset().Int32Value(),
+ r0);
+ // Might call out to helper, which will return resolved string in r0
+ loadWordDisp(cUnit, rSELF,
+ OFFSETOF_MEMBER(Thread, pResolveStringFromCode), rLR);
+ loadWordDisp(cUnit, r0, Array::DataOffset().Int32Value() +
+ (sizeof(String*) * mir->dalvikInsn.vB), r0);
+ loadConstant(cUnit, r1, mir->dalvikInsn.vB);
+ opRegImm(cUnit, kOpCmp, r0, 0); // Is resolved?
+ genBarrier(cUnit);
+ // For testing, always force through helper
+ if (!EXERCISE_SLOWEST_STRING_PATH) {
+ genIT(cUnit, kArmCondEq, "T");
+ }
+ genRegCopy(cUnit, r0, r2); // .eq
+ opReg(cUnit, kOpBlx, rLR); // .eq, helper(Method*, string_idx)
+ genBarrier(cUnit);
+ storeValue(cUnit, rlDest, getRetLoc(cUnit));
+ } else {
+ int mReg = loadCurrMethod(cUnit);
+ int resReg = oatAllocTemp(cUnit);
+ RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
+ loadWordDisp(cUnit, mReg, Method::DexCacheStringsOffset().Int32Value(),
+ resReg);
+ loadWordDisp(cUnit, resReg, Array::DataOffset().Int32Value() +
+ (sizeof(String*) * mir->dalvikInsn.vB), rlResult.lowReg);
+ storeValue(cUnit, rlDest, rlResult);
+ }
}
/*
@@ -1778,25 +1808,8 @@
OFFSETOF_MEMBER(Thread, pCheckSuspendFromCode), rLR);
genRegCopy(cUnit, r0, rSELF);
opRegImm(cUnit, kOpCmp, rSuspendCount, 0);
- /*
- * FIXME: for efficiency we should use an if-converted suspend
- * test here. However, support for IT is a bit weak at the
- * moment, and requires knowledge of the exact number of instructions
- * to fall in the skip shadow. While the exception mechanism
- * remains in flux, use a compare and branch sequence. Once
- * things firm up, restore the conditional skip (and perhaps
- * fix the utility to handle variable-sized shadows).
- */
-#if 0
genIT(cUnit, kArmCondNe, "");
- callUnwindableHelper(cUnit, rLR); // CheckSuspendFromCode(self)
-#else
- ArmLIR* branch = opCondBranch(cUnit, kArmCondEq);
- callRuntimeHelper(cUnit, rLR); // CheckSuspendFromCode(self)
- ArmLIR* target = newLIR0(cUnit, kArmPseudoTargetLabel);
- target->defMask = ENCODE_ALL;
- branch->generic.target = (LIR*)target;
-#endif
+ opReg(cUnit, kOpBlx, rLR);
oatFreeCallTemps(cUnit);
}