Merge "Fix heap bitmap rounding down size error" into ics-mr1-plus-art
diff --git a/src/compiler/Compiler.h b/src/compiler/Compiler.h
index 4d749ce..088768b 100644
--- a/src/compiler/Compiler.h
+++ b/src/compiler/Compiler.h
@@ -197,6 +197,7 @@
bool oatIsFpReg(int reg);
uint32_t oatFpRegMask(void);
void oatReplaceSpecialChars(std::string& str);
+BasicBlock* oatFindBlock(CompilationUnit* cUnit, unsigned int codeOffset);
} // namespace art
diff --git a/src/compiler/Frontend.cc b/src/compiler/Frontend.cc
index b714065..9fa6911 100644
--- a/src/compiler/Frontend.cc
+++ b/src/compiler/Frontend.cc
@@ -246,6 +246,12 @@
return bb;
}
+/* Find existing block */
+BasicBlock* oatFindBlock(CompilationUnit* cUnit, unsigned int codeOffset)
+{
+ return findBlock(cUnit, codeOffset, false, false, NULL);
+}
+
/* Turn method name into a legal Linux file name */
void oatReplaceSpecialChars(std::string& str)
{
@@ -781,7 +787,7 @@
|| (PrettyMethod(method_idx, dex_file).find("FloatMath") != std::string::npos)
|| (PrettyMethod(method_idx, dex_file).find("Goto") != std::string::npos)
|| (PrettyMethod(method_idx, dex_file).find("InternedString") != std::string::npos)
- // || (PrettyMethod(method_idx, dex_file).find("IntMath") != std::string::npos)
+ || (PrettyMethod(method_idx, dex_file).find("IntMath") != std::string::npos)
|| (PrettyMethod(method_idx, dex_file).find("InstField") != std::string::npos)
|| (PrettyMethod(method_idx, dex_file).find("MethodCall") != std::string::npos)
|| (PrettyMethod(method_idx, dex_file).find("Monitor") != std::string::npos)
diff --git a/src/compiler/codegen/MethodBitcode.cc b/src/compiler/codegen/MethodBitcode.cc
index a4521bb..71921d0 100644
--- a/src/compiler/codegen/MethodBitcode.cc
+++ b/src/compiler/codegen/MethodBitcode.cc
@@ -140,6 +140,38 @@
return GET_ELEM_N(cUnit->ssaStrings, char*, ssaReg);
}
+llvm::BasicBlock* findCaseTarget(CompilationUnit* cUnit, uint32_t vaddr)
+{
+ BasicBlock* bb = oatFindBlock(cUnit, vaddr);
+ DCHECK(bb != NULL);
+ return getLLVMBlock(cUnit, bb->id);
+}
+
+void convertPackedSwitch(CompilationUnit* cUnit, BasicBlock* bb,
+ int32_t tableOffset, RegLocation rlSrc)
+{
+ const Instruction::PackedSwitchPayload* payload =
+ reinterpret_cast<const Instruction::PackedSwitchPayload*>(
+ cUnit->insns + cUnit->currentDalvikOffset + tableOffset);
+
+ llvm::Value* value = getLLVMValue(cUnit, rlSrc.origSReg);
+
+ llvm::SwitchInst* sw =
+ cUnit->irb->CreateSwitch(value, getLLVMBlock(cUnit, bb->fallThrough->id),
+ payload->case_count);
+
+ for (uint16_t i = 0; i < payload->case_count; ++i) {
+ llvm::BasicBlock* llvmBB =
+ findCaseTarget(cUnit, cUnit->currentDalvikOffset + payload->targets[i]);
+ sw->addCase(cUnit->irb->getInt32(payload->first_key + i), llvmBB);
+ }
+ llvm::MDNode* switchNode =
+ llvm::MDNode::get(*cUnit->context, cUnit->irb->getInt32(tableOffset));
+ sw->setMetadata("SwitchTable", switchNode);
+ bb->taken = NULL;
+ bb->fallThrough = NULL;
+}
+
void convertSget(CompilationUnit* cUnit, int32_t fieldIndex,
greenland::IntrinsicHelper::IntrinsicId id,
RegLocation rlDest)
@@ -1501,11 +1533,12 @@
rlDest, rlSrc[0], rlSrc[1]);
break;
-#if 0
case Instruction::PACKED_SWITCH:
- genPackedSwitch(cUnit, vB, rlSrc[0]);
+ convertPackedSwitch(cUnit, bb, vB, rlSrc[0]);
break;
+#if 0
+
case Instruction::SPARSE_SWITCH:
genSparseSwitch(cUnit, vB, rlSrc[0], labelList);
break;
@@ -2138,12 +2171,17 @@
{
RegLocation rlDest = getLoc(cUnit, inst);
llvm::Value* lhs = inst->getOperand(0);
- // Special-case RSUB
+ // Special-case RSUB/NEG
llvm::ConstantInt* lhsImm = llvm::dyn_cast<llvm::ConstantInt>(lhs);
if ((op == kOpSub) && (lhsImm != NULL)) {
RegLocation rlSrc1 = getLoc(cUnit, inst->getOperand(1));
- genArithOpIntLit(cUnit, Instruction::RSUB_INT, rlDest, rlSrc1,
- lhsImm->getSExtValue());
+ if (rlSrc1.wide) {
+ DCHECK_EQ(lhsImm->getSExtValue(), 0);
+ genArithOpLong(cUnit, Instruction::NEG_LONG, rlDest, rlSrc1, rlSrc1);
+ } else {
+ genArithOpIntLit(cUnit, Instruction::RSUB_INT, rlDest, rlSrc1,
+ lhsImm->getSExtValue());
+ }
return;
}
DCHECK(lhsImm == NULL);
@@ -2560,6 +2598,20 @@
genCmpLong(cUnit, rlDest, rlSrc1, rlSrc2);
}
+void cvtSwitch(CompilationUnit* cUnit, llvm::Instruction* inst)
+{
+ llvm::SwitchInst* swInst = llvm::dyn_cast<llvm::SwitchInst>(inst);
+ DCHECK(swInst != NULL);
+ llvm::Value* testVal = swInst->getCondition();
+ llvm::MDNode* tableOffsetNode = swInst->getMetadata("SwitchTable");
+ DCHECK(tableOffsetNode != NULL);
+ llvm::ConstantInt* tableOffsetValue =
+ static_cast<llvm::ConstantInt*>(tableOffsetNode->getOperand(0));
+ int32_t tableOffset = tableOffsetValue->getSExtValue();
+ RegLocation rlSrc = getLoc(cUnit, testVal);
+ genPackedSwitch(cUnit, tableOffset, rlSrc);
+}
+
void cvtInvoke(CompilationUnit* cUnit, llvm::CallInst* callInst,
bool isVoid, bool isFilledNewArray)
{
@@ -2999,6 +3051,8 @@
case llvm::Instruction::SExt: cvtIntExt(cUnit, inst, true /* signed */);
break;
+ case llvm::Instruction::Switch: cvtSwitch(cUnit, inst); break;
+
case llvm::Instruction::Unreachable:
break; // FIXME: can we really ignore these?
@@ -3007,7 +3061,6 @@
case llvm::Instruction::UIToFP:
case llvm::Instruction::PtrToInt:
case llvm::Instruction::IntToPtr:
- case llvm::Instruction::Switch:
case llvm::Instruction::FCmp:
case llvm::Instruction::URem:
case llvm::Instruction::UDiv: