diff options
55 files changed, 779 insertions, 911 deletions
diff --git a/build/Android.libart-compiler-llvm.mk b/build/Android.libart-compiler-llvm.mk index 4f89883841..a36962dbc1 100644 --- a/build/Android.libart-compiler-llvm.mk +++ b/build/Android.libart-compiler-llvm.mk @@ -42,7 +42,7 @@ ifeq ($(ART_USE_PORTABLE_COMPILER),true) src/compiler/intermediate_rep.cc \ src/compiler/ralloc.cc \ src/compiler/ssa_transformation.cc \ - src/compiler/utility.cc \ + src/compiler/compiler_utility.cc \ src/compiler/codegen/ralloc_util.cc \ src/compiler/codegen/arm/target_arm.cc \ src/compiler/codegen/arm/assemble_arm.cc \ diff --git a/build/Android.libart-compiler.mk b/build/Android.libart-compiler.mk index fa51a9920e..f94b8b699e 100644 --- a/build/Android.libart-compiler.mk +++ b/build/Android.libart-compiler.mk @@ -20,7 +20,7 @@ LIBART_COMPILER_COMMON_SRC_FILES += \ src/compiler/intermediate_rep.cc \ src/compiler/ralloc.cc \ src/compiler/ssa_transformation.cc \ - src/compiler/utility.cc \ + src/compiler/compiler_utility.cc \ src/compiler/codegen/ralloc_util.cc \ src/oat/jni/calling_convention.cc \ src/oat/jni/jni_compiler.cc \ diff --git a/src/compiler/codegen/arm/arm_lir.h b/src/compiler/codegen/arm/arm_lir.h index a068502972..503fbda48e 100644 --- a/src/compiler/codegen/arm/arm_lir.h +++ b/src/compiler/codegen/arm/arm_lir.h @@ -17,7 +17,6 @@ #ifndef ART_SRC_COMPILER_CODEGEN_ARM_ARMLIR_H_ #define ART_SRC_COMPILER_CODEGEN_ARM_ARMLIR_H_ -#include "../../dalvik.h" #include "../../compiler_internals.h" namespace art { @@ -135,11 +134,11 @@ enum ArmResourceEncodingPos { kArmRegEnd = 48, }; -#define ENCODE_ARM_REG_LIST(N) ((u8) N) +#define ENCODE_ARM_REG_LIST(N) ((uint64_t) N) #define ENCODE_ARM_REG_SP (1ULL << kArmRegSP) #define ENCODE_ARM_REG_LR (1ULL << kArmRegLR) #define ENCODE_ARM_REG_PC (1ULL << kArmRegPC) -#define ENCODE_ARM_REG_FPCS_LIST(N) ((u8)N << kArmFPReg16) +#define ENCODE_ARM_REG_FPCS_LIST(N) ((uint64_t)N << kArmFPReg16) enum ArmNativeRegisterPool { r0 = 0, @@ -592,7 +591,7 @@ enum ArmEncodingKind { /* Struct used to define the snippet positions for each Thumb opcode */ struct ArmEncodingMap { - u4 skeleton; + uint32_t skeleton; struct { ArmEncodingKind kind; int end; /* end for kFmtBitBlt, 1-bit slice end for FP regs */ @@ -605,11 +604,6 @@ struct ArmEncodingMap { int size; /* Size in bytes */ }; -/* Keys for target-specific scheduling and other optimization hints */ -enum ArmTargetOptHints { - kMaxHoistDistance, -}; - extern const ArmEncodingMap EncodingMap[kArmLast]; } // namespace art diff --git a/src/compiler/codegen/arm/assemble_arm.cc b/src/compiler/codegen/arm/assemble_arm.cc index e1b867254a..6370f6c215 100644 --- a/src/compiler/codegen/arm/assemble_arm.cc +++ b/src/compiler/codegen/arm/assemble_arm.cc @@ -14,10 +14,8 @@ * limitations under the License. */ -#include "../../dalvik.h" -#include "../../compiler_internals.h" #include "arm_lir.h" -#include "codegen.h" +#include "../codegen_util.h" namespace art { @@ -1252,11 +1250,11 @@ AssemblerStatus oatAssembleInstructions(CompilationUnit* cUnit, continue; } const ArmEncodingMap *encoder = &EncodingMap[lir->opcode]; - u4 bits = encoder->skeleton; + uint32_t bits = encoder->skeleton; int i; for (i = 0; i < 4; i++) { - u4 operand; - u4 value; + uint32_t operand; + uint32_t value; operand = lir->operands[i]; switch (encoder->fieldLoc[i].kind) { case kFmtUnused: @@ -1337,13 +1335,13 @@ AssemblerStatus oatAssembleInstructions(CompilationUnit* cUnit, bits |= value; break; case kFmtOff24: { - u4 signbit = (operand >> 31) & 0x1; - u4 i1 = (operand >> 22) & 0x1; - u4 i2 = (operand >> 21) & 0x1; - u4 imm10 = (operand >> 11) & 0x03ff; - u4 imm11 = operand & 0x07ff; - u4 j1 = (i1 ^ signbit) ? 0 : 1; - u4 j2 = (i2 ^ signbit) ? 0 : 1; + uint32_t signbit = (operand >> 31) & 0x1; + uint32_t i1 = (operand >> 22) & 0x1; + uint32_t i2 = (operand >> 21) & 0x1; + uint32_t imm10 = (operand >> 11) & 0x03ff; + uint32_t imm11 = operand & 0x07ff; + uint32_t j1 = (i1 ^ signbit) ? 0 : 1; + uint32_t j2 = (i2 ^ signbit) ? 0 : 1; value = (signbit << 26) | (j1 << 13) | (j2 << 11) | (imm10 << 16) | imm11; bits |= value; diff --git a/src/compiler/codegen/arm/backend_arm.cc b/src/compiler/codegen/arm/backend_arm.cc index d8f29968d0..47d19674cc 100644 --- a/src/compiler/codegen/arm/backend_arm.cc +++ b/src/compiler/codegen/arm/backend_arm.cc @@ -16,17 +16,14 @@ #define _CODEGEN_C #define _ARMV7_A -#include "../../dalvik.h" -#include "../../compiler_internals.h" #include "arm_lir.h" -#include "../ralloc.h" -#include "codegen.h" +#include "../ralloc_util.h" /* Common codegen utility code */ #include "../codegen_util.cc" #include "utility_arm.cc" -#include "../codegen_factory.cc" +#include "../gen_loadstore.cc" #include "../gen_common.cc" #include "../gen_invoke.cc" #include "call_arm.cc" diff --git a/src/compiler/codegen/arm/call_arm.cc b/src/compiler/codegen/arm/call_arm.cc index 3fd5b15b8d..92b067c51a 100644 --- a/src/compiler/codegen/arm/call_arm.cc +++ b/src/compiler/codegen/arm/call_arm.cc @@ -324,7 +324,7 @@ void genSpecialCase(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir, void genSparseSwitch(CompilationUnit* cUnit, uint32_t tableOffset, RegLocation rlSrc) { - const u2* table = cUnit->insns + cUnit->currentDalvikOffset + tableOffset; + const uint16_t* table = cUnit->insns + cUnit->currentDalvikOffset + tableOffset; if (cUnit->printMe) { dumpSparseSwitchTable(table); } @@ -372,7 +372,7 @@ void genSparseSwitch(CompilationUnit* cUnit, uint32_t tableOffset, void genPackedSwitch(CompilationUnit* cUnit, uint32_t tableOffset, RegLocation rlSrc) { - const u2* table = cUnit->insns + cUnit->currentDalvikOffset + tableOffset; + const uint16_t* table = cUnit->insns + cUnit->currentDalvikOffset + tableOffset; if (cUnit->printMe) { dumpPackedSwitchTable(table); } @@ -428,14 +428,14 @@ void genPackedSwitch(CompilationUnit* cUnit, uint32_t tableOffset, */ void genFillArrayData(CompilationUnit* cUnit, uint32_t tableOffset, RegLocation rlSrc) { - const u2* table = cUnit->insns + cUnit->currentDalvikOffset + tableOffset; + const uint16_t* table = cUnit->insns + cUnit->currentDalvikOffset + tableOffset; // Add the table to the list - we'll process it later FillArrayData *tabRec = (FillArrayData *) oatNew(cUnit, sizeof(FillArrayData), true, kAllocData); tabRec->table = table; tabRec->vaddr = cUnit->currentDalvikOffset; - u2 width = tabRec->table[1]; - u4 size = tabRec->table[2] | (((u4)tabRec->table[3]) << 16); + uint16_t width = tabRec->table[1]; + uint32_t size = tabRec->table[2] | ((static_cast<uint32_t>(tabRec->table[3])) << 16); tabRec->size = (size * width) + 8; oatInsertGrowableList(cUnit, &cUnit->fillArrayData, (intptr_t)tabRec); @@ -456,10 +456,10 @@ void genFillArrayData(CompilationUnit* cUnit, uint32_t tableOffset, RegLocation * Handle simple case (thin lock) inline. If it's complicated, bail * out to the heavyweight lock/unlock routines. We'll use dedicated * registers here in order to be in the right position in case we - * to bail to dvm[Lock/Unlock]Object(self, object) + * to bail to oat[Lock/Unlock]Object(self, object) * - * r0 -> self pointer [arg0 for dvm[Lock/Unlock]Object - * r1 -> object [arg1 for dvm[Lock/Unlock]Object + * r0 -> self pointer [arg0 for oat[Lock/Unlock]Object + * r1 -> object [arg1 for oat[Lock/Unlock]Object * r2 -> intial contents of object->lock, later result of strex * r3 -> self->threadId * r12 -> allow to be used by utilities as general temp diff --git a/src/compiler/codegen/arm/codegen.h b/src/compiler/codegen/arm/codegen.h deleted file mode 100644 index 47f45c6c20..0000000000 --- a/src/compiler/codegen/arm/codegen.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* This file contains register alloction support. */ - -#include "../../compiler_ir.h" - -namespace art { - -#if defined(_CODEGEN_C) -LIR *opRegImm(CompilationUnit* cUnit, OpKind op, int rDestSrc1, int value); -LIR *opRegReg(CompilationUnit* cUnit, OpKind op, int rDestSrc1, int rSrc2); -LIR* opCmpImmBranch(CompilationUnit* cUnit, ConditionCode cond, int reg, - int checkValue, LIR* target); -bool genNegLong(CompilationUnit* cUnit, RegLocation rlDest, - RegLocation rlSrc); - -/* Forward declaraton the portable versions due to circular dependency */ -bool genArithOpFloatPortable(CompilationUnit* cUnit, Instruction::Code opcode, - RegLocation rlDest, RegLocation rlSrc1, - RegLocation rlSrc2); - -bool genArithOpDoublePortable(CompilationUnit* cUnit, Instruction::Code opcode, - RegLocation rlDest, RegLocation rlSrc1, - RegLocation rlSrc2); - -bool genConversionPortable(CompilationUnit* cUnit, Instruction::Code opcode, - RegLocation rlDest, RegLocation rlSrc); - -ArmConditionCode oatArmConditionEncoding(ConditionCode code); - -int loadHelper(CompilationUnit* cUnit, int offset); -LIR* loadConstant(CompilationUnit* cUnit, int reg, int immVal); -void opRegCopyWide(CompilationUnit* cUnit, int destLo, int destHi, - int srcLo, int srcHi); -LIR* opRegCopy(CompilationUnit* cUnit, int rDest, int rSrc); -void freeRegLocTemps(CompilationUnit* cUnit, RegLocation rlKeep, - RegLocation rlFree); - - -/* - * Return most flexible allowed register class based on size. - * Bug: 2813841 - * Must use a core register for data types narrower than word (due - * to possible unaligned load/store. - */ -inline RegisterClass oatRegClassBySize(OpSize size) -{ - return (size == kUnsignedHalf || - size == kSignedHalf || - size == kUnsignedByte || - size == kSignedByte ) ? kCoreReg : kAnyReg; -} - -/* - * Construct an s4 from two consecutive half-words of switch data. - * This needs to check endianness because the DEX optimizer only swaps - * half-words in instruction stream. - * - * "switchData" must be 32-bit aligned. - */ -#if __BYTE_ORDER == __LITTLE_ENDIAN -inline s4 s4FromSwitchData(const void* switchData) { - return *(s4*) switchData; -} -#else -inline s4 s4FromSwitchData(const void* switchData) { - u2* data = switchData; - return data[0] | (((s4) data[1]) << 16); -} -#endif - -#endif - -extern void oatSetupResourceMasks(CompilationUnit* cUnit, LIR* lir); - -extern LIR* oatRegCopyNoInsert(CompilationUnit* cUnit, int rDest, int rSrc); - -bool genAddLong(CompilationUnit* cUnit, RegLocation rlDest, - RegLocation rlSrc1, RegLocation rlSrc2); -bool genSubLong(CompilationUnit* cUnit, RegLocation rlDest, - RegLocation rlSrc1, RegLocation rlSrc2); -bool genAndLong(CompilationUnit* cUnit, RegLocation rlDest, - RegLocation rlSrc1, RegLocation rlSrc2); -bool genOrLong(CompilationUnit* cUnit, RegLocation rlDest, - RegLocation rlSrc1, RegLocation rlSrc2); -bool genXorLong(CompilationUnit* cUnit, RegLocation rlDest, - RegLocation rlSrc1, RegLocation rlSrc2); - -} // namespace art diff --git a/src/compiler/codegen/arm/target_arm.cc b/src/compiler/codegen/arm/target_arm.cc index fc643ea8cc..5838ca799d 100644 --- a/src/compiler/codegen/arm/target_arm.cc +++ b/src/compiler/codegen/arm/target_arm.cc @@ -16,7 +16,8 @@ #include "../../compiler_internals.h" #include "arm_lir.h" -#include "../ralloc.h" +#include "../ralloc_util.h" +#include "../codegen_util.h" #include <string> @@ -122,9 +123,9 @@ bool sameRegType(int reg1, int reg2) /* * Decode the register id. */ -u8 getRegMaskCommon(CompilationUnit* cUnit, int reg) +uint64_t getRegMaskCommon(CompilationUnit* cUnit, int reg) { - u8 seed; + uint64_t seed; int shift; int regId; @@ -206,7 +207,7 @@ void setupTargetResourceMasks(CompilationUnit* cUnit, LIR* lir) } /* Fixup for kThumbPush/lr and kThumbPop/pc */ if (opcode == kThumbPush || opcode == kThumbPop) { - u8 r8Mask = oatGetRegMaskCommon(cUnit, r8); + uint64_t r8Mask = oatGetRegMaskCommon(cUnit, r8); if ((opcode == kThumbPush) && (lir->useMask & r8Mask)) { lir->useMask &= ~r8Mask; lir->useMask |= ENCODE_ARM_REG_LR; @@ -310,7 +311,7 @@ char* decodeFPCSRegList(int count, int base, char* buf) int expandImmediate(int value) { int mode = (value & 0xf00) >> 8; - u4 bits = value & 0xff; + uint32_t bits = value & 0xff; switch (mode) { case 0: return bits; @@ -472,7 +473,7 @@ std::string buildInsnString(const char* fmt, LIR* lir, unsigned char* baseAddr) return buf; } -void oatDumpResourceMask(LIR* lir, u8 mask, const char* prefix) +void oatDumpResourceMask(LIR* lir, uint64_t mask, const char* prefix) { char buf[256]; buf[0] = 0; @@ -591,21 +592,6 @@ bool oatArchVariantInit(void) return true; } -int oatTargetOptHint(int key) -{ - int res = 0; - switch (key) { - case kMaxHoistDistance: - res = 7; - break; - default: - LOG(FATAL) << "Unknown target optimization hint key: " << key; - } - return res; -} - -/* This file contains codegen for the Thumb ISA. */ - /* * Alloc a pair of core registers, or a double. Low reg in low byte, * high reg in next byte. @@ -755,8 +741,7 @@ void oatFlushRegWide(CompilationUnit* cUnit, int reg1, int reg2) SRegToVReg(cUnit, info1->sReg)) info1 = info2; int vReg = SRegToVReg(cUnit, info1->sReg); - oatFlushRegWideImpl(cUnit, rARM_SP, oatVRegOffset(cUnit, vReg), - info1->reg, info1->partner); + storeBaseDispWide(cUnit, rARM_SP, oatVRegOffset(cUnit, vReg), info1->reg, info1->partner); } } @@ -766,7 +751,7 @@ void oatFlushReg(CompilationUnit* cUnit, int reg) if (info->live && info->dirty) { info->dirty = false; int vReg = SRegToVReg(cUnit, info->sReg); - oatFlushRegImpl(cUnit, rARM_SP, oatVRegOffset(cUnit, vReg), reg, kWord); + storeBaseDisp(cUnit, rARM_SP, oatVRegOffset(cUnit, vReg), reg, kWord); } } diff --git a/src/compiler/codegen/arm/utility_arm.cc b/src/compiler/codegen/arm/utility_arm.cc index e83093b198..90698260a8 100644 --- a/src/compiler/codegen/arm/utility_arm.cc +++ b/src/compiler/codegen/arm/utility_arm.cc @@ -59,9 +59,9 @@ LIR* loadFPConstantValue(CompilationUnit* cUnit, int rDest, int value) return loadPcRel; } -int leadingZeros(u4 val) +int leadingZeros(uint32_t val) { - u4 alt; + uint32_t alt; int n; int count; @@ -82,11 +82,11 @@ int leadingZeros(u4 val) * Determine whether value can be encoded as a Thumb2 modified * immediate. If not, return -1. If so, return i:imm3:a:bcdefgh form. */ -int modifiedImmediate(u4 value) +int modifiedImmediate(uint32_t value) { int zLeading; int zTrailing; - u4 b0 = value & 0xff; + uint32_t b0 = value & 0xff; /* Note: case of value==0 must use 0:000:0:0000000 encoding */ if (value <= 0xFF) diff --git a/src/compiler/codegen/codegen_util.cc b/src/compiler/codegen/codegen_util.cc index b0a1e4437c..6ce48abb5c 100644 --- a/src/compiler/codegen/codegen_util.cc +++ b/src/compiler/codegen/codegen_util.cc @@ -17,13 +17,14 @@ #include "gc_map.h" #include "verifier/dex_gc_map.h" #include "verifier/method_verifier.h" +#include "codegen_util.h" namespace art { void setMemRefType(LIR* lir, bool isLoad, int memType) { - u8 *maskPtr; - u8 mask = ENCODE_MEM;; + uint64_t *maskPtr; + uint64_t mask = ENCODE_MEM;; DCHECK(EncodingMap[lir->opcode].flags & (IS_LOAD | IS_STORE)); if (isLoad) { maskPtr = &lir->useMask; @@ -68,7 +69,7 @@ void annotateDalvikRegAccess(LIR* lir, int regId, bool isLoad, bool is64bit) lir->aliasInfo = ENCODE_ALIAS_INFO(regId, is64bit); } -u8 oatGetRegMaskCommon(CompilationUnit* cUnit, int reg) +uint64_t oatGetRegMaskCommon(CompilationUnit* cUnit, int reg) { return getRegMaskCommon(cUnit, reg); } @@ -76,13 +77,13 @@ u8 oatGetRegMaskCommon(CompilationUnit* cUnit, int reg) /* * Mark the corresponding bit(s). */ -inline void setupRegMask(CompilationUnit* cUnit, u8* mask, int reg) +inline void setupRegMask(CompilationUnit* cUnit, uint64_t* mask, int reg) { *mask |= getRegMaskCommon(cUnit, reg); } /* Exported version of setupRegMask */ -void oatSetupRegMask(CompilationUnit* cUnit, u8* mask, int reg) +void oatSetupRegMask(CompilationUnit* cUnit, uint64_t* mask, int reg) { setupRegMask(cUnit, mask, reg); } @@ -493,8 +494,6 @@ LIR* addWordData(CompilationUnit* cUnit, LIR* *constantListP, int value) LIR* addWideData(CompilationUnit* cUnit, LIR* *constantListP, int valLo, int valHi) { - //FIXME: hard-coded little endian, need BE variant - // Insert high word into list first addWordData(cUnit, constantListP, valHi); return addWordData(cUnit, constantListP, valLo); } @@ -943,7 +942,7 @@ LIR* insertCaseLabel(CompilationUnit* cUnit, int vaddr, int keyVal) void markPackedCaseLabels(CompilationUnit* cUnit, SwitchTable *tabRec) { - const u2* table = tabRec->table; + const uint16_t* table = tabRec->table; int baseVaddr = tabRec->vaddr; int *targets = (int*)&table[4]; int entries = table[1]; @@ -956,7 +955,7 @@ void markPackedCaseLabels(CompilationUnit* cUnit, SwitchTable *tabRec) void markSparseCaseLabels(CompilationUnit* cUnit, SwitchTable *tabRec) { - const u2* table = tabRec->table; + const uint16_t* table = tabRec->table; int baseVaddr = tabRec->vaddr; int entries = table[1]; int* keys = (int*)&table[2]; @@ -985,9 +984,7 @@ void oatProcessSwitchTables(CompilationUnit* cUnit) } } -//FIXME: Do we have endian issues here? - -void dumpSparseSwitchTable(const u2* table) +void dumpSparseSwitchTable(const uint16_t* table) /* * Sparse switch data format: * ushort ident = 0x0200 magic value @@ -998,7 +995,7 @@ void dumpSparseSwitchTable(const u2* table) * Total size is (2+size*4) 16-bit code units. */ { - u2 ident = table[0]; + uint16_t ident = table[0]; int entries = table[1]; int* keys = (int*)&table[2]; int* targets = &keys[entries]; @@ -1009,7 +1006,7 @@ void dumpSparseSwitchTable(const u2* table) } } -void dumpPackedSwitchTable(const u2* table) +void dumpPackedSwitchTable(const uint16_t* table) /* * Packed switch data format: * ushort ident = 0x0100 magic value @@ -1020,7 +1017,7 @@ void dumpPackedSwitchTable(const u2* table) * Total size is (4+size*2) 16-bit code units. */ { - u2 ident = table[0]; + uint16_t ident = table[0]; int* targets = (int*)&table[4]; int entries = table[1]; int lowKey = s4FromSwitchData(&table[2]); diff --git a/src/compiler/codegen/codegen_util.h b/src/compiler/codegen/codegen_util.h new file mode 100644 index 0000000000..49d52e8f30 --- /dev/null +++ b/src/compiler/codegen/codegen_util.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ART_SRC_COMPILER_CODEGEN_CODEGENUTIL_H_ +#define ART_SRC_COMPILER_CODEGEN_CODEGENUTIL_H_ + +namespace art { + +inline int32_t s4FromSwitchData(const void* switchData) { return *(int32_t*) switchData; } +inline RegisterClass oatRegClassBySize(OpSize size) { return (size == kUnsignedHalf || size == kSignedHalf || size == kUnsignedByte || size == kSignedByte ) ? kCoreReg : kAnyReg; } +void oatAssembleLIR(CompilationUnit* cUnit); +void setMemRefType(LIR* lir, bool isLoad, int memType); +void annotateDalvikRegAccess(LIR* lir, int regId, bool isLoad, bool is64bit); +uint64_t oatGetRegMaskCommon(CompilationUnit* cUnit, int reg); +void oatSetupRegMask(CompilationUnit* cUnit, uint64_t* mask, int reg); +void setupResourceMasks(CompilationUnit* cUnit, LIR* lir); +void oatDumpLIRInsn(CompilationUnit* cUnit, LIR* arg, unsigned char* baseAddr); +void oatDumpPromotionMap(CompilationUnit *cUnit); +void dumpMappingTable(const char* table_name, const std::string& descriptor, const std::string& name, const std::string& signature, const std::vector<uint32_t>& v); +void oatCodegenDump(CompilationUnit* cUnit); +// TODO: remove default parameters +LIR* rawLIR(CompilationUnit* cUnit, int dalvikOffset, int opcode, int op0 = 0, int op1 = 0, int op2 = 0, int op3 = 0, int op4 = 0, LIR* target = NULL); +LIR* newLIR0(CompilationUnit* cUnit, int opcode); +LIR* newLIR1(CompilationUnit* cUnit, int opcode, int dest); +LIR* newLIR2(CompilationUnit* cUnit, int opcode, int dest, int src1); +LIR* newLIR3(CompilationUnit* cUnit, int opcode, int dest, int src1, int src2); +LIR* newLIR4(CompilationUnit* cUnit, int opcode, int dest, int src1, int src2, int info); +LIR* newLIR5(CompilationUnit* cUnit, int opcode, int dest, int src1, int src2, int info1, int info2); +LIR* scanLiteralPool(LIR* dataTarget, int value, unsigned int delta); +LIR* scanLiteralPoolWide(LIR* dataTarget, int valLo, int valHi); +LIR* addWordData(CompilationUnit* cUnit, LIR* *constantListP, int value); +LIR* addWideData(CompilationUnit* cUnit, LIR* *constantListP, int valLo, int valHi); +void oatProcessSwitchTables(CompilationUnit* cUnit); +void dumpSparseSwitchTable(const uint16_t* table); +void dumpPackedSwitchTable(const uint16_t* table); +LIR* markBoundary(CompilationUnit* cUnit, int offset, const char* instStr); + +} // namespace art + +#endif // ART_SRC_COMPILER_CODEGEN_CODEGENUTIL_H_ diff --git a/src/compiler/codegen/compiler_codegen.h b/src/compiler/codegen/compiler_codegen.h index 45838c1465..2d1396544a 100644 --- a/src/compiler/codegen/compiler_codegen.h +++ b/src/compiler/codegen/compiler_codegen.h @@ -21,7 +21,6 @@ namespace art { - // Set to 1 to measure cost of suspend check #define NO_SUSPEND 0 @@ -127,123 +126,11 @@ enum OpFeatureFlags { #define REG_USE12 (REG_USE1 | REG_USE2) #define REG_USE23 (REG_USE2 | REG_USE3) -LIR* rawLIR(CompilationUnit* cUnit, int dalvikOffset, int opcode, int op0 = 0, - int op1 = 0, int op2 = 0, int op3 = 0, int op4 = 0, - LIR* target = NULL); - -int oatGetInsnSize(LIR* lir); - -void genFusedLongCmpBranch(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir); -void genFusedFPCmpBranch(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir, - bool gtBias, bool isDouble); - -CallInfo* oatNewCallInfo(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir, - InvokeType type, bool isRange); - -/* Lower middle-level IR to low-level IR for the whole method */ -void oatMethodMIR2LIR(CompilationUnit* cUnit); - -/* Bitcode conversions */ -void oatMethodMIR2Bitcode(CompilationUnit* cUnit); -void oatMethodBitcode2LIR(CompilationUnit* cUnit); - -/* Lower middle-level IR to low-level IR for the simple methods */ -void oatSpecialMIR2LIR(CompilationUnit* cUnit, SpecialCaseHandler specialCase ); - -/* Assemble LIR into machine code */ -void oatAssembleLIR(CompilationUnit* cUnit); -AssemblerStatus oatAssembleInstructions(CompilationUnit* cUnit, - intptr_t startAddr); -void oatAssignOffsets(CompilationUnit* cUnit); -int oatAssignInsnOffsets(CompilationUnit* cUnit); - -/* Implemented in the codegen/<target>/ArchUtility.c */ -void oatCodegenDump(CompilationUnit* cUnit); -void oatDumpPromotionMap(CompilationUnit* cUnit); -std::string buildInsnString(const char* fmt, LIR* lir, - unsigned char* baseAddr); - - -/* Implemented in codegen/<target>/Ralloc.c */ -void oatSimpleRegAlloc(CompilationUnit* cUnit); - -/* Implemented in codegen/<target>/Thumb<version>Util.c */ -void oatInitializeRegAlloc(CompilationUnit* cUnit); - -/* Implemented in codegen/<target>/<target_variant>/ArchVariant.c */ -InstructionSet oatInstructionSet(); - -/* - * Implemented in codegen/<target>/<target_variant>/ArchVariant.c - * Architecture-specific initializations and checks - */ -bool oatArchVariantInit(void); - -/* Implemented in codegen/<target>/<target_variant>/ArchVariant.c */ -int oatTargetOptHint(int key); - -/* Implemented in codegen/<target>/<target_variant>/ArchVariant.c */ -void oatGenMemBarrier(CompilationUnit* cUnit, int barrierKind); - -LIR* genRegMemCheck(CompilationUnit* cUnit, ConditionCode cCode, - int reg1, int base, int offset, ThrowKind kind); -LIR* opThreadMem(CompilationUnit* cUnit, OpKind op, int threadOffset); -LIR* opMem(CompilationUnit* cUnit, OpKind op, int rBase, int disp); -LIR* storeBaseIndexedDisp(CompilationUnit *cUnit, - int rBase, int rIndex, int scale, int displacement, - int rSrc, int rSrcHi, OpSize size, int sReg); -LIR* opRegMem(CompilationUnit *cUnit, OpKind op, int rDest, int rBase, int offset); -LIR* opCmpBranch(CompilationUnit* cUnit, ConditionCode cond, int src1, - int src2, LIR* target); -void oatSetupRegMask(CompilationUnit* cUnit, u8* mask, int reg); -u8 oatGetRegMaskCommon(CompilationUnit* cUnit, int reg); -void setupTargetResourceMasks(CompilationUnit* cUnit, LIR* lir); -RegLocation genDivRem(CompilationUnit* cUnit, RegLocation rlDest, int regLo, int regHi, bool isDiv); -RegLocation genDivRemLit(CompilationUnit* cUnit, RegLocation rlDest, int regLo, int lit, bool isDiv); -void markGCCard(CompilationUnit* cUnit, int valReg, int tgtAddrReg); -bool genInlinedMinMaxInt(CompilationUnit *cUnit, CallInfo* info, bool isMin); -void opLea(CompilationUnit* cUnit, int rBase, int reg1, int reg2, int scale, int offset); -void opTlsCmp(CompilationUnit* cUnit, int offset, int val); -bool genInlinedSqrt(CompilationUnit* cUnit, CallInfo* info); -bool genInlinedCas32(CompilationUnit* cUnit, CallInfo* info, bool need_write_barrier); -LIR* opPcRelLoad(CompilationUnit* cUnit, int reg, LIR* target); -LIR* opVldm(CompilationUnit* cUnit, int rBase, int count); -LIR* opVstm(CompilationUnit* cUnit, int rBase, int count); -void genMultiplyByTwoBitMultiplier(CompilationUnit* cUnit, RegLocation rlSrc, - RegLocation rlResult, int lit, - int firstBit, int secondBit); -RegLocation inlineTarget(CompilationUnit* cUnit, CallInfo* info); -RegLocation inlineTargetWide(CompilationUnit* cUnit, CallInfo* info); -void genDivZeroCheck(CompilationUnit* cUnit, int regLo, int regHi); -LIR* genImmedCheck(CompilationUnit* cUnit, ConditionCode cCode, - int reg, int immVal, ThrowKind kind); -LIR* opTestSuspend(CompilationUnit* cUnit, LIR* target); -LIR* opDecAndBranch(CompilationUnit* cUnit, ConditionCode cCode, int reg, LIR* target); -LIR* opIT(CompilationUnit* cUnit, ArmConditionCode cond, const char* guide); -uint64_t getPCUseDefEncoding(); -uint64_t getRegMaskCommon(CompilationUnit* cUnit, int reg); -// TODO: clean up include files -int s2d(int lowReg, int highReg); -bool fpReg(int reg); -bool singleReg(int reg); -bool doubleReg(int reg); -uint32_t fpRegMask(); -bool sameRegType(int reg1, int reg2); -int targetReg(SpecialTargetRegister reg); -RegLocation locCReturn(); -RegLocation locCReturnWide(); -RegLocation locCReturnFloat(); -RegLocation locCReturnDouble(); -LIR* loadWordDisp(CompilationUnit* cUnit, int rBase, int displacement, int rDest); -LIR *storeWordDisp(CompilationUnit *cUnit, int rBase, - int displacement, int rSrc); -void removeRedundantBranches(CompilationUnit* cUnit); -LIR* newLIR0(CompilationUnit* cUnit, int opcode); -LIR* newLIR1(CompilationUnit* cUnit, int opcode, int dest); -LIR *opRegImm(CompilationUnit *cUnit, OpKind op, int rDestSrc1, int value); -void spillCoreRegs(CompilationUnit* cUnit); -void unSpillCoreRegs(CompilationUnit* cUnit); -void opRegThreadMem(CompilationUnit* cUnit, OpKind op, int rDest, int threadOffset); +// TEMP +#include "gen_loadstore.h" +#include "gen_common.h" +#include "gen_invoke.h" +#include "target_list.h" } // namespace art diff --git a/src/compiler/codegen/gen_common.cc b/src/compiler/codegen/gen_common.cc index bc61c54f1f..fe10fe46af 100644 --- a/src/compiler/codegen/gen_common.cc +++ b/src/compiler/codegen/gen_common.cc @@ -18,14 +18,14 @@ namespace art { +//TODO: remove decl. +void genInvoke(CompilationUnit* cUnit, CallInfo* info); + /* * This source files contains "gen" codegen routines that should * be applicable to most targets. Only mid-level support utilities * and "op" calls may be used here. */ -void genInvoke(CompilationUnit* cUnit, CallInfo* info); -bool smallLiteralDivide(CompilationUnit* cUnit, Instruction::Code dalvikOpcode, - RegLocation rlSrc, RegLocation rlDest, int lit); void markSafepointPC(CompilationUnit* cUnit, LIR* inst) { @@ -2161,7 +2161,6 @@ bool genConversionCall(CompilationUnit* cUnit, int funcOffset, return false; } -void genNegFloat(CompilationUnit* cUnit, RegLocation rlDest, RegLocation rlSrc); bool genArithOpFloatPortable(CompilationUnit* cUnit, Instruction::Code opcode, RegLocation rlDest, RegLocation rlSrc1, RegLocation rlSrc2) @@ -2204,7 +2203,6 @@ bool genArithOpFloatPortable(CompilationUnit* cUnit, Instruction::Code opcode, return false; } -void genNegDouble(CompilationUnit* cUnit, RegLocation rlDst, RegLocation rlSrc); bool genArithOpDoublePortable(CompilationUnit* cUnit, Instruction::Code opcode, RegLocation rlDest, RegLocation rlSrc1, RegLocation rlSrc2) diff --git a/src/compiler/codegen/gen_common.h b/src/compiler/codegen/gen_common.h new file mode 100644 index 0000000000..db4b74c6bb --- /dev/null +++ b/src/compiler/codegen/gen_common.h @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ART_SRC_COMPILER_CODEGEN_GENCOMMON_H_ +#define ART_SRC_COMPILER_CODEGEN_GENCOMMON_H_ + +void markSafepointPC(CompilationUnit* cUnit, LIR* inst); +void callRuntimeHelperImm(CompilationUnit* cUnit, int helperOffset, int arg0, bool safepointPC); +void callRuntimeHelperReg(CompilationUnit* cUnit, int helperOffset, int arg0, bool safepointPC); +void callRuntimeHelperRegLocation(CompilationUnit* cUnit, int helperOffset, RegLocation arg0, bool safepointPC); +void callRuntimeHelperImmImm(CompilationUnit* cUnit, int helperOffset, int arg0, int arg1, bool safepointPC); +void callRuntimeHelperImmRegLocation(CompilationUnit* cUnit, int helperOffset, int arg0, RegLocation arg1, bool safepointPC); +void callRuntimeHelperRegLocationImm(CompilationUnit* cUnit, int helperOffset, RegLocation arg0, int arg1, bool safepointPC); +void callRuntimeHelperImmReg(CompilationUnit* cUnit, int helperOffset, int arg0, int arg1, bool safepointPC); +void callRuntimeHelperRegImm(CompilationUnit* cUnit, int helperOffset, int arg0, int arg1, bool safepointPC); +void callRuntimeHelperImmMethod(CompilationUnit* cUnit, int helperOffset, int arg0, bool safepointPC); +void callRuntimeHelperRegLocationRegLocation(CompilationUnit* cUnit, int helperOffset, RegLocation arg0, RegLocation arg1, bool safepointPC); +void callRuntimeHelperRegReg(CompilationUnit* cUnit, int helperOffset, int arg0, int arg1, bool safepointPC); +void callRuntimeHelperRegRegImm(CompilationUnit* cUnit, int helperOffset, int arg0, int arg1, int arg2, bool safepointPC); +void callRuntimeHelperImmMethodRegLocation(CompilationUnit* cUnit, int helperOffset, int arg0, RegLocation arg2, bool safepointPC); +void callRuntimeHelperImmMethodImm(CompilationUnit* cUnit, int helperOffset, int arg0, int arg2, bool safepointPC); +void callRuntimeHelperImmRegLocationRegLocation(CompilationUnit* cUnit, int helperOffset, int arg0, RegLocation arg1, RegLocation arg2, bool safepointPC); +void genBarrier(CompilationUnit* cUnit); +LIR* opUnconditionalBranch(CompilationUnit* cUnit, LIR* target); +LIR* genCheck(CompilationUnit* cUnit, ConditionCode cCode, ThrowKind kind); +LIR* genImmedCheck(CompilationUnit* cUnit, ConditionCode cCode, int reg, int immVal, ThrowKind kind); +LIR* genNullCheck(CompilationUnit* cUnit, int sReg, int mReg, int optFlags); +LIR* genRegRegCheck(CompilationUnit* cUnit, ConditionCode cCode, int reg1, int reg2, ThrowKind kind); +void genCompareAndBranch(CompilationUnit* cUnit, Instruction::Code opcode, RegLocation rlSrc1, RegLocation rlSrc2, LIR* taken, LIR* fallThrough); +void genCompareZeroAndBranch(CompilationUnit* cUnit, Instruction::Code opcode, RegLocation rlSrc, LIR* taken, LIR* fallThrough); +void genIntToLong(CompilationUnit* cUnit, RegLocation rlDest, RegLocation rlSrc); +void genIntNarrowing(CompilationUnit* cUnit, Instruction::Code opcode, RegLocation rlDest, RegLocation rlSrc); +void genNewArray(CompilationUnit* cUnit, uint32_t type_idx, RegLocation rlDest, RegLocation rlSrc); +void genFilledNewArray(CompilationUnit* cUnit, CallInfo* info); +void genSput(CompilationUnit* cUnit, uint32_t fieldIdx, RegLocation rlSrc, bool isLongOrDouble, bool isObject); +void genSget(CompilationUnit* cUnit, uint32_t fieldIdx, RegLocation rlDest, bool isLongOrDouble, bool isObject); +void genShowTarget(CompilationUnit* cUnit); +void handleSuspendLaunchpads(CompilationUnit *cUnit); +void handleIntrinsicLaunchpads(CompilationUnit *cUnit); +void handleThrowLaunchpads(CompilationUnit *cUnit); +void oatSetupResourceMasks(CompilationUnit* cUnit, LIR* lir); +bool fastInstance(CompilationUnit* cUnit, uint32_t fieldIdx, int& fieldOffset, bool& isVolatile, bool isPut); +void genIGet(CompilationUnit* cUnit, uint32_t fieldIdx, int optFlags, OpSize size, RegLocation rlDest, RegLocation rlObj, bool isLongOrDouble, bool isObject); +void genIPut(CompilationUnit* cUnit, uint32_t fieldIdx, int optFlags, OpSize size, RegLocation rlSrc, RegLocation rlObj, bool isLongOrDouble, bool isObject); +void genConstClass(CompilationUnit* cUnit, uint32_t type_idx, RegLocation rlDest); +void genConstString(CompilationUnit* cUnit, uint32_t string_idx, RegLocation rlDest); +void genNewInstance(CompilationUnit* cUnit, uint32_t type_idx, RegLocation rlDest); +void genMoveException(CompilationUnit* cUnit, RegLocation rlDest); +void genThrow(CompilationUnit* cUnit, RegLocation rlSrc); +void genInstanceof(CompilationUnit* cUnit, uint32_t type_idx, RegLocation rlDest, RegLocation rlSrc); +void genCheckCast(CompilationUnit* cUnit, uint32_t type_idx, RegLocation rlSrc); +void genArrayObjPut(CompilationUnit* cUnit, int optFlags, RegLocation rlArray, RegLocation rlIndex, RegLocation rlSrc, int scale); +void genArrayGet(CompilationUnit* cUnit, int optFlags, OpSize size, RegLocation rlArray, RegLocation rlIndex, RegLocation rlDest, int scale); +void genArrayPut(CompilationUnit* cUnit, int optFlags, OpSize size, RegLocation rlArray, RegLocation rlIndex, RegLocation rlSrc, int scale); +void genLong3Addr(CompilationUnit* cUnit, OpKind firstOp, OpKind secondOp, RegLocation rlDest, RegLocation rlSrc1, RegLocation rlSrc2); +bool genShiftOpLong(CompilationUnit* cUnit, Instruction::Code opcode, RegLocation rlDest, RegLocation rlSrc1, RegLocation rlShift); +bool genArithOpInt(CompilationUnit* cUnit, Instruction::Code opcode, RegLocation rlDest, RegLocation rlSrc1, RegLocation rlSrc2); +bool handleEasyDivide(CompilationUnit* cUnit, Instruction::Code dalvikOpcode, RegLocation rlSrc, RegLocation rlDest, int lit); +bool handleEasyMultiply(CompilationUnit* cUnit, RegLocation rlSrc, RegLocation rlDest, int lit); +bool genArithOpIntLit(CompilationUnit* cUnit, Instruction::Code opcode, RegLocation rlDest, RegLocation rlSrc, int lit); +bool genArithOpLong(CompilationUnit* cUnit, Instruction::Code opcode, RegLocation rlDest, RegLocation rlSrc1, RegLocation rlSrc2); +bool genConversionCall(CompilationUnit* cUnit, int funcOffset, RegLocation rlDest, RegLocation rlSrc); +bool genArithOpFloatPortable(CompilationUnit* cUnit, Instruction::Code opcode, RegLocation rlDest, RegLocation rlSrc1, RegLocation rlSrc2); +bool genArithOpDoublePortable(CompilationUnit* cUnit, Instruction::Code opcode, RegLocation rlDest, RegLocation rlSrc1, RegLocation rlSrc2); +bool genConversionPortable(CompilationUnit* cUnit, Instruction::Code opcode, RegLocation rlDest, RegLocation rlSrc); +void genSuspendTest(CompilationUnit* cUnit, int optFlags); +void genSuspendTestAndBranch(CompilationUnit* cUnit, int optFlags, LIR* target); + +#endif // ART_SRC_COMPILER_CODEGEN_GENCOMMON_H_ diff --git a/src/compiler/codegen/gen_invoke.cc b/src/compiler/codegen/gen_invoke.cc index efd4f5ae6a..bac6a76762 100644 --- a/src/compiler/codegen/gen_invoke.cc +++ b/src/compiler/codegen/gen_invoke.cc @@ -24,11 +24,6 @@ namespace art { * and "op" calls may be used here. */ -typedef int (*NextCallInsn)(CompilationUnit*, CallInfo*, int, uint32_t dexIdx, - uint32_t methodIdx, uintptr_t directCode, - uintptr_t directMethod, InvokeType type); -LIR* opCondBranch(CompilationUnit* cUnit, ConditionCode cc, LIR* target); - /* * If there are any ins passed in registers that have not been promoted * to a callee-save register, flush them to the frame. Perform intial @@ -112,7 +107,8 @@ void flushIns(CompilationUnit* cUnit, RegLocation* argLocs, RegLocation rlMethod } } -void scanMethodLiteralPool(CompilationUnit* cUnit, LIR** methodTarget, LIR** codeTarget, const DexFile* dexFile, uint32_t dexMethodIdx) +void scanMethodLiteralPool(CompilationUnit* cUnit, LIR** methodTarget, LIR** codeTarget, + const DexFile* dexFile, uint32_t dexMethodIdx) { LIR* curTarget = cUnit->methodLiteralList; LIR* nextTarget = curTarget != NULL ? curTarget->next : NULL; diff --git a/src/compiler/codegen/gen_invoke.h b/src/compiler/codegen/gen_invoke.h new file mode 100644 index 0000000000..d4a348cfe3 --- /dev/null +++ b/src/compiler/codegen/gen_invoke.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ART_SRC_COMPILER_CODEGEN_GENINVOKE_H_ +#define ART_SRC_COMPILER_CODEGEN_GENINVOKE_H_ + +typedef int (*NextCallInsn)(CompilationUnit*, CallInfo*, int, uint32_t dexIdx, + uint32_t methodIdx, uintptr_t directCode, + uintptr_t directMethod, InvokeType type); + +void flushIns(CompilationUnit* cUnit, RegLocation* argLocs, RegLocation rlMethod); +int genDalvikArgsNoRange(CompilationUnit* cUnit, CallInfo* info, int callState, LIR** pcrLabel, NextCallInsn nextCallInsn, uint32_t dexIdx, uint32_t methodIdx, uintptr_t directCode, uintptr_t directMethod, InvokeType type, bool skipThis); +int genDalvikArgsRange(CompilationUnit* cUnit, CallInfo* info, int callState, LIR** pcrLabel, NextCallInsn nextCallInsn, uint32_t dexIdx, uint32_t methodIdx, uintptr_t directCode, uintptr_t directMethod, InvokeType type, bool skipThis); +RegLocation inlineTarget(CompilationUnit* cUnit, CallInfo* info); +RegLocation inlineTargetWide(CompilationUnit* cUnit, CallInfo* info); +bool genInlinedCharAt(CompilationUnit* cUnit, CallInfo* info); +bool genInlinedStringIsEmptyOrLength(CompilationUnit* cUnit, CallInfo* info, bool isEmpty); +bool genInlinedAbsInt(CompilationUnit *cUnit, CallInfo* info); +bool genInlinedAbsLong(CompilationUnit *cUnit, CallInfo* info); +bool genInlinedFloatCvt(CompilationUnit *cUnit, CallInfo* info); +bool genInlinedDoubleCvt(CompilationUnit *cUnit, CallInfo* info); +bool genInlinedIndexOf(CompilationUnit* cUnit, CallInfo* info, bool zeroBased); +bool genInlinedStringCompareTo(CompilationUnit* cUnit, CallInfo* info); +bool genIntrinsic(CompilationUnit* cUnit, CallInfo* info); + +#endif // ART_SRC_COMPILER_CODEGEN_GENINVOKE_H_ diff --git a/src/compiler/codegen/codegen_factory.cc b/src/compiler/codegen/gen_loadstore.cc index 600b324841..600b324841 100644 --- a/src/compiler/codegen/codegen_factory.cc +++ b/src/compiler/codegen/gen_loadstore.cc diff --git a/src/compiler/codegen/gen_loadstore.h b/src/compiler/codegen/gen_loadstore.h new file mode 100644 index 0000000000..a06ed792a0 --- /dev/null +++ b/src/compiler/codegen/gen_loadstore.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ART_SRC_COMPILER_CODEGEN_GENLOADSTORE_H_ +#define ART_SRC_COMPILER_CODEGEN_GENLOADSTORE_H_ + +LIR* loadConstant(CompilationUnit* cUnit, int rDest, int value); +LIR* loadWordDisp(CompilationUnit* cUnit, int rBase, int displacement, int rDest); +LIR* storeWordDisp(CompilationUnit* cUnit, int rBase, int displacement, int rSrc); +void loadValueDirect(CompilationUnit* cUnit, RegLocation rlSrc, int rDest); +void loadValueDirectFixed(CompilationUnit* cUnit, RegLocation rlSrc, int rDest); +void loadValueDirectWide(CompilationUnit* cUnit, RegLocation rlSrc, int regLo, int regHi); +void loadValueDirectWideFixed(CompilationUnit* cUnit, RegLocation rlSrc, int regLo, int regHi); +RegLocation loadValue(CompilationUnit* cUnit, RegLocation rlSrc, RegisterClass opKind); +void storeValue(CompilationUnit* cUnit, RegLocation rlDest, RegLocation rlSrc); +RegLocation loadValueWide(CompilationUnit* cUnit, RegLocation rlSrc, RegisterClass opKind); +void storeValueWide(CompilationUnit* cUnit, RegLocation rlDest, RegLocation rlSrc); +void loadCurrMethodDirect(CompilationUnit *cUnit, int rTgt); +RegLocation loadCurrMethod(CompilationUnit *cUnit); +bool methodStarInReg(CompilationUnit* cUnit); + +#endif // ART_SRC_COMPILER_CODEGEN_GENLOADSTORE_H_ diff --git a/src/compiler/codegen/local_optimizations.cc b/src/compiler/codegen/local_optimizations.cc index 2688d65877..e485f03a36 100644 --- a/src/compiler/codegen/local_optimizations.cc +++ b/src/compiler/codegen/local_optimizations.cc @@ -43,7 +43,7 @@ void convertMemOpIntoMove(CompilationUnit* cUnit, LIR* origLIR, int dest, { /* Insert a move to replace the load */ LIR* moveLIR; - moveLIR = oatRegCopyNoInsert( cUnit, dest, src); + moveLIR = opRegCopyNoInsert( cUnit, dest, src); /* * Insert the converted instruction after the original since the * optimization is scannng in the top-down order and the new instruction @@ -102,7 +102,7 @@ void applyLoadStoreElimination(CompilationUnit* cUnit, LIR* headLIR, bool isThisLIRLoad = EncodingMap[thisLIR->opcode].flags & IS_LOAD; LIR* checkLIR; /* Use the mem mask to determine the rough memory location */ - u8 thisMemMask = (thisLIR->useMask | thisLIR->defMask) & ENCODE_MEM; + uint64_t thisMemMask = (thisLIR->useMask | thisLIR->defMask) & ENCODE_MEM; /* * Currently only eliminate redundant ld/st for constant and Dalvik @@ -110,8 +110,8 @@ void applyLoadStoreElimination(CompilationUnit* cUnit, LIR* headLIR, */ if (!(thisMemMask & (ENCODE_LITERAL | ENCODE_DALVIK_REG))) continue; - u8 stopDefRegMask = thisLIR->defMask & ~ENCODE_MEM; - u8 stopUseRegMask; + uint64_t stopDefRegMask = thisLIR->defMask & ~ENCODE_MEM; + uint64_t stopUseRegMask; if (cUnit->instructionSet == kX86) { stopUseRegMask = (IS_BRANCH | thisLIR->useMask) & ~ENCODE_MEM; } else { @@ -134,8 +134,8 @@ void applyLoadStoreElimination(CompilationUnit* cUnit, LIR* headLIR, */ if (checkLIR->flags.isNop) continue; - u8 checkMemMask = (checkLIR->useMask | checkLIR->defMask) & ENCODE_MEM; - u8 aliasCondition = thisMemMask & checkMemMask; + uint64_t checkMemMask = (checkLIR->useMask | checkLIR->defMask) & ENCODE_MEM; + uint64_t aliasCondition = thisMemMask & checkMemMask; bool stopHere = false; /* @@ -287,7 +287,7 @@ void applyLoadHoisting(CompilationUnit* cUnit, LIR* headLIR, LIR* tailLIR) continue; } - u8 stopUseAllMask = thisLIR->useMask; + uint64_t stopUseAllMask = thisLIR->useMask; if (cUnit->instructionSet != kX86) { /* @@ -302,8 +302,8 @@ void applyLoadHoisting(CompilationUnit* cUnit, LIR* headLIR, LIR* tailLIR) } /* Similar as above, but just check for pure register dependency */ - u8 stopUseRegMask = stopUseAllMask & ~ENCODE_MEM; - u8 stopDefRegMask = thisLIR->defMask & ~ENCODE_MEM; + uint64_t stopUseRegMask = stopUseAllMask & ~ENCODE_MEM; + uint64_t stopDefRegMask = thisLIR->defMask & ~ENCODE_MEM; int nextSlot = 0; bool stopHere = false; @@ -319,8 +319,8 @@ void applyLoadHoisting(CompilationUnit* cUnit, LIR* headLIR, LIR* tailLIR) */ if (checkLIR->flags.isNop) continue; - u8 checkMemMask = checkLIR->defMask & ENCODE_MEM; - u8 aliasCondition = stopUseAllMask & checkMemMask; + uint64_t checkMemMask = checkLIR->defMask & ENCODE_MEM; + uint64_t aliasCondition = stopUseAllMask & checkMemMask; stopHere = false; /* Potential WAR alias seen - check the exact relation */ diff --git a/src/compiler/codegen/optimizer.h b/src/compiler/codegen/local_optimizations.h index f5c81a673d..440090f27a 100644 --- a/src/compiler/codegen/optimizer.h +++ b/src/compiler/codegen/local_optimizations.h @@ -14,19 +14,13 @@ * limitations under the License. */ -#ifndef ART_SRC_COMPILER_COMPILER_OPTIMIZATION_H_ -#define ART_SRC_COMPILER_COMPILER_OPTIMIZATION_H_ - -#include "../dalvik.h" +#ifndef ART_SRC_COMPILER_CODEGEN_LOCALOPTIMIZATIONS_H_ +#define ART_SRC_COMPILER_CODEGEN_LOCALOPTIMIZATIONS_H_ namespace art { -/* Forward declarations */ -struct CompilationUnit; -struct LIR; - -void oatApplyLocalOptimizations(CompilationUnit* cUnit, LIR* head, LIR* tail); +void oatApplyLocalOptimizations(CompilationUnit* cUnit, LIR* headLIR, LIR* tailLIR); } // namespace art -#endif // ART_SRC_COMPILER_COMPILER_OPTIMIZATION_H_ +#endif // ART_SRC_COMPILER_CODEGEN_LOCALOPTIMIZATIONS_H_ diff --git a/src/compiler/codegen/method_bitcode.cc b/src/compiler/codegen/method_bitcode.cc index 1e81458dca..d6f1ae9034 100644 --- a/src/compiler/codegen/method_bitcode.cc +++ b/src/compiler/codegen/method_bitcode.cc @@ -27,6 +27,9 @@ #include <llvm/Support/Casting.h> #include <llvm/Support/InstIterator.h> +#include "method_codegen_driver.h" +#include "local_optimizations.h" + static const char* kLabelFormat = "%c0x%x_%d"; static const char kInvalidBlock = 0xff; static const char kNormalBlock = 'L'; @@ -2819,8 +2822,8 @@ void cvtSwitch(CompilationUnit* cUnit, llvm::Instruction* inst) static_cast<llvm::ConstantInt*>(tableOffsetNode->getOperand(0)); int32_t tableOffset = tableOffsetValue->getSExtValue(); RegLocation rlSrc = getLoc(cUnit, testVal); - const u2* table = cUnit->insns + cUnit->currentDalvikOffset + tableOffset; - u2 tableMagic = *table; + const uint16_t* table = cUnit->insns + cUnit->currentDalvikOffset + tableOffset; + uint16_t tableMagic = *table; if (tableMagic == 0x100) { genPackedSwitch(cUnit, tableOffset, rlSrc); } else { diff --git a/src/compiler/codegen/method_bitcode.h b/src/compiler/codegen/method_bitcode.h new file mode 100644 index 0000000000..8b1428682d --- /dev/null +++ b/src/compiler/codegen/method_bitcode.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ART_SRC_COMPILER_CODEGEN_METHODBITCODE_H_ +#define ART_SRC_COMPILER_CODEGEN_METHODBITCODE_H_ + +namespace art { + +void oatMethodMIR2Bitcode(CompilationUnit* cUnit); +void oatMethodBitcode2LIR(CompilationUnit* cUnit); + +} // namespace art + +#endif // ART_SRC_COMPILER_CODEGEN_METHODBITCODE_H_ diff --git a/src/compiler/codegen/method_codegen_driver.cc b/src/compiler/codegen/method_codegen_driver.cc index 3170abc7f0..4ca06b70da 100644 --- a/src/compiler/codegen/method_codegen_driver.cc +++ b/src/compiler/codegen/method_codegen_driver.cc @@ -16,6 +16,8 @@ #include "object_utils.h" +#include "local_optimizations.h" + namespace art { const RegLocation badLoc = {kLocDalvikFrame, 0, 0, 0, 0, 0, 0, 0, 0, @@ -50,6 +52,7 @@ RegLocation oatGetReturn(CompilationUnit* cUnit, bool isFloat) return res; } +// TODO: move to gen_invoke.cc void genInvoke(CompilationUnit* cUnit, CallInfo* info) { if (genIntrinsic(cUnit, info)) { @@ -177,6 +180,7 @@ void genInvoke(CompilationUnit* cUnit, CallInfo* info) * high-word loc for wide arguments. Also pull up any following * MOVE_RESULT and incorporate it into the invoke. */ +//TODO: move to gen_invoke.cc or utils CallInfo* oatNewCallInfo(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir, InvokeType type, bool isRange) { @@ -1032,35 +1036,4 @@ void oatMethodMIR2LIR(CompilationUnit* cUnit) } } -/* Needed by the ld/st optmizatons */ -LIR* oatRegCopyNoInsert(CompilationUnit* cUnit, int rDest, int rSrc) -{ - return opRegCopyNoInsert(cUnit, rDest, rSrc); -} - -/* Needed by the register allocator */ -void oatRegCopy(CompilationUnit* cUnit, int rDest, int rSrc) -{ - opRegCopy(cUnit, rDest, rSrc); -} - -/* Needed by the register allocator */ -void oatRegCopyWide(CompilationUnit* cUnit, int destLo, int destHi, - int srcLo, int srcHi) -{ - opRegCopyWide(cUnit, destLo, destHi, srcLo, srcHi); -} - -void oatFlushRegImpl(CompilationUnit* cUnit, int rBase, - int displacement, int rSrc, OpSize size) -{ - storeBaseDisp(cUnit, rBase, displacement, rSrc, size); -} - -void oatFlushRegWideImpl(CompilationUnit* cUnit, int rBase, - int displacement, int rSrcLo, int rSrcHi) -{ - storeBaseDispWide(cUnit, rBase, displacement, rSrcLo, rSrcHi); -} - } // namespace art diff --git a/src/compiler/codegen/method_codegen_driver.h b/src/compiler/codegen/method_codegen_driver.h new file mode 100644 index 0000000000..dbed04962d --- /dev/null +++ b/src/compiler/codegen/method_codegen_driver.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ART_SRC_COMPILER_CODEGEN_METHODCODEGENDRIVER_H_ +#define ART_SRC_COMPILER_CODEGEN_METHODCODEGENDRIVER_H_ + +namespace art { +// TODO: move genInvoke to gen_invoke.cc +void genInvoke(CompilationUnit* cUnit, CallInfo* info); +// TODO: move genInvoke to gen_invoke.cc or utils +CallInfo* oatNewCallInfo(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir, InvokeType type, bool isRange); +void oatSpecialMIR2LIR(CompilationUnit* cUnit, SpecialCaseHandler specialCase); +void oatMethodMIR2LIR(CompilationUnit* cUnit); + + +} // namespace art + +#endif // ART_SRC_COMPILER_CODEGEN_METHODCODEGENDRIVER_H_ diff --git a/src/compiler/codegen/mips/assemble_mips.cc b/src/compiler/codegen/mips/assemble_mips.cc index ab7a6775eb..1fa3a6b645 100644 --- a/src/compiler/codegen/mips/assemble_mips.cc +++ b/src/compiler/codegen/mips/assemble_mips.cc @@ -14,10 +14,8 @@ * limitations under the License. */ -#include "../../dalvik.h" -#include "../../compiler_internals.h" #include "mips_lir.h" -#include "codegen.h" +#include "../codegen_util.h" namespace art { @@ -653,11 +651,11 @@ AssemblerStatus oatAssembleInstructions(CompilationUnit *cUnit, continue; } const MipsEncodingMap *encoder = &EncodingMap[lir->opcode]; - u4 bits = encoder->skeleton; + uint32_t bits = encoder->skeleton; int i; for (i = 0; i < 4; i++) { - u4 operand; - u4 value; + uint32_t operand; + uint32_t value; operand = lir->operands[i]; switch (encoder->fieldLoc[i].kind) { case kFmtUnused: @@ -703,7 +701,7 @@ AssemblerStatus oatAssembleInstructions(CompilationUnit *cUnit, // TUNING: replace with proper delay slot handling if (encoder->size == 8) { const MipsEncodingMap *encoder = &EncodingMap[kMipsNop]; - u4 bits = encoder->skeleton; + uint32_t bits = encoder->skeleton; cUnit->codeBuffer.push_back(bits & 0xff); cUnit->codeBuffer.push_back((bits >> 8) & 0xff); cUnit->codeBuffer.push_back((bits >> 16) & 0xff); diff --git a/src/compiler/codegen/mips/backend_mips.cc b/src/compiler/codegen/mips/backend_mips.cc index 023d6135e0..596a5f74e2 100644 --- a/src/compiler/codegen/mips/backend_mips.cc +++ b/src/compiler/codegen/mips/backend_mips.cc @@ -16,17 +16,14 @@ #define _CODEGEN_C -#include "../../dalvik.h" -#include "../../compiler_internals.h" #include "mips_lir.h" -#include "../ralloc.h" -#include "codegen.h" +#include "../ralloc_util.h" /* Common codegen building blocks */ #include "../codegen_util.cc" #include "utility_mips.cc" -#include "../codegen_factory.cc" +#include "../gen_loadstore.cc" #include "../gen_common.cc" #include "../gen_invoke.cc" #include "call_mips.cc" diff --git a/src/compiler/codegen/mips/call_mips.cc b/src/compiler/codegen/mips/call_mips.cc index 50cb5948e6..bf67b42645 100644 --- a/src/compiler/codegen/mips/call_mips.cc +++ b/src/compiler/codegen/mips/call_mips.cc @@ -60,7 +60,7 @@ void genSpecialCase(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir, void genSparseSwitch(CompilationUnit* cUnit, uint32_t tableOffset, RegLocation rlSrc) { - const u2* table = cUnit->insns + cUnit->currentDalvikOffset + tableOffset; + const uint16_t* table = cUnit->insns + cUnit->currentDalvikOffset + tableOffset; if (cUnit->printMe) { dumpSparseSwitchTable(table); } @@ -139,7 +139,7 @@ void genSparseSwitch(CompilationUnit* cUnit, uint32_t tableOffset, void genPackedSwitch(CompilationUnit* cUnit, uint32_t tableOffset, RegLocation rlSrc) { - const u2* table = cUnit->insns + cUnit->currentDalvikOffset + tableOffset; + const uint16_t* table = cUnit->insns + cUnit->currentDalvikOffset + tableOffset; if (cUnit->printMe) { dumpPackedSwitchTable(table); } @@ -223,14 +223,14 @@ void genPackedSwitch(CompilationUnit* cUnit, uint32_t tableOffset, void genFillArrayData(CompilationUnit* cUnit, uint32_t tableOffset, RegLocation rlSrc) { - const u2* table = cUnit->insns + cUnit->currentDalvikOffset + tableOffset; + const uint16_t* table = cUnit->insns + cUnit->currentDalvikOffset + tableOffset; // Add the table to the list - we'll process it later FillArrayData *tabRec = (FillArrayData *) oatNew(cUnit, sizeof(FillArrayData), true, kAllocData); tabRec->table = table; tabRec->vaddr = cUnit->currentDalvikOffset; - u2 width = tabRec->table[1]; - u4 size = tabRec->table[2] | (((u4)tabRec->table[3]) << 16); + uint16_t width = tabRec->table[1]; + uint32_t size = tabRec->table[2] | ((static_cast<uint32_t>(tabRec->table[3])) << 16); tabRec->size = (size * width) + 8; oatInsertGrowableList(cUnit, &cUnit->fillArrayData, (intptr_t)tabRec); diff --git a/src/compiler/codegen/mips/codegen.h b/src/compiler/codegen/mips/codegen.h deleted file mode 100644 index 0b3a01e4a0..0000000000 --- a/src/compiler/codegen/mips/codegen.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* This file contains register alloction support */ - -#include "../../compiler_ir.h" - -namespace art { - -#if defined(_CODEGEN_C) -bool genAddLong(CompilationUnit* cUnit, RegLocation rlDest, - RegLocation rlSrc1, RegLocation rlSrc2); -bool genSubLong(CompilationUnit* cUnit, RegLocation rlDest, - RegLocation rlSrc1, RegLocation rlSrc2); -bool genNegLong(CompilationUnit* cUnit, RegLocation rlDest, - RegLocation rlSrc); -LIR *opRegImm(CompilationUnit* cUnit, OpKind op, int rDestSrc1, int value); -LIR *opRegReg(CompilationUnit* cUnit, OpKind op, int rDestSrc1, int rSrc2); -LIR* opCmpBranch(CompilationUnit* cUnit, ConditionCode cond, int src1, - int src2, LIR* target); -LIR* opCmpImmBranch(CompilationUnit* cUnit, ConditionCode cond, int reg, - int checkValue, LIR* target); - -/* Forward declaraton the portable versions due to circular dependency */ -bool genArithOpFloatPortable(CompilationUnit* cUnit, Instruction::Code opcode, - RegLocation rlDest, RegLocation rlSrc1, - RegLocation rlSrc2); - -bool genArithOpDoublePortable(CompilationUnit* cUnit, Instruction::Code opcode, - RegLocation rlDest, RegLocation rlSrc1, - RegLocation rlSrc2); - -bool genConversionPortable(CompilationUnit* cUnit, Instruction::Code opcode, - RegLocation rlDest, RegLocation rlSrc); - -int loadHelper(CompilationUnit* cUnit, int offset); -LIR* loadConstant(CompilationUnit* cUnit, int reg, int immVal); -void opRegCopyWide(CompilationUnit* cUnit, int destLo, int destHi, - int srcLo, int srcHi); -LIR* opRegCopy(CompilationUnit* cUnit, int rDest, int rSrc); -void freeRegLocTemps(CompilationUnit* cUnit, RegLocation rlKeep, - RegLocation rlFree); - - -/* - * Return most flexible allowed register class based on size. - * Bug: 2813841 - * Must use a core register for data types narrower than word (due - * to possible unaligned load/store. - */ -inline RegisterClass oatRegClassBySize(OpSize size) { - return (size == kUnsignedHalf || - size == kSignedHalf || - size == kUnsignedByte || - size == kSignedByte) ? kCoreReg : kAnyReg; -} - -/* - * Construct an s4 from two consecutive half-words of switch data. - * This needs to check endianness because the DEX optimizer only swaps - * half-words in instruction stream. - * - * "switchData" must be 32-bit aligned. - */ -#if __BYTE_ORDER == __LITTLE_ENDIAN -inline s4 s4FromSwitchData(const void* switchData) { - return *reinterpret_cast<const s4*>(switchData); -} -#else -inline s4 s4FromSwitchData(const void* switchData) { - u2* data = switchData; - return data[0] | (((s4) data[1]) << 16); -} -#endif - -#endif - -extern void oatSetupResourceMasks(CompilationUnit* cUnit, LIR* lir); - -extern LIR* oatRegCopyNoInsert(CompilationUnit* cUnit, int rDest, int rSrc); - -bool genAddLong(CompilationUnit* cUnit, RegLocation rlDest, - RegLocation rlSrc1, RegLocation rlSrc2); -bool genSubLong(CompilationUnit* cUnit, RegLocation rlDest, - RegLocation rlSrc1, RegLocation rlSrc2); -bool genAndLong(CompilationUnit* cUnit, RegLocation rlDest, - RegLocation rlSrc1, RegLocation rlSrc2); -bool genOrLong(CompilationUnit* cUnit, RegLocation rlDest, - RegLocation rlSrc1, RegLocation rlSrc2); -bool genXorLong(CompilationUnit* cUnit, RegLocation rlDest, - RegLocation rlSrc1, RegLocation rlSrc2); - -} // namespace art diff --git a/src/compiler/codegen/mips/fp_mips.cc b/src/compiler/codegen/mips/fp_mips.cc index 04056ad96d..5ee5de451e 100644 --- a/src/compiler/codegen/mips/fp_mips.cc +++ b/src/compiler/codegen/mips/fp_mips.cc @@ -67,9 +67,8 @@ bool genArithOpFloat(CompilationUnit *cUnit, Instruction::Code opcode, RegLocati #endif } -static bool genArithOpDouble(CompilationUnit *cUnit, Instruction::Code opcode, - RegLocation rlDest, RegLocation rlSrc1, - RegLocation rlSrc2) +bool genArithOpDouble(CompilationUnit *cUnit, Instruction::Code opcode, + RegLocation rlDest, RegLocation rlSrc1, RegLocation rlSrc2) { #ifdef __mips_hard_float int op = kMipsNop; @@ -117,8 +116,8 @@ static bool genArithOpDouble(CompilationUnit *cUnit, Instruction::Code opcode, #endif } -static bool genConversion(CompilationUnit *cUnit, Instruction::Code opcode, - RegLocation rlDest, RegLocation rlSrc) +bool genConversion(CompilationUnit *cUnit, Instruction::Code opcode, RegLocation rlDest, + RegLocation rlSrc) { #ifdef __mips_hard_float int op = kMipsNop; @@ -170,8 +169,8 @@ static bool genConversion(CompilationUnit *cUnit, Instruction::Code opcode, #endif } -static bool genCmpFP(CompilationUnit *cUnit, Instruction::Code opcode, RegLocation rlDest, - RegLocation rlSrc1, RegLocation rlSrc2) +bool genCmpFP(CompilationUnit *cUnit, Instruction::Code opcode, RegLocation rlDest, + RegLocation rlSrc1, RegLocation rlSrc2) { bool wide = true; int offset; diff --git a/src/compiler/codegen/mips/mips_lir.h b/src/compiler/codegen/mips/mips_lir.h index 03dd71401c..4b604d2ab8 100644 --- a/src/compiler/codegen/mips/mips_lir.h +++ b/src/compiler/codegen/mips/mips_lir.h @@ -17,7 +17,6 @@ #ifndef ART_COMPILER_COMPILER_CODEGEN_MIPS_MIPSLIR_H_ #define ART_COMPILER_COMPILER_CODEGEN_MIPS_MIPSLIR_H_ -#include "../../dalvik.h" #include "../../compiler_internals.h" namespace art { @@ -164,7 +163,7 @@ enum MipsResourceEncodingPos { kMipsRegEnd = 51, }; -#define ENCODE_MIPS_REG_LIST(N) ((u8) N) +#define ENCODE_MIPS_REG_LIST(N) ((uint64_t) N) #define ENCODE_MIPS_REG_SP (1ULL << kMipsRegSP) #define ENCODE_MIPS_REG_LR (1ULL << kMipsRegLR) #define ENCODE_MIPS_REG_PC (1ULL << kMipsRegPC) @@ -420,7 +419,7 @@ enum MipsEncodingKind { /* Struct used to define the snippet positions for each MIPS opcode */ struct MipsEncodingMap { - u4 skeleton; + uint32_t skeleton; struct { MipsEncodingKind kind; int end; /* end for kFmtBitBlt, 1-bit slice end for FP regs */ @@ -433,11 +432,6 @@ struct MipsEncodingMap { int size; /* Size in bytes */ }; -/* Keys for target-specific scheduling and other optimization hints */ -enum MipsTargetOptHints { - kMaxHoistDistance, -}; - extern MipsEncodingMap EncodingMap[kMipsLast]; #define IS_UIMM16(v) ((0 <= (v)) && ((v) <= 65535)) diff --git a/src/compiler/codegen/mips/target_mips.cc b/src/compiler/codegen/mips/target_mips.cc index f32f6c2b40..a5a8d7edfe 100644 --- a/src/compiler/codegen/mips/target_mips.cc +++ b/src/compiler/codegen/mips/target_mips.cc @@ -16,7 +16,8 @@ #include "../../compiler_internals.h" #include "mips_lir.h" -#include "../ralloc.h" +#include "../ralloc_util.h" +#include "../codegen_util.h" #include <string> @@ -125,9 +126,9 @@ bool sameRegType(int reg1, int reg2) /* * Decode the register id. */ -u8 getRegMaskCommon(CompilationUnit* cUnit, int reg) +uint64_t getRegMaskCommon(CompilationUnit* cUnit, int reg) { - u8 seed; + uint64_t seed; int shift; int regId; @@ -274,7 +275,7 @@ std::string buildInsnString(const char *fmt, LIR *lir, unsigned char* baseAddr) } // FIXME: need to redo resource maps for MIPS - fix this at that time -void oatDumpResourceMask(LIR *lir, u8 mask, const char *prefix) +void oatDumpResourceMask(LIR *lir, uint64_t mask, const char *prefix) { char buf[256]; buf[0] = 0; @@ -361,8 +362,7 @@ void oatFlushRegWide(CompilationUnit* cUnit, int reg1, int reg2) if (SRegToVReg(cUnit, info2->sReg) < SRegToVReg(cUnit, info1->sReg)) info1 = info2; int vReg = SRegToVReg(cUnit, info1->sReg); - oatFlushRegWideImpl(cUnit, rMIPS_SP, oatVRegOffset(cUnit, vReg), info1->reg, - info1->partner); + storeBaseDispWide(cUnit, rMIPS_SP, oatVRegOffset(cUnit, vReg), info1->reg, info1->partner); } } @@ -372,7 +372,7 @@ void oatFlushReg(CompilationUnit* cUnit, int reg) if (info->live && info->dirty) { info->dirty = false; int vReg = SRegToVReg(cUnit, info->sReg); - oatFlushRegImpl(cUnit, rMIPS_SP, oatVRegOffset(cUnit, vReg), reg, kWord); + storeBaseDisp(cUnit, rMIPS_SP, oatVRegOffset(cUnit, vReg), reg, kWord); } } @@ -488,19 +488,6 @@ bool oatArchVariantInit(void) return true; } -int dvmCompilerTargetOptHint(int key) -{ - int res; - switch (key) { - case kMaxHoistDistance: - res = 2; - break; - default: - LOG(FATAL) << "Unknown target optimization hint key: " << key; - } - return res; -} - void oatGenMemBarrier(CompilationUnit *cUnit, int barrierKind) { #if ANDROID_SMP != 0 diff --git a/src/compiler/codegen/ralloc_util.cc b/src/compiler/codegen/ralloc_util.cc index 059d1c3c24..4b66ddf286 100644 --- a/src/compiler/codegen/ralloc_util.cc +++ b/src/compiler/codegen/ralloc_util.cc @@ -19,7 +19,8 @@ #include "../compiler_utility.h" #include "../compiler_ir.h" #include "../dataflow.h" -#include "ralloc.h" +#include "ralloc_util.h" +#include "codegen_util.h" namespace art { @@ -935,8 +936,8 @@ RegLocation evalLocWide(CompilationUnit* cUnit, RegLocation loc, newRegs = oatAllocTypedTempPair(cUnit, loc.fp, regClass); lowReg = newRegs & 0xff; highReg = (newRegs >> 8) & 0xff; - oatRegCopyWide(cUnit, lowReg, highReg, loc.lowReg, - loc.highReg); + opRegCopyWide(cUnit, lowReg, highReg, loc.lowReg, + loc.highReg); copyRegInfo(cUnit, lowReg, loc.lowReg); copyRegInfo(cUnit, highReg, loc.highReg); oatClobber(cUnit, loc.lowReg); @@ -980,7 +981,7 @@ extern RegLocation oatEvalLoc(CompilationUnit* cUnit, RegLocation loc, if (!regClassMatches(regClass, loc.lowReg)) { /* Wrong register class. Realloc, copy and transfer ownership */ newReg = oatAllocTypedTemp(cUnit, loc.fp, regClass); - oatRegCopy(cUnit, newReg, loc.lowReg); + opRegCopy(cUnit, newReg, loc.lowReg); copyRegInfo(cUnit, newReg, loc.lowReg); oatClobber(cUnit, loc.lowReg); loc.lowReg = newReg; @@ -1006,24 +1007,28 @@ extern RegLocation oatGetRawSrc(CompilationUnit* cUnit, MIR* mir, int num) RegLocation res = cUnit->regLocation[mir->ssaRep->uses[num]]; return res; } + extern RegLocation oatGetRawDest(CompilationUnit* cUnit, MIR* mir) { DCHECK_GT(mir->ssaRep->numDefs, 0); RegLocation res = cUnit->regLocation[mir->ssaRep->defs[0]]; return res; } + extern RegLocation oatGetDest(CompilationUnit* cUnit, MIR* mir) { RegLocation res = oatGetRawDest(cUnit, mir); DCHECK(!res.wide); return res; } + extern RegLocation oatGetSrc(CompilationUnit* cUnit, MIR* mir, int num) { RegLocation res = oatGetRawSrc(cUnit, mir, num); DCHECK(!res.wide); return res; } + extern RegLocation oatGetDestWide(CompilationUnit* cUnit, MIR* mir) { RegLocation res = oatGetRawDest(cUnit, mir); diff --git a/src/compiler/codegen/ralloc.h b/src/compiler/codegen/ralloc_util.h index 8c327e4d21..56b1e22038 100644 --- a/src/compiler/codegen/ralloc.h +++ b/src/compiler/codegen/ralloc_util.h @@ -14,8 +14,8 @@ * limitations under the License. */ -#ifndef ART_SRC_COMPILER_RALLOC_H_ -#define ART_SRC_COMPILER_RALLOC_H_ +#ifndef ART_SRC_COMPILER_CODEGEN_RALLOCUTIL_H_ +#define ART_SRC_COMPILER_CODEGEN_RALLOCUTIL_H_ /* * This file contains target independent register alloction support. @@ -208,15 +208,6 @@ extern int oatAllocTypedTempPair(CompilationUnit* cUnit, extern int oatAllocTypedTemp(CompilationUnit* cUnit, bool fpHint, int regClass); -extern void oatRegCopyWide(CompilationUnit* cUnit, int destLo, - int destHi, int srcLo, int srcHi); - -extern void oatFlushRegImpl(CompilationUnit* cUnit, int rBase, - int displacement, int rSrc, OpSize size); - -extern void oatFlushRegWideImpl(CompilationUnit* cUnit, int rBase, - int displacement, int rSrcLo, int rSrcHi); - extern void oatDumpCoreRegPool(CompilationUnit* cUint); extern void oatDumpFPRegPool(CompilationUnit* cUint); extern bool oatCheckCorePoolSanity(CompilationUnit* cUnit); @@ -226,9 +217,8 @@ extern bool oatIsFPReg(int reg); extern uint32_t oatFPRegMask(void); extern void oatAdjustSpillMask(CompilationUnit* cUnit); void oatMarkPreservedSingle(CompilationUnit* cUnit, int vReg, int reg); -void oatRegCopy(CompilationUnit* cUnit, int rDest, int rSrc); int oatComputeFrameSize(CompilationUnit* cUnit); } // namespace art -#endif // ART_SRC_COMPILER_RALLOC_H_ +#endif // ART_SRC_COMPILER_CODEGEN_RALLOCUTIL_H_ diff --git a/src/compiler/codegen/target_list.h b/src/compiler/codegen/target_list.h new file mode 100644 index 0000000000..2ada0737aa --- /dev/null +++ b/src/compiler/codegen/target_list.h @@ -0,0 +1,143 @@ +ArmConditionCode oatArmConditionEncoding(ConditionCode code); +AssemblerStatus oatAssembleInstructions(CompilationUnit* cUnit, intptr_t startAddr); +bool doubleReg(int reg); +bool fpReg(int reg); +bool genAddLong(CompilationUnit* cUnit, RegLocation rlDest, RegLocation rlSrc1, RegLocation rlSrc2); +bool genAndLong(CompilationUnit* cUnit, RegLocation rlDest, RegLocation rlSrc1, RegLocation rlSrc2); +bool genArithOpDouble(CompilationUnit* cUnit, Instruction::Code opcode, RegLocation rlDest, RegLocation rlSrc1, RegLocation rlSrc2); +bool genArithOpFloat(CompilationUnit *cUnit, Instruction::Code opcode, RegLocation rlDest, RegLocation rlSrc1, RegLocation rlSrc2); +bool genArithOpFloat(CompilationUnit* cUnit, Instruction::Code opcode, RegLocation rlDest, RegLocation rlSrc1, RegLocation rlSrc2); +bool genCmpFP(CompilationUnit* cUnit, Instruction::Code opcode, RegLocation rlDest, RegLocation rlSrc1, RegLocation rlSrc2); +bool genConversion(CompilationUnit* cUnit, Instruction::Code opcode, RegLocation rlDest, RegLocation rlSrc); +bool genInlinedCas32(CompilationUnit* cUnit, CallInfo* info, bool need_write_barrier); +bool genInlinedMinMaxInt(CompilationUnit *cUnit, CallInfo* info, bool isMin); +bool genInlinedSqrt(CompilationUnit* cUnit, CallInfo* info); +bool genNegLong(CompilationUnit* cUnit, RegLocation rlDest, RegLocation rlSrc); +bool genOrLong(CompilationUnit* cUnit, RegLocation rlDest, RegLocation rlSrc1, RegLocation rlSrc2); +bool genSubLong(CompilationUnit* cUnit, RegLocation rlDest, RegLocation rlSrc1, RegLocation rlSrc2); +bool genXorLong(CompilationUnit* cUnit, RegLocation rlDest, RegLocation rlSrc1, RegLocation rlSrc2); +bool oatArchInit(); +bool oatArchVariantInit(void); +bool oatIsFpReg(int reg); +bool sameRegType(int reg1, int reg2); +bool singleReg(int reg); +bool smallLiteralDivide(CompilationUnit* cUnit, Instruction::Code dalvikOpcode, RegLocation rlSrc, RegLocation rlDest, int lit); +char* decodeFPCSRegList(int count, int base, char* buf); +char* decodeRegList(int opcode, int vector, char* buf); +RegisterInfo* oatGetRegInfo(CompilationUnit* cUnit, int reg); +RegLocation oatGetReturnAlt(CompilationUnit* cUnit); +RegLocation oatGetReturnWideAlt(CompilationUnit* cUnit); +void oatClobberCalleeSave(CompilationUnit *cUnit); +void oatFreeCallTemps(CompilationUnit* cUnit); +void oatLockCallTemps(CompilationUnit* cUnit); +InstructionSet oatInstructionSet(); +int encodeImmDoubleHigh(int value); +int encodeImmDouble(int valLo, int valHi); +int encodeImmSingle(int value); +int encodeShift(int code, int amount); +int expandImmediate(int value); +int inPosition(CompilationUnit* cUnit, int sReg); +int leadingZeros(uint32_t val); +int loadHelper(CompilationUnit* cUnit, int offset); +int modifiedImmediate(uint32_t value); +int oatAllocTypedTemp(CompilationUnit* cUnit, bool fpHint, int regClass); +int oatAllocTypedTempPair(CompilationUnit* cUnit, bool fpHint, int regClass); +int oatAssignInsnOffsets(CompilationUnit* cUnit); +int oatGetInsnSize(LIR* lir); +int s2d(int lowReg, int highReg); +int targetReg(SpecialTargetRegister reg); +LIR* fpRegCopy(CompilationUnit* cUnit, int rDest, int rSrc); +LIR* genRegMemCheck(CompilationUnit* cUnit, ConditionCode cCode, int reg1, int base, int offset, ThrowKind kind); +LIR* loadBaseDispBody(CompilationUnit* cUnit, int rBase, int displacement, int rDest, int rDestHi, OpSize size, int sReg); +LIR* loadBaseDisp(CompilationUnit* cUnit, int rBase, int displacement, int rDest, OpSize size, int sReg); +LIR* loadBaseDispWide(CompilationUnit* cUnit, int rBase, int displacement, int rDestLo, int rDestHi, int sReg); +LIR* loadBaseIndexed(CompilationUnit* cUnit, int rBase, int rIndex, int rDest, int scale, OpSize size); +LIR* loadBaseIndexedDisp(CompilationUnit *cUnit, int rBase, int rIndex, int scale, int displacement, int rDest, int rDestHi, OpSize size, int sReg); +LIR* loadConstantNoClobber(CompilationUnit* cUnit, int rDest, int value); +LIR* loadConstantValueWide(CompilationUnit* cUnit, int rDestLo, int rDestHi, int valLo, int valHi); +LIR* loadFPConstantValue(CompilationUnit* cUnit, int rDest, int value); +LIR* loadMultiple(CompilationUnit *cUnit, int rBase, int rMask); +LIR* opBranchUnconditional(CompilationUnit* cUnit, OpKind op); +LIR* opCmpBranch(CompilationUnit* cUnit, ConditionCode cond, int src1, int src2, LIR* target); +LIR* opCmpImmBranch(CompilationUnit* cUnit, ConditionCode cond, int reg, int checkValue, LIR* target); +LIR* opCondBranch(CompilationUnit* cUnit, ConditionCode cc, LIR* target); +LIR* opDecAndBranch(CompilationUnit* cUnit, ConditionCode cCode, int reg, LIR* target); +LIR* opIT(CompilationUnit* cUnit, ArmConditionCode cond, const char* guide); +LIR* opMem(CompilationUnit* cUnit, OpKind op, int rBase, int disp); +LIR* opPcRelLoad(CompilationUnit* cUnit, int reg, LIR* target); +LIR* opReg(CompilationUnit* cUnit, OpKind op, int rDestSrc); +LIR* opRegCopy(CompilationUnit* cUnit, int rDest, int rSrc); +LIR* opRegCopyNoInsert(CompilationUnit* cUnit, int rDest, int rSrc); +LIR* opRegImm(CompilationUnit* cUnit, OpKind op, int rDestSrc1, int value); +LIR* opRegMem(CompilationUnit* cUnit, OpKind op, int rDest, int rBase, int offset); +LIR* opRegReg(CompilationUnit* cUnit, OpKind op, int rDestSrc1, int rSrc2); +LIR* opRegRegImm(CompilationUnit* cUnit, OpKind op, int rDest, int rSrc1, int value); +LIR* opRegRegReg(CompilationUnit* cUnit, OpKind op, int rDest, int rSrc1, int rSrc2); +LIR* opRegRegRegShift(CompilationUnit* cUnit, OpKind op, int rDest, int rSrc1, int rSrc2, int shift); +LIR* opRegRegShift(CompilationUnit* cUnit, OpKind op, int rDestSrc1, int rSrc2, int shift); +LIR* opTestSuspend(CompilationUnit* cUnit, LIR* target); +LIR* opThreadMem(CompilationUnit* cUnit, OpKind op, int threadOffset); +LIR* opVldm(CompilationUnit* cUnit, int rBase, int count); +LIR* opVstm(CompilationUnit* cUnit, int rBase, int count); +LIR* storeBaseDispBody(CompilationUnit* cUnit, int rBase, int displacement, int rSrc, int rSrcHi, OpSize size); +LIR* storeBaseDisp(CompilationUnit* cUnit, int rBase, int displacement, int rSrc, OpSize size); +LIR* storeBaseDispWide(CompilationUnit* cUnit, int rBase, int displacement, int rSrcLo, int rSrcHi); +LIR* storeBaseIndexed(CompilationUnit* cUnit, int rBase, int rIndex, int rSrc, int scale, OpSize size); +LIR* storeBaseIndexedDisp(CompilationUnit *cUnit, int rBase, int rIndex, int scale, int displacement, int rSrc, int rSrcHi, OpSize size, int sReg); +LIR* storeMultiple(CompilationUnit *cUnit, int rBase, int rMask); +MIR* getNextMir(CompilationUnit* cUnit, BasicBlock** pBb, MIR* mir); +MIR* specialIdentity(CompilationUnit* cUnit, MIR* mir); +MIR* specialIGet(CompilationUnit* cUnit, BasicBlock** bb, MIR* mir, OpSize size, bool longOrDouble, bool isObject); +MIR* specialIPut(CompilationUnit* cUnit, BasicBlock** bb, MIR* mir, OpSize size, bool longOrDouble, bool isObject); +RegLocation argLoc(CompilationUnit* cUnit, RegLocation loc); +RegLocation genDivRem(CompilationUnit* cUnit, RegLocation rlDest, int regLo, int regHi, bool isDiv); +RegLocation genDivRemLit(CompilationUnit* cUnit, RegLocation rlDest, int regLo, int lit, bool isDiv); +RegLocation loadArg(CompilationUnit* cUnit, RegLocation loc); +RegLocation locCReturn(); +RegLocation locCReturnDouble(); +RegLocation locCReturnFloat(); +RegLocation locCReturnWide(); +std::string buildInsnString(const char* fmt, LIR* lir, unsigned char* baseAddr); +uint64_t getRegMaskCommon(CompilationUnit* cUnit, int reg); +uint32_t fpRegMask(); +uint32_t oatFpRegMask(); +uint64_t getPCUseDefEncoding(); +void convertShortToLongBranch(CompilationUnit* cUnit, LIR* lir); +void freeRegLocTemps(CompilationUnit* cUnit, RegLocation rlKeep, RegLocation rlFree); +void genCmpLong(CompilationUnit* cUnit, RegLocation rlDest, RegLocation rlSrc1, RegLocation rlSrc2); +void genDivZeroCheck(CompilationUnit* cUnit, int regLo, int regHi); +void genEntrySequence(CompilationUnit* cUnit, RegLocation* argLocs, RegLocation rlMethod); +void genExitSequence(CompilationUnit* cUnit); +void genFillArrayData(CompilationUnit* cUnit, uint32_t tableOffset, RegLocation rlSrc); +void genFusedFPCmpBranch(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir, bool gtBias, bool isDouble); +void genFusedLongCmpBranch(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir); +void genMonitorEnter(CompilationUnit* cUnit, int optFlags, RegLocation rlSrc); +void genMonitorExit(CompilationUnit* cUnit, int optFlags, RegLocation rlSrc); +void genMultiplyByTwoBitMultiplier(CompilationUnit* cUnit, RegLocation rlSrc, RegLocation rlResult, int lit, int firstBit, int secondBit); +void genNegDouble(CompilationUnit* cUnit, RegLocation rlDest, RegLocation rlSrc); +void genNegFloat(CompilationUnit* cUnit, RegLocation rlDest, RegLocation rlSrc); +void genPackedSwitch(CompilationUnit* cUnit, uint32_t tableOffset, RegLocation rlSrc); +void genPrintLabel(CompilationUnit *cUnit, MIR* mir); +void genSparseSwitch(CompilationUnit* cUnit, uint32_t tableOffset, RegLocation rlSrc); +void genSpecialCase(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir, SpecialCaseHandler specialCase); +void loadPair(CompilationUnit* cUnit, int base, int lowReg, int highReg); +void lockLiveArgs(CompilationUnit* cUnit, MIR* mir); +void markGCCard(CompilationUnit* cUnit, int valReg, int tgtAddrReg); +void oatAdjustSpillMask(CompilationUnit* cUnit); +void oatClobberCalleeSave(CompilationUnit *cUnit); +void oatDumpResourceMask(LIR* lir, uint64_t mask, const char* prefix); +void oatFlushReg(CompilationUnit* cUnit, int reg); +void oatFlushRegWide(CompilationUnit* cUnit, int reg1, int reg2); +void oatGenMemBarrier(CompilationUnit* cUnit, int barrierKind); +void oatInitializeRegAlloc(CompilationUnit* cUnit); +void oatMarkPreservedSingle(CompilationUnit* cUnit, int vReg, int reg); +void oatNopLIR( LIR* lir); +void opLea(CompilationUnit* cUnit, int rBase, int reg1, int reg2, int scale, int offset); +void opRegCopyWide(CompilationUnit* cUnit, int destLo, int destHi, int srcLo, int srcHi); +void opRegThreadMem(CompilationUnit* cUnit, OpKind op, int rDest, int threadOffset); +void opTlsCmp(CompilationUnit* cUnit, int offset, int val); +void removeRedundantBranches(CompilationUnit* cUnit); +void setupTargetResourceMasks(CompilationUnit* cUnit, LIR* lir); +void spillCoreRegs(CompilationUnit* cUnit); +void unSpillCoreRegs(CompilationUnit* cUnit); +X86ConditionCode oatX86ConditionEncoding(ConditionCode cond); diff --git a/src/compiler/codegen/x86/assemble_x86.cc b/src/compiler/codegen/x86/assemble_x86.cc index 79ed075828..63d2b83a34 100644 --- a/src/compiler/codegen/x86/assemble_x86.cc +++ b/src/compiler/codegen/x86/assemble_x86.cc @@ -14,10 +14,8 @@ * limitations under the License. */ -#include "../../dalvik.h" -#include "../../compiler_internals.h" #include "x86_lir.h" -#include "codegen.h" +#include "../codegen_util.h" namespace art { diff --git a/src/compiler/codegen/x86/backend_x86.cc b/src/compiler/codegen/x86/backend_x86.cc index 6abfb23b09..13388ff9b4 100644 --- a/src/compiler/codegen/x86/backend_x86.cc +++ b/src/compiler/codegen/x86/backend_x86.cc @@ -16,17 +16,14 @@ #define _CODEGEN_C -#include "../../dalvik.h" -#include "../../compiler_internals.h" #include "x86_lir.h" -#include "../ralloc.h" -#include "codegen.h" +#include "../ralloc_util.h" /* Common codegen utility code */ #include "../codegen_util.cc" #include "utility_x86.cc" -#include "../codegen_factory.cc" +#include "../gen_loadstore.cc" #include "../gen_common.cc" #include "../gen_invoke.cc" #include "call_x86.cc" diff --git a/src/compiler/codegen/x86/call_x86.cc b/src/compiler/codegen/x86/call_x86.cc index 0cd9b2da2d..2b52270724 100644 --- a/src/compiler/codegen/x86/call_x86.cc +++ b/src/compiler/codegen/x86/call_x86.cc @@ -33,7 +33,7 @@ BasicBlock *findBlock(CompilationUnit* cUnit, unsigned int codeOffset, void genSparseSwitch(CompilationUnit* cUnit, uint32_t tableOffset, RegLocation rlSrc) { - const u2* table = cUnit->insns + cUnit->currentDalvikOffset + tableOffset; + const uint16_t* table = cUnit->insns + cUnit->currentDalvikOffset + tableOffset; if (cUnit->printMe) { dumpSparseSwitchTable(table); } @@ -71,7 +71,7 @@ void genSparseSwitch(CompilationUnit* cUnit, uint32_t tableOffset, void genPackedSwitch(CompilationUnit* cUnit, uint32_t tableOffset, RegLocation rlSrc) { - const u2* table = cUnit->insns + cUnit->currentDalvikOffset + tableOffset; + const uint16_t* table = cUnit->insns + cUnit->currentDalvikOffset + tableOffset; if (cUnit->printMe) { dumpPackedSwitchTable(table); } @@ -134,14 +134,14 @@ void callRuntimeHelperRegReg(CompilationUnit* cUnit, int helperOffset, void genFillArrayData(CompilationUnit* cUnit, uint32_t tableOffset, RegLocation rlSrc) { - const u2* table = cUnit->insns + cUnit->currentDalvikOffset + tableOffset; + const uint16_t* table = cUnit->insns + cUnit->currentDalvikOffset + tableOffset; // Add the table to the list - we'll process it later FillArrayData *tabRec = (FillArrayData *)oatNew(cUnit, sizeof(FillArrayData), true, kAllocData); tabRec->table = table; tabRec->vaddr = cUnit->currentDalvikOffset; - u2 width = tabRec->table[1]; - u4 size = tabRec->table[2] | (((u4)tabRec->table[3]) << 16); + uint16_t width = tabRec->table[1]; + uint32_t size = tabRec->table[2] | ((static_cast<uint32_t>(tabRec->table[3])) << 16); tabRec->size = (size * width) + 8; oatInsertGrowableList(cUnit, &cUnit->fillArrayData, (intptr_t)tabRec); diff --git a/src/compiler/codegen/x86/codegen.h b/src/compiler/codegen/x86/codegen.h deleted file mode 100644 index c95fa672ac..0000000000 --- a/src/compiler/codegen/x86/codegen.h +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* This file contains register alloction support */ - -#include "../../compiler_ir.h" - -namespace art { - -#if defined(_CODEGEN_C) -bool genAddLong(CompilationUnit* cUnit, RegLocation rlDest, - RegLocation rlSrc1, RegLocation rlSrc2); -bool genSubLong(CompilationUnit* cUnit, RegLocation rlDest, - RegLocation rlSrc1, RegLocation rlSrc2); -bool genAndLong(CompilationUnit* cUnit, RegLocation rlDest, - RegLocation rlSrc1, RegLocation rlSrc2); -bool genOrLong(CompilationUnit* cUnit, RegLocation rlDest, - RegLocation rlSrc1, RegLocation rlSrc2); -bool genXorLong(CompilationUnit* cUnit, RegLocation rlDest, - RegLocation rlSrc1, RegLocation rlSrc2); -bool genNegLong(CompilationUnit* cUnit, RegLocation rlDest, - RegLocation rlSrc); -LIR *opRegImm(CompilationUnit* cUnit, OpKind op, int rDestSrc1, int value); -LIR *opRegReg(CompilationUnit* cUnit, OpKind op, int rDestSrc1, int rSrc2); -LIR* opCmpBranch(CompilationUnit* cUnit, ConditionCode cond, int src1, - int src2, LIR* target); -LIR* opCmpImmBranch(CompilationUnit* cUnit, ConditionCode cond, int reg, - int checkValue, LIR* target); - -/* Forward declaration of the portable versions due to circular dependency */ -bool genArithOpFloatPortable(CompilationUnit* cUnit, Instruction::Code opcode, - RegLocation rlDest, RegLocation rlSrc1, - RegLocation rlSrc2); - -bool genArithOpDoublePortable(CompilationUnit* cUnit, Instruction::Code opcode, - RegLocation rlDest, RegLocation rlSrc1, - RegLocation rlSrc2); - -bool genConversionPortable(CompilationUnit* cUnit, Instruction::Code opcode, - RegLocation rlDest, RegLocation rlSrc); - -int loadHelper(CompilationUnit* cUnit, int offset); -LIR* loadConstant(CompilationUnit* cUnit, int reg, int immVal); -void opRegCopyWide(CompilationUnit* cUnit, int destLo, int destHi, - int srcLo, int srcHi); -LIR* opRegCopy(CompilationUnit* cUnit, int rDest, int rSrc); -void freeRegLocTemps(CompilationUnit* cUnit, RegLocation rlKeep, - RegLocation rlFree); - - -/* - * Return most flexible allowed register class based on size. - * Bug: 2813841 - * Must use a core register for data types narrower than word (due - * to possible unaligned load/store. - */ -inline RegisterClass oatRegClassBySize(OpSize size) -{ - return (size == kUnsignedHalf || - size == kSignedHalf || - size == kUnsignedByte || - size == kSignedByte ) ? kCoreReg : kAnyReg; -} - -/* - * Construct an s4 from two consecutive half-words of switch data. - * This needs to check endianness because the DEX optimizer only swaps - * half-words in instruction stream. - * - * "switchData" must be 32-bit aligned. - */ -#if __BYTE_ORDER == __LITTLE_ENDIAN -inline s4 s4FromSwitchData(const void* switchData) { - return *(s4*) switchData; -} -#else -inline s4 s4FromSwitchData(const void* switchData) { - u2* data = switchData; - return data[0] | (((s4) data[1]) << 16); -} -#endif - -#endif - -extern void oatSetupResourceMasks(CompilationUnit* cUnit, LIR* lir); - -extern LIR* oatRegCopyNoInsert(CompilationUnit* cUnit, int rDest, int rSrc); - -} // namespace art diff --git a/src/compiler/codegen/x86/fp_x86.cc b/src/compiler/codegen/x86/fp_x86.cc index 0a08ab0b4c..411bd1e381 100644 --- a/src/compiler/codegen/x86/fp_x86.cc +++ b/src/compiler/codegen/x86/fp_x86.cc @@ -16,9 +16,8 @@ namespace art { -static bool genArithOpFloat(CompilationUnit *cUnit, Instruction::Code opcode, - RegLocation rlDest, RegLocation rlSrc1, - RegLocation rlSrc2) { +bool genArithOpFloat(CompilationUnit *cUnit, Instruction::Code opcode, + RegLocation rlDest, RegLocation rlSrc1, RegLocation rlSrc2) { X86OpCode op = kX86Nop; RegLocation rlResult; @@ -67,9 +66,8 @@ static bool genArithOpFloat(CompilationUnit *cUnit, Instruction::Code opcode, return false; } -static bool genArithOpDouble(CompilationUnit *cUnit, Instruction::Code opcode, - RegLocation rlDest, RegLocation rlSrc1, - RegLocation rlSrc2) { +bool genArithOpDouble(CompilationUnit *cUnit, Instruction::Code opcode, + RegLocation rlDest, RegLocation rlSrc1, RegLocation rlSrc2) { X86OpCode op = kX86Nop; RegLocation rlResult; @@ -117,8 +115,8 @@ static bool genArithOpDouble(CompilationUnit *cUnit, Instruction::Code opcode, return false; } -static bool genConversion(CompilationUnit *cUnit, Instruction::Code opcode, - RegLocation rlDest, RegLocation rlSrc) { +bool genConversion(CompilationUnit *cUnit, Instruction::Code opcode, + RegLocation rlDest, RegLocation rlSrc) { RegisterClass rcSrc = kFPReg; X86OpCode op = kX86Nop; int srcReg; @@ -210,8 +208,8 @@ static bool genConversion(CompilationUnit *cUnit, Instruction::Code opcode, return false; } -static bool genCmpFP(CompilationUnit *cUnit, Instruction::Code code, RegLocation rlDest, - RegLocation rlSrc1, RegLocation rlSrc2) { +bool genCmpFP(CompilationUnit *cUnit, Instruction::Code code, RegLocation rlDest, + RegLocation rlSrc1, RegLocation rlSrc2) { bool single = (code == Instruction::CMPL_FLOAT) || (code == Instruction::CMPG_FLOAT); bool unorderedGt = (code == Instruction::CMPG_DOUBLE) || (code == Instruction::CMPG_FLOAT); int srcReg1; diff --git a/src/compiler/codegen/x86/target_x86.cc b/src/compiler/codegen/x86/target_x86.cc index a211c2fe0e..a254876e60 100644 --- a/src/compiler/codegen/x86/target_x86.cc +++ b/src/compiler/codegen/x86/target_x86.cc @@ -16,7 +16,8 @@ #include "../../compiler_internals.h" #include "x86_lir.h" -#include "../ralloc.h" +#include "../ralloc_util.h" +#include "../codegen_util.h" #include <string> @@ -132,9 +133,9 @@ bool sameRegType(int reg1, int reg2) /* * Decode the register id. */ -u8 getRegMaskCommon(CompilationUnit* cUnit, int reg) +uint64_t getRegMaskCommon(CompilationUnit* cUnit, int reg) { - u8 seed; + uint64_t seed; int shift; int regId; @@ -280,7 +281,7 @@ std::string buildInsnString(const char *fmt, LIR *lir, unsigned char* baseAddr) return buf; } -void oatDumpResourceMask(LIR *lir, u8 mask, const char *prefix) +void oatDumpResourceMask(LIR *lir, uint64_t mask, const char *prefix) { char buf[256]; buf[0] = 0; @@ -360,8 +361,7 @@ void oatFlushRegWide(CompilationUnit* cUnit, int reg1, int reg2) if (SRegToVReg(cUnit, info2->sReg) < SRegToVReg(cUnit, info1->sReg)) info1 = info2; int vReg = SRegToVReg(cUnit, info1->sReg); - oatFlushRegWideImpl(cUnit, rX86_SP, oatVRegOffset(cUnit, vReg), - info1->reg, info1->partner); + storeBaseDispWide(cUnit, rX86_SP, oatVRegOffset(cUnit, vReg), info1->reg, info1->partner); } } @@ -371,7 +371,7 @@ void oatFlushReg(CompilationUnit* cUnit, int reg) if (info->live && info->dirty) { info->dirty = false; int vReg = SRegToVReg(cUnit, info->sReg); - oatFlushRegImpl(cUnit, rX86_SP, oatVRegOffset(cUnit, vReg), reg, kWord); + storeBaseDisp(cUnit, rX86_SP, oatVRegOffset(cUnit, vReg), reg, kWord); } } @@ -458,19 +458,6 @@ bool oatArchVariantInit(void) return true; } -int dvmCompilerTargetOptHint(int key) -{ - int res; - switch (key) { - case kMaxHoistDistance: - res = 2; - break; - default: - LOG(FATAL) << "Unknown target optimization hint key: " << key; - } - return res; -} - void oatGenMemBarrier(CompilationUnit *cUnit, int /* barrierKind */) { #if ANDROID_SMP != 0 diff --git a/src/compiler/codegen/x86/x86_lir.h b/src/compiler/codegen/x86/x86_lir.h index fe6d8cb338..3008bc259c 100644 --- a/src/compiler/codegen/x86/x86_lir.h +++ b/src/compiler/codegen/x86/x86_lir.h @@ -17,7 +17,6 @@ #ifndef ART_COMPILER_COMPILER_CODEGEN_X86_X86LIR_H_ #define ART_COMPILER_COMPILER_CODEGEN_X86_X86LIR_H_ -#include "../../dalvik.h" #include "../../compiler_internals.h" namespace art { @@ -143,7 +142,7 @@ enum X86ResourceEncodingPos { kX86RegEnd = kX86FPRegEnd, }; -#define ENCODE_X86_REG_LIST(N) ((u8) N) +#define ENCODE_X86_REG_LIST(N) (static_cast<uint64_t>(N)) #define ENCODE_X86_REG_SP (1ULL << kX86RegSP) /* @@ -436,11 +435,6 @@ extern X86EncodingMap EncodingMap[kX86Last]; #define kSY 0 #define kST 0 -/* Keys for target-specific scheduling and other optimization hints */ -enum X86TargetOptHints { - kMaxHoistDistance, -}; - /* Offsets of high and low halves of a 64bit value */ #define LOWORD_OFFSET 0 #define HIWORD_OFFSET 4 diff --git a/src/compiler/compiler_internals.h b/src/compiler/compiler_internals.h index 2f81afe5aa..c62d8c65ba 100644 --- a/src/compiler/compiler_internals.h +++ b/src/compiler/compiler_internals.h @@ -17,7 +17,23 @@ #ifndef ART_SRC_COMPILER_COMPILER_INTERNAL_H_ #define ART_SRC_COMPILER_COMPILER_INTERNAL_H_ -#include "dalvik.h" +#include <assert.h> +#include <stdbool.h> +#include <stdint.h> +#include <stdio.h> + +#include "gc/card_table.h" +#include "class_linker.h" +#include "compiler.h" +#include "dex_cache.h" +#include "logging.h" +#include "monitor.h" +#include "object.h" +#include "thread.h" +#include "utils.h" + +#include "frontend.h" +#include "ralloc.h" #include "compiler_utility.h" #include "compiler_ir.h" #include "codegen/compiler_codegen.h" diff --git a/src/compiler/compiler_ir.h b/src/compiler/compiler_ir.h index 6c6442d943..f73fe92467 100644 --- a/src/compiler/compiler_ir.h +++ b/src/compiler/compiler_ir.h @@ -18,8 +18,8 @@ #define ART_SRC_COMPILER_COMPILER_IR_H_ #include <vector> - -#include "codegen/optimizer.h" +#include "dex_instruction.h" +#include "compiler.h" #include "compiler_utility.h" #include "oat_compilation_unit.h" #include "safe_map.h" @@ -38,6 +38,10 @@ namespace art { // Minimum field size to contain Dalvik vReg number #define VREG_NUM_WIDTH 16 +struct ArenaBitVector; +struct LIR; +class LLVMInfo; + enum RegisterClass { kCoreReg, kFPReg, @@ -73,9 +77,9 @@ enum RegLocationType { struct PromotionMap { RegLocationType coreLocation:3; - u1 coreReg; + uint8_t coreReg; RegLocationType fpLocation:3; - u1 fpReg; + uint8_t fpReg; bool firstInPair; }; @@ -89,8 +93,8 @@ struct RegLocation { unsigned ref:1; // Something GC cares about unsigned highWord:1; // High word of pair? unsigned home:1; // Does this represent the home location? - u1 lowReg; // First physical register - u1 highReg; // 2nd physical register (if wide) + uint8_t lowReg; // First physical register + uint8_t highReg; // 2nd physical register (if wide) int32_t sRegLow; // SSA name for low Dalvik word int32_t origSReg; // TODO: remove after Bitcode gen complete // and consolodate usage w/ sRegLow @@ -229,8 +233,8 @@ struct LIR { unsigned int unused:25; } flags; int aliasInfo; // For Dalvik register & litpool disambiguation - u8 useMask; // Resource mask for use - u8 defMask; // Resource mask for def + uint64_t useMask; // Resource mask for use + uint64_t defMask; // Resource mask for def }; /* Shared pseudo opcodes - must be < 0 */ @@ -601,8 +605,8 @@ struct CompilationUnit { int currentDalvikOffset; GrowableList switchTables; GrowableList fillArrayData; - const u2* insns; - u4 insnsSize; + const uint16_t* insns; + uint32_t insnsSize; bool disableDataflow; // Skip dataflow analysis if possible SafeMap<unsigned int, BasicBlock*> blockMap; // findBlock lookup cache SafeMap<unsigned int, unsigned int> blockIdMap; // Block collapse lookup cache @@ -797,7 +801,7 @@ enum ThrowKind { struct SwitchTable { int offset; - const u2* table; // Original dex table + const uint16_t* table; // Original dex table int vaddr; // Dalvik offset of switch opcode LIR* anchor; // Reference instruction for relative offsets LIR** targets; // Array of case targets @@ -805,7 +809,7 @@ struct SwitchTable { struct FillArrayData { int offset; - const u2* table; // Original dex table + const uint16_t* table; // Original dex table int size; int vaddr; // Dalvik offset of FILL_ARRAY_DATA opcode }; diff --git a/src/compiler/utility.cc b/src/compiler/compiler_utility.cc index 4a138c6322..8bd4713adc 100644 --- a/src/compiler/utility.cc +++ b/src/compiler/compiler_utility.cc @@ -14,14 +14,13 @@ * limitations under the License. */ -#include "dalvik.h" #include "compiler_internals.h" namespace art { #ifdef WITH_MEMSTATS struct Memstats { - u4 allocStats[kNumAllocKinds]; + uint32_t allocStats[kNumAllocKinds]; int listSizes[kNumListKinds]; int listWasted[kNumListKinds]; int listGrows[kNumListKinds]; @@ -82,7 +81,7 @@ const char* bitMapNames[kNumBitMapKinds] = { }; #endif -#define kArenaBitVectorGrowth 4 /* increase by 4 u4s when limit hit */ +#define kArenaBitVectorGrowth 4 /* increase by 4 uint32_ts when limit hit */ /* Allocate the initial memory block for arena-based allocation */ bool oatHeapInit(CompilationUnit* cUnit) @@ -264,7 +263,7 @@ intptr_t oatGrowableListGetElement(const GrowableList* gList, size_t idx) /* Dump memory usage stats */ void oatDumpMemStats(CompilationUnit* cUnit) { - u4 total = 0; + uint32_t total = 0; for (int i = 0; i < kNumAllocKinds; i++) { total += cUnit->mstats->allocStats[i]; } @@ -369,11 +368,11 @@ ArenaBitVector* oatAllocBitVector(CompilationUnit* cUnit, bv->storageSize = count; bv->expandable = expandable; - bv->storage = (u4*) oatNew(cUnit, count * sizeof(u4), true, - kAllocGrowableBitMap); + bv->storage = static_cast<uint32_t*>(oatNew(cUnit, count * sizeof(uint32_t), true, + kAllocGrowableBitMap)); #ifdef WITH_MEMSTATS bv->kind = kind; - cUnit->mstats->bitMapSizes[kind] += count * sizeof(u4); + cUnit->mstats->bitMapSizes[kind] += count * sizeof(uint32_t); #endif return bv; } @@ -383,7 +382,7 @@ ArenaBitVector* oatAllocBitVector(CompilationUnit* cUnit, */ bool oatIsBitSet(const ArenaBitVector* pBits, unsigned int num) { - DCHECK_LT(num, pBits->storageSize * sizeof(u4) * 8); + DCHECK_LT(num, pBits->storageSize * sizeof(uint32_t) * 8); unsigned int val = pBits->storage[num >> 5] & checkMasks[num & 0x1f]; return (val != 0); @@ -395,7 +394,7 @@ bool oatIsBitSet(const ArenaBitVector* pBits, unsigned int num) void oatClearAllBits(ArenaBitVector* pBits) { unsigned int count = pBits->storageSize; - memset(pBits->storage, 0, count * sizeof(u4)); + memset(pBits->storage, 0, count * sizeof(uint32_t)); } /* @@ -408,7 +407,7 @@ void oatClearAllBits(ArenaBitVector* pBits) */ bool oatSetBit(CompilationUnit* cUnit, ArenaBitVector* pBits, unsigned int num) { - if (num >= pBits->storageSize * sizeof(u4) * 8) { + if (num >= pBits->storageSize * sizeof(uint32_t) * 8) { if (!pBits->expandable) { LOG(FATAL) << "Can't expand"; } @@ -416,15 +415,15 @@ bool oatSetBit(CompilationUnit* cUnit, ArenaBitVector* pBits, unsigned int num) /* Round up to word boundaries for "num+1" bits */ unsigned int newSize = (num + 1 + 31) >> 5; DCHECK_GT(newSize, pBits->storageSize); - u4 *newStorage = (u4*)oatNew(cUnit, newSize * sizeof(u4), false, - kAllocGrowableBitMap); - memcpy(newStorage, pBits->storage, pBits->storageSize * sizeof(u4)); + uint32_t *newStorage = static_cast<uint32_t*>(oatNew(cUnit, newSize * sizeof(uint32_t), false, + kAllocGrowableBitMap)); + memcpy(newStorage, pBits->storage, pBits->storageSize * sizeof(uint32_t)); memset(&newStorage[pBits->storageSize], 0, - (newSize - pBits->storageSize) * sizeof(u4)); + (newSize - pBits->storageSize) * sizeof(uint32_t)); #ifdef WITH_MEMSTATS cUnit->mstats->bitMapWasted[pBits->kind] += - pBits->storageSize * sizeof(u4); - cUnit->mstats->bitMapSizes[pBits->kind] += newSize * sizeof(u4); + pBits->storageSize * sizeof(uint32_t); + cUnit->mstats->bitMapSizes[pBits->kind] += newSize * sizeof(uint32_t); cUnit->mstats->bitMapGrows[pBits->kind]++; #endif pBits->storage = newStorage; @@ -445,7 +444,7 @@ bool oatSetBit(CompilationUnit* cUnit, ArenaBitVector* pBits, unsigned int num) */ bool oatClearBit(ArenaBitVector* pBits, unsigned int num) { - if (num >= pBits->storageSize * sizeof(u4) * 8) { + if (num >= pBits->storageSize * sizeof(uint32_t) * 8) { LOG(FATAL) << "Attempt to clear a bit not set in the vector yet";; } @@ -459,7 +458,7 @@ bool oatClearBit(ArenaBitVector* pBits, unsigned int num) void oatMarkAllBits(ArenaBitVector* pBits, bool set) { int value = set ? -1 : 0; - memset(pBits->storage, value, pBits->storageSize * (int)sizeof(u4)); + memset(pBits->storage, value, pBits->storageSize * static_cast<int>(sizeof(uint32_t))); } void oatDebugBitVector(char* msg, const ArenaBitVector* bv, int length) @@ -499,7 +498,7 @@ void oatBitVectorIteratorInit(ArenaBitVector* pBits, ArenaBitVectorIterator* iterator) { iterator->pBits = pBits; - iterator->bitSize = pBits->storageSize * sizeof(u4) * 8; + iterator->bitSize = pBits->storageSize * sizeof(uint32_t) * 8; iterator->idx = 0; } @@ -523,7 +522,7 @@ void oatCopyBitVector(ArenaBitVector* dest, const ArenaBitVector* src) /* if dest is expandable and < src, we could expand dest to match */ checkSizes(dest, src); - memcpy(dest->storage, src->storage, sizeof(u4) * dest->storageSize); + memcpy(dest->storage, src->storage, sizeof(uint32_t) * dest->storageSize); } /* @@ -608,7 +607,7 @@ int oatCountSetBits(const ArenaBitVector* pBits) unsigned int count = 0; for (word = 0; word < pBits->storageSize; word++) { - u4 val = pBits->storage[word]; + uint32_t val = pBits->storage[word]; if (val != 0) { if (val == 0xffffffff) { @@ -630,23 +629,23 @@ int oatCountSetBits(const ArenaBitVector* pBits) int oatBitVectorIteratorNext(ArenaBitVectorIterator* iterator) { ArenaBitVector* pBits = iterator->pBits; - u4 bitIndex = iterator->idx; - u4 bitSize = iterator->bitSize; + uint32_t bitIndex = iterator->idx; + uint32_t bitSize = iterator->bitSize; - DCHECK_EQ(bitSize, pBits->storageSize * sizeof(u4) * 8); + DCHECK_EQ(bitSize, pBits->storageSize * sizeof(uint32_t) * 8); if (bitIndex >= bitSize) return -1; - u4 wordIndex = bitIndex >> 5; - u4 endWordIndex = bitSize >> 5; - u4* storage = pBits->storage; - u4 word = storage[wordIndex++]; + uint32_t wordIndex = bitIndex >> 5; + uint32_t endWordIndex = bitSize >> 5; + uint32_t* storage = pBits->storage; + uint32_t word = storage[wordIndex++]; // Mask out any bits in the first word we've already considered word &= ~((1 << (bitIndex & 0x1f))-1); for (; wordIndex <= endWordIndex;) { - u4 bitPos = bitIndex & 0x1f; + uint32_t bitPos = bitIndex & 0x1f; if (word == 0) { bitIndex += (32 - bitPos); word = storage[wordIndex++]; diff --git a/src/compiler/compiler_utility.h b/src/compiler/compiler_utility.h index 5dfb95f0cd..2e30380516 100644 --- a/src/compiler/compiler_utility.h +++ b/src/compiler/compiler_utility.h @@ -17,13 +17,72 @@ #ifndef ART_SRC_COMPILER_COMPILER_UTILITY_H_ #define ART_SRC_COMPILER_COMPILER_UTILITY_H_ -#include "dalvik.h" +#include <stdint.h> +#include <stddef.h> namespace art { +struct CompilationUnit; + /* Each arena page has some overhead, so take a few bytes off */ #define ARENA_DEFAULT_SIZE ((2 * 1024 * 1024) - 256) +/* Type of allocation for memory tuning */ +enum oatAllocKind { + kAllocMisc, + kAllocBB, + kAllocLIR, + kAllocMIR, + kAllocDFInfo, + kAllocGrowableList, + kAllocGrowableBitMap, + kAllocDalvikToSSAMap, + kAllocDebugInfo, + kAllocSuccessor, + kAllocRegAlloc, + kAllocData, + kAllocPredecessors, + kNumAllocKinds +}; + +/* Type of growable list for memory tuning */ +enum oatListKind { + kListMisc = 0, + kListBlockList, + kListSSAtoDalvikMap, + kListDfsOrder, + kListDfsPostOrder, + kListDomPostOrderTraversal, + kListThrowLaunchPads, + kListSuspendLaunchPads, + kListSwitchTables, + kListFillArrayData, + kListSuccessorBlocks, + kListPredecessors, + kNumListKinds +}; + +/* Type of growable bitmap for memory tuning */ +enum oatBitMapKind { + kBitMapMisc = 0, + kBitMapUse, + kBitMapDef, + kBitMapLiveIn, + kBitMapBMatrix, + kBitMapDominators, + kBitMapIDominated, + kBitMapDomFrontier, + kBitMapPhi, + kBitMapTmpBlocks, + kBitMapInputBlocks, + kBitMapRegisterV, + kBitMapTempSSARegisterV, + kBitMapNullCheck, + kBitMapTmpBlockV, + kBitMapPredecessors, + kNumBitMapKinds +}; + /* Allocate the initial memory block for arena-based allocation */ bool oatHeapInit(CompilationUnit* cUnit); @@ -66,9 +125,9 @@ struct GrowableListIterator { * All operations on a BitVector are unsynchronized. */ struct ArenaBitVector { - bool expandable; /* expand bitmap if we run out? */ - u4 storageSize; /* current size, in 32-bit words */ - u4* storage; + bool expandable; /* expand bitmap if we run out? */ + uint32_t storageSize; /* current size, in 32-bit words */ + uint32_t* storage; #ifdef WITH_MEMSTATS oatBitMapKind kind; /* for memory use tuning */ #endif @@ -77,8 +136,8 @@ struct ArenaBitVector { /* Handy iterator to walk through the bit positions set to 1 */ struct ArenaBitVectorIterator { ArenaBitVector* pBits; - u4 idx; - u4 bitSize; + uint32_t idx; + uint32_t bitSize; }; #define GET_ELEM_N(LIST, TYPE, N) (((TYPE*) LIST->elemList)[N]) @@ -125,7 +184,7 @@ bool oatTestBitVectors(const ArenaBitVector* src1, const ArenaBitVector* src2); int oatCountSetBits(const ArenaBitVector* pBits); void oatDumpLIRInsn(CompilationUnit* cUnit, LIR* lir, unsigned char* baseAddr); -void oatDumpResourceMask(LIR* lir, u8 mask, const char* prefix); +void oatDumpResourceMask(LIR* lir, uint64_t mask, const char* prefix); void oatDumpBlockBitVector(const GrowableList* blocks, char* msg, const ArenaBitVector* bv, int length); void oatGetBlockName(BasicBlock* bb, char* name); diff --git a/src/compiler/dalvik.h b/src/compiler/dalvik.h deleted file mode 100644 index 7ceb81788a..0000000000 --- a/src/compiler/dalvik.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * Common defines for all Dalvik code. - */ -#ifndef DALVIK_COMMON_H_ -#define DALVIK_COMMON_H_ - -#include <assert.h> -#include <stdbool.h> -#include <stdint.h> -#include <stdio.h> - -#include "gc/card_table.h" -#include "class_linker.h" -#include "compiler.h" -#include "dex_cache.h" -#include "logging.h" -#include "monitor.h" -#include "object.h" -#include "thread.h" -#include "utils.h" - -// From Common.h -typedef uint8_t u1; -typedef uint16_t u2; -typedef uint32_t u4; -typedef uint64_t u8; -typedef int8_t s1; -typedef int16_t s2; -typedef int32_t s4; -typedef int64_t s8; -typedef unsigned long long u8; - -#include "frontend.h" - -#endif diff --git a/src/compiler/dataflow.cc b/src/compiler/dataflow.cc index a20a428013..65068ed317 100644 --- a/src/compiler/dataflow.cc +++ b/src/compiler/dataflow.cc @@ -14,7 +14,7 @@ * limitations under the License. */ -#include "dalvik.h" +#include "compiler_internals.h" #include "dataflow.h" namespace art { diff --git a/src/compiler/dataflow.h b/src/compiler/dataflow.h index 44f40c3e72..ff15939ce0 100644 --- a/src/compiler/dataflow.h +++ b/src/compiler/dataflow.h @@ -17,7 +17,6 @@ #ifndef ART_SRC_COMPILER_DATAFLOW_H_ #define ART_SRC_COMPILER_DATAFLOW_H_ -#include "dalvik.h" #include "compiler_internals.h" namespace art { @@ -158,19 +157,25 @@ struct LoopInfo { ArenaBitVector* blocks; }; -void oatMethodLoopDetection(CompilationUnit*); - -void oatMethodUseCount(CompilationUnit*); - -void oatMethodNullCheckElimination(CompilationUnit*); - -void oatDumpCheckStats(CompilationUnit*); - -void oatMethodBasicBlockCombine(CompilationUnit*); - -void oatMethodCodeLayout(CompilationUnit*); - -void oatMethodBasicBlockOptimization(CompilationUnit*); +int SRegToVReg(const CompilationUnit* cUnit, int ssaReg); +char* oatGetDalvikDisassembly(CompilationUnit* cUnit, const DecodedInstruction& insn, const char* note); +char* oatFullDisassembler(CompilationUnit* cUnit, const MIR* mir); +char* oatGetSSAString(CompilationUnit* cUnit, SSARepresentation* ssaRep); +bool oatFindLocalLiveIn(CompilationUnit* cUnit, BasicBlock* bb); +bool oatDoSSAConversion(CompilationUnit* cUnit, BasicBlock* bb); +bool oatDoConstantPropagation(CompilationUnit* cUnit, BasicBlock* bb); +void oatInitializeSSAConversion(CompilationUnit* cUnit); +bool oatClearVisitedFlag(struct CompilationUnit* cUnit, struct BasicBlock* bb); +void oatDataFlowAnalysisDispatcher(CompilationUnit* cUnit, bool (*func)(CompilationUnit*, BasicBlock*), DataFlowAnalysisMode dfaMode, bool isIterative); +MIR* oatFindMoveResult(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir); +void oatMethodNullCheckElimination(CompilationUnit *cUnit); +void oatMethodBasicBlockCombine(CompilationUnit* cUnit); +void oatMethodCodeLayout(CompilationUnit* cUnit); +void oatDumpCheckStats(CompilationUnit *cUnit); +void oatMethodBasicBlockOptimization(CompilationUnit *cUnit); +void oatDumpLoops(CompilationUnit *cUnit); +void oatMethodLoopDetection(CompilationUnit *cUnit); +void oatMethodUseCount(CompilationUnit *cUnit); } // namespace art diff --git a/src/compiler/frontend.cc b/src/compiler/frontend.cc index d753cec3e0..134aaa7f32 100644 --- a/src/compiler/frontend.cc +++ b/src/compiler/frontend.cc @@ -14,12 +14,16 @@ * limitations under the License. */ -#include "dalvik.h" +#include "compiler.h" #include "compiler_internals.h" #include "dataflow.h" +#include "ssa_transformation.h" #include "leb128.h" #include "object.h" #include "runtime.h" +#include "codegen/codegen_util.h" +#include "codegen/method_bitcode.h" +#include "codegen/method_codegen_driver.h" #include <llvm/Support/Threading.h> @@ -94,8 +98,8 @@ static uint32_t kCompilerDebugFlags = 0 | // Enable debug/testing modes //(1 << kDebugVerifyBitcode) | 0; -inline bool contentIsInsn(const u2* codePtr) { - u2 instr = *codePtr; +inline bool contentIsInsn(const uint16_t* codePtr) { + uint16_t instr = *codePtr; Instruction::Code opcode = (Instruction::Code)(instr & 0xff); /* @@ -108,7 +112,7 @@ inline bool contentIsInsn(const u2* codePtr) { /* * Parse an instruction, return the length of the instruction */ -inline int parseInsn(CompilationUnit* cUnit, const u2* codePtr, +inline int parseInsn(CompilationUnit* cUnit, const uint16_t* codePtr, DecodedInstruction* decoded_instruction, bool printMe) { // Don't parse instruction data @@ -511,7 +515,7 @@ void processTryCatchBlocks(CompilationUnit* cUnit) /* Process instructions with the kBranch flag */ BasicBlock* processCanBranch(CompilationUnit* cUnit, BasicBlock* curBlock, MIR* insn, int curOffset, int width, int flags, - const u2* codePtr, const u2* codeEnd) + const uint16_t* codePtr, const uint16_t* codeEnd) { int target = curOffset; switch (insn->dalvikInsn.opcode) { @@ -595,7 +599,7 @@ BasicBlock* processCanBranch(CompilationUnit* cUnit, BasicBlock* curBlock, void processCanSwitch(CompilationUnit* cUnit, BasicBlock* curBlock, MIR* insn, int curOffset, int width, int flags) { - u2* switchData= (u2 *) (cUnit->insns + curOffset + insn->dalvikInsn.vB); + uint16_t* switchData= (uint16_t*) (cUnit->insns + curOffset + insn->dalvikInsn.vB); int size; int* keyTable; int* targetTable; @@ -684,8 +688,8 @@ void processCanSwitch(CompilationUnit* cUnit, BasicBlock* curBlock, /* Process instructions with the kThrow flag */ BasicBlock* processCanThrow(CompilationUnit* cUnit, BasicBlock* curBlock, MIR* insn, int curOffset, int width, int flags, - ArenaBitVector* tryBlockAddr, const u2* codePtr, - const u2* codeEnd) + ArenaBitVector* tryBlockAddr, const uint16_t* codePtr, + const uint16_t* codeEnd) { const DexFile::CodeItem* code_item = cUnit->code_item; bool inTryBlock = oatIsBitSet(tryBlockAddr, curOffset); @@ -792,8 +796,8 @@ CompiledMethod* compileMethod(Compiler& compiler, { VLOG(compiler) << "Compiling " << PrettyMethod(method_idx, dex_file) << "..."; - const u2* codePtr = code_item->insns_; - const u2* codeEnd = code_item->insns_ + code_item->insns_size_in_code_units_; + const uint16_t* codePtr = code_item->insns_; + const uint16_t* codeEnd = code_item->insns_ + code_item->insns_size_in_code_units_; int numBlocks = 0; unsigned int curOffset = 0; diff --git a/src/compiler/frontend.h b/src/compiler/frontend.h index 11214cf971..049d9d4df0 100644 --- a/src/compiler/frontend.h +++ b/src/compiler/frontend.h @@ -64,62 +64,6 @@ enum optControlVector { kPromoteCompilerTemps, }; -/* Type of allocation for memory tuning */ -enum oatAllocKind { - kAllocMisc, - kAllocBB, - kAllocLIR, - kAllocMIR, - kAllocDFInfo, - kAllocGrowableList, - kAllocGrowableBitMap, - kAllocDalvikToSSAMap, - kAllocDebugInfo, - kAllocSuccessor, - kAllocRegAlloc, - kAllocData, - kAllocPredecessors, - kNumAllocKinds -}; - -/* Type of growable list for memory tuning */ -enum oatListKind { - kListMisc = 0, - kListBlockList, - kListSSAtoDalvikMap, - kListDfsOrder, - kListDfsPostOrder, - kListDomPostOrderTraversal, - kListThrowLaunchPads, - kListSuspendLaunchPads, - kListSwitchTables, - kListFillArrayData, - kListSuccessorBlocks, - kListPredecessors, - kNumListKinds -}; - -/* Type of growable bitmap for memory tuning */ -enum oatBitMapKind { - kBitMapMisc = 0, - kBitMapUse, - kBitMapDef, - kBitMapLiveIn, - kBitMapBMatrix, - kBitMapDominators, - kBitMapIDominated, - kBitMapDomFrontier, - kBitMapPhi, - kBitMapTmpBlocks, - kBitMapInputBlocks, - kBitMapRegisterV, - kBitMapTempSSARegisterV, - kBitMapNullCheck, - kBitMapTmpBlockV, - kBitMapPredecessors, - kNumBitMapKinds -}; - /* Force code generation paths for testing */ enum debugControlVector { kDebugDisplayMissingTargets, @@ -201,40 +145,9 @@ class LLVMInfo { struct CompilationUnit; struct BasicBlock; -struct SSARepresentation; -struct GrowableList; -struct MIR; - -void oatInit(CompilationUnit* cUnit, const Compiler& compiler); -bool oatArchInit(void); -bool oatStartup(void); -void oatShutdown(void); -void oatScanAllClassPointers(void (*callback)(void* ptr)); -void oatInitializeSSAConversion(CompilationUnit* cUnit); -int SRegToVReg(const CompilationUnit* cUnit, int ssaReg); -int SRegToSubscript(const CompilationUnit* cUnit, int ssaReg); -bool oatFindLocalLiveIn(CompilationUnit* cUnit, BasicBlock* bb); -bool oatDoSSAConversion(CompilationUnit* cUnit, BasicBlock* bb); -bool oatDoConstantPropagation(CompilationUnit* cUnit, BasicBlock* bb); -bool oatFindInductionVariables(CompilationUnit* cUnit, BasicBlock* bb); -/* Clear the visited flag for each BB */ -bool oatClearVisitedFlag(CompilationUnit* cUnit, BasicBlock* bb); -char* oatGetDalvikDisassembly(CompilationUnit* cUnit, const DecodedInstruction& insn, - const char* note); -char* oatFullDisassembler(CompilationUnit* cUnit, const MIR* mir); -char* oatGetSSAString(CompilationUnit* cUnit, SSARepresentation* ssaRep); -void oatDataFlowAnalysisDispatcher(CompilationUnit* cUnit, - bool (*func)(CompilationUnit* , BasicBlock*), - DataFlowAnalysisMode dfaMode, - bool isIterative); -void oatMethodSSATransformation(CompilationUnit* cUnit); -u8 oatGetRegResourceMask(int reg); -void oatDumpCFG(CompilationUnit* cUnit, const char* dirPrefix); -void oatProcessSwitchTables(CompilationUnit* cUnit); -bool oatIsFpReg(int reg); -uint32_t oatFpRegMask(void); -void oatReplaceSpecialChars(std::string& str); + BasicBlock* oatFindBlock(CompilationUnit* cUnit, unsigned int codeOffset); +void oatReplaceSpecialChars(std::string& str); } // namespace art diff --git a/src/compiler/intermediate_rep.cc b/src/compiler/intermediate_rep.cc index 96bec22455..2c648d97e2 100644 --- a/src/compiler/intermediate_rep.cc +++ b/src/compiler/intermediate_rep.cc @@ -14,7 +14,6 @@ * limitations under the License. */ -#include "dalvik.h" #include "compiler_internals.h" namespace art { diff --git a/src/compiler/ralloc.cc b/src/compiler/ralloc.cc index d9c6a5716a..ffb7fecf68 100644 --- a/src/compiler/ralloc.cc +++ b/src/compiler/ralloc.cc @@ -14,10 +14,9 @@ * limitations under the License. */ -#include "dalvik.h" #include "compiler_internals.h" #include "dataflow.h" -#include "codegen/ralloc.h" +#include "codegen/ralloc_util.h" namespace art { diff --git a/src/compiler/ralloc.h b/src/compiler/ralloc.h new file mode 100644 index 0000000000..be94419bf7 --- /dev/null +++ b/src/compiler/ralloc.h @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ART_SRC_COMPILER_RALLOC_H_ +#define ART_SRC_COMPILER_RALLOC_H_ + +#include "compiler_internals.h" + +namespace art { + +void oatSimpleRegAlloc(CompilationUnit* cUnit); + +} // namespace art + +#endif // ART_SRC_COMPILER_RALLOC_H_ diff --git a/src/compiler/ssa_transformation.cc b/src/compiler/ssa_transformation.cc index 09562faa59..e689f6a247 100644 --- a/src/compiler/ssa_transformation.cc +++ b/src/compiler/ssa_transformation.cc @@ -14,7 +14,7 @@ * limitations under the License. */ -#include "dalvik.h" +#include "compiler_internals.h" #include "dataflow.h" namespace art { diff --git a/src/compiler/ssa_transformation.h b/src/compiler/ssa_transformation.h new file mode 100644 index 0000000000..4c3ceb3a75 --- /dev/null +++ b/src/compiler/ssa_transformation.h @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ART_SRC_COMPILER_SSATRANSFORMATION_H_ +#define ART_SRC_COMPILER_SSATRANSFORMATION_H_ + +#include "compiler_internals.h" + +namespace art { + +void oatMethodSSATransformation(CompilationUnit* cUnit); + +} // namespace art + +#endif // ART_SRC_COMPILER_DATAFLOW_H_ |