summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/CompilerIR.h3
-rw-r--r--src/compiler/Dataflow.cc64
-rw-r--r--src/compiler/Dataflow.h2
-rw-r--r--src/compiler/Frontend.cc6
-rw-r--r--src/compiler/codegen/MethodBitcode.cc920
5 files changed, 537 insertions, 458 deletions
diff --git a/src/compiler/CompilerIR.h b/src/compiler/CompilerIR.h
index 1cbf2b5f19..87dbd096c0 100644
--- a/src/compiler/CompilerIR.h
+++ b/src/compiler/CompilerIR.h
@@ -280,6 +280,8 @@ struct BasicBlock {
bool visited;
bool hidden;
bool catchEntry;
+ bool explicitThrow;
+ bool conditionalBranch;
#if defined(ART_USE_QUICK_COMPILER)
bool hasReturn;
#endif
@@ -611,6 +613,7 @@ struct CompilationUnit {
bool requireShadowFrame;
int numShadowFrameEntries;
int* shadowMap;
+ std::set<llvm::BasicBlock*> llvmBlocks;
#endif
#ifndef NDEBUG
/*
diff --git a/src/compiler/Dataflow.cc b/src/compiler/Dataflow.cc
index a5cdbdeaaa..6fe0659eb6 100644
--- a/src/compiler/Dataflow.cc
+++ b/src/compiler/Dataflow.cc
@@ -1970,6 +1970,54 @@ bool countChecks( struct CompilationUnit* cUnit, struct BasicBlock* bb)
return false;
}
+/* Try to make common case the fallthrough path */
+bool layoutBlocks(struct CompilationUnit* cUnit, struct BasicBlock* bb)
+{
+ // TODO: For now, just looking for direct throws. Consider generalizing for profile feedback
+ if (!bb->explicitThrow) {
+ return false;
+ }
+ BasicBlock* walker = bb;
+ while (true) {
+ // Check termination conditions
+ if ((walker->blockType == kEntryBlock) || (walker->predecessors->numUsed != 1)) {
+ break;
+ }
+ BasicBlock* prev = GET_ELEM_N(walker->predecessors, BasicBlock*, 0);
+ if (prev->conditionalBranch) {
+ if (prev->fallThrough == walker) {
+ // Already done - return
+ break;
+ }
+ DCHECK_EQ(walker, prev->taken);
+ // Got one. Flip it and exit
+ Instruction::Code opcode = prev->lastMIRInsn->dalvikInsn.opcode;
+ switch (opcode) {
+ case Instruction::IF_EQ: opcode = Instruction::IF_NE; break;
+ case Instruction::IF_NE: opcode = Instruction::IF_EQ; break;
+ case Instruction::IF_LT: opcode = Instruction::IF_GE; break;
+ case Instruction::IF_GE: opcode = Instruction::IF_LT; break;
+ case Instruction::IF_GT: opcode = Instruction::IF_LE; break;
+ case Instruction::IF_LE: opcode = Instruction::IF_GT; break;
+ case Instruction::IF_EQZ: opcode = Instruction::IF_NEZ; break;
+ case Instruction::IF_NEZ: opcode = Instruction::IF_EQZ; break;
+ case Instruction::IF_LTZ: opcode = Instruction::IF_GEZ; break;
+ case Instruction::IF_GEZ: opcode = Instruction::IF_LTZ; break;
+ case Instruction::IF_GTZ: opcode = Instruction::IF_LEZ; break;
+ case Instruction::IF_LEZ: opcode = Instruction::IF_GTZ; break;
+ default: LOG(FATAL) << "Unexpected opcode 0x" << std::hex << (int)opcode;
+ }
+ prev->lastMIRInsn->dalvikInsn.opcode = opcode;
+ BasicBlock* tBB = prev->taken;
+ prev->taken = prev->fallThrough;
+ prev->fallThrough = tBB;
+ break;
+ }
+ walker = prev;
+ }
+ return false;
+}
+
/* Combine any basic blocks terminated by instructions that we now know can't throw */
bool combineBlocks(struct CompilationUnit* cUnit, struct BasicBlock* bb)
{
@@ -1992,9 +2040,14 @@ bool combineBlocks(struct CompilationUnit* cUnit, struct BasicBlock* bb)
// Grab the attributes from the paired opcode
MIR* throwInsn = mir->meta.throwInsn;
int dfAttributes = oatDataFlowAttributes[throwInsn->dalvikInsn.opcode];
- // Only null checks, and null checks eliminated?
- if (((dfAttributes & DF_HAS_NULL_CHKS) == 0) || ((dfAttributes & DF_HAS_RANGE_CHKS) != 0)
- || !(throwInsn->optimizationFlags & MIR_IGNORE_NULL_CHECK)) {
+ bool canCombine = true;
+ if (dfAttributes & DF_HAS_NULL_CHKS) {
+ canCombine &= ((throwInsn->optimizationFlags & MIR_IGNORE_NULL_CHECK) != 0);
+ }
+ if (dfAttributes & DF_HAS_RANGE_CHKS) {
+ canCombine &= ((throwInsn->optimizationFlags & MIR_IGNORE_RANGE_CHECK) != 0);
+ }
+ if (!canCombine) {
break;
}
// OK - got one. Combine
@@ -2180,6 +2233,11 @@ void oatMethodBasicBlockCombine(CompilationUnit* cUnit)
oatDataFlowAnalysisDispatcher(cUnit, combineBlocks, kPreOrderDFSTraversal, false);
}
+void oatMethodCodeLayout(CompilationUnit* cUnit)
+{
+ oatDataFlowAnalysisDispatcher(cUnit, layoutBlocks, kAllNodes, false);
+}
+
void oatDumpCheckStats(CompilationUnit *cUnit)
{
Checkstats* stats = (Checkstats*)oatNew(cUnit, sizeof(Checkstats), true, kAllocDFInfo);
diff --git a/src/compiler/Dataflow.h b/src/compiler/Dataflow.h
index e2d5a4c50a..8e99e4dffe 100644
--- a/src/compiler/Dataflow.h
+++ b/src/compiler/Dataflow.h
@@ -168,6 +168,8 @@ void oatDumpCheckStats(CompilationUnit*);
void oatMethodBasicBlockCombine(CompilationUnit*);
+void oatMethodCodeLayout(CompilationUnit*);
+
void oatMethodBasicBlockOptimization(CompilationUnit*);
} // namespace art
diff --git a/src/compiler/Frontend.cc b/src/compiler/Frontend.cc
index 4aa0ac89e9..50630aea06 100644
--- a/src/compiler/Frontend.cc
+++ b/src/compiler/Frontend.cc
@@ -519,6 +519,7 @@ BasicBlock* processCanBranch(CompilationUnit* cUnit, BasicBlock* curBlock,
case Instruction::IF_GE:
case Instruction::IF_GT:
case Instruction::IF_LE:
+ curBlock->conditionalBranch = true;
target += (int) insn->dalvikInsn.vC;
break;
case Instruction::IF_EQZ:
@@ -527,6 +528,7 @@ BasicBlock* processCanBranch(CompilationUnit* cUnit, BasicBlock* curBlock,
case Instruction::IF_GEZ:
case Instruction::IF_GTZ:
case Instruction::IF_LEZ:
+ curBlock->conditionalBranch = true;
target += (int) insn->dalvikInsn.vB;
break;
default:
@@ -720,6 +722,7 @@ BasicBlock* processCanThrow(CompilationUnit* cUnit, BasicBlock* curBlock,
}
if (insn->dalvikInsn.opcode == Instruction::THROW){
+ curBlock->explicitThrow = true;
if ((codePtr < codeEnd) && contentIsInsn(codePtr)) {
// Force creation of new block following THROW via side-effect
findBlock(cUnit, curOffset + width, /* split */ false,
@@ -1074,6 +1077,9 @@ CompiledMethod* oatCompileMethod(Compiler& compiler,
oatDumpCompilationUnit(cUnit.get());
}
+ /* Do a code layout pass */
+ oatMethodCodeLayout(cUnit.get());
+
if (cUnit->enableDebug & (1 << kDebugVerifyDataflow)) {
/* Verify if all blocks are connected as claimed */
oatDataFlowAnalysisDispatcher(cUnit.get(), verifyPredInfo, kAllNodes,
diff --git a/src/compiler/codegen/MethodBitcode.cc b/src/compiler/codegen/MethodBitcode.cc
index c4e1b9ddf3..25aae113a8 100644
--- a/src/compiler/codegen/MethodBitcode.cc
+++ b/src/compiler/codegen/MethodBitcode.cc
@@ -160,10 +160,10 @@ void createLocFromValue(CompilationUnit* cUnit, llvm::Value* val)
if (cUnit->printMe && loc.home) {
if (loc.wide) {
- LOG(INFO) << "Promoted wide " << s << " to regs " << loc.lowReg
+ LOG(INFO) << "Promoted wide " << s << " to regs " << static_cast<int>(loc.lowReg)
<< "/" << loc.highReg;
} else {
- LOG(INFO) << "Promoted " << s << " to reg " << loc.lowReg;
+ LOG(INFO) << "Promoted " << s << " to reg " << static_cast<int>(loc.lowReg);
}
}
cUnit->locMap.Put(val, loc);
@@ -2856,475 +2856,485 @@ RegLocation valToLoc(CompilationUnit* cUnit, llvm::Value* val)
bool methodBitcodeBlockCodeGen(CompilationUnit* cUnit, llvm::BasicBlock* bb)
{
- bool isEntry = (bb == &cUnit->func->getEntryBlock());
- // Define the starting label
- LIR* blockLabel = cUnit->blockToLabelMap.Get(bb);
- // Extract the type and starting offset from the block's name
- char blockType = kNormalBlock;
- if (!isEntry) {
- const char* blockName = bb->getName().str().c_str();
- int dummy;
- sscanf(blockName, kLabelFormat, &blockType, &blockLabel->operands[0], &dummy);
- cUnit->currentDalvikOffset = blockLabel->operands[0];
- } else {
- cUnit->currentDalvikOffset = 0;
- }
- // Set the label kind
- blockLabel->opcode = kPseudoNormalBlockLabel;
- // Insert the label
- oatAppendLIR(cUnit, blockLabel);
-
- LIR* headLIR = NULL;
-
- if (blockType == kCatchBlock) {
- headLIR = newLIR0(cUnit, kPseudoSafepointPC);
- }
-
- // Free temp registers and reset redundant store tracking */
- oatResetRegPool(cUnit);
- oatResetDefTracking(cUnit);
+ while (cUnit->llvmBlocks.find(bb) == cUnit->llvmBlocks.end()) {
+ llvm::BasicBlock* nextBB = NULL;
+ cUnit->llvmBlocks.insert(bb);
+ bool isEntry = (bb == &cUnit->func->getEntryBlock());
+ // Define the starting label
+ LIR* blockLabel = cUnit->blockToLabelMap.Get(bb);
+ // Extract the type and starting offset from the block's name
+ char blockType = kNormalBlock;
+ if (!isEntry) {
+ const char* blockName = bb->getName().str().c_str();
+ int dummy;
+ sscanf(blockName, kLabelFormat, &blockType, &blockLabel->operands[0], &dummy);
+ cUnit->currentDalvikOffset = blockLabel->operands[0];
+ } else {
+ cUnit->currentDalvikOffset = 0;
+ }
+ // Set the label kind
+ blockLabel->opcode = kPseudoNormalBlockLabel;
+ // Insert the label
+ oatAppendLIR(cUnit, blockLabel);
- //TODO: restore oat incoming liveness optimization
- oatClobberAllRegs(cUnit);
+ LIR* headLIR = NULL;
- if (isEntry) {
- RegLocation* argLocs = (RegLocation*)
- oatNew(cUnit, sizeof(RegLocation) * cUnit->numIns, true, kAllocMisc);
- llvm::Function::arg_iterator it(cUnit->func->arg_begin());
- llvm::Function::arg_iterator it_end(cUnit->func->arg_end());
- // Skip past Method*
- it++;
- for (unsigned i = 0; it != it_end; ++it) {
- llvm::Value* val = it;
- argLocs[i++] = valToLoc(cUnit, val);
- llvm::Type* ty = val->getType();
- if ((ty == cUnit->irb->getInt64Ty()) || (ty == cUnit->irb->getDoubleTy())) {
- argLocs[i] = argLocs[i-1];
- argLocs[i].lowReg = argLocs[i].highReg;
- argLocs[i].origSReg++;
- argLocs[i].sRegLow = INVALID_SREG;
- argLocs[i].highWord = true;
- i++;
- }
- }
- genEntrySequence(cUnit, argLocs, cUnit->methodLoc);
- }
-
- // Visit all of the instructions in the block
- for (llvm::BasicBlock::iterator it = bb->begin(), e = bb->end(); it != e;) {
- llvm::Instruction* inst = it;
- llvm::BasicBlock::iterator nextIt = ++it;
- // Extract the Dalvik offset from the instruction
- uint32_t opcode = inst->getOpcode();
- llvm::MDNode* dexOffsetNode = inst->getMetadata("DexOff");
- if (dexOffsetNode != NULL) {
- llvm::ConstantInt* dexOffsetValue =
- static_cast<llvm::ConstantInt*>(dexOffsetNode->getOperand(0));
- cUnit->currentDalvikOffset = dexOffsetValue->getZExtValue();
+ if (blockType == kCatchBlock) {
+ headLIR = newLIR0(cUnit, kPseudoSafepointPC);
}
+ // Free temp registers and reset redundant store tracking */
oatResetRegPool(cUnit);
- if (cUnit->disableOpt & (1 << kTrackLiveTemps)) {
- oatClobberAllRegs(cUnit);
- }
-
- if (cUnit->disableOpt & (1 << kSuppressLoads)) {
- oatResetDefTracking(cUnit);
+ oatResetDefTracking(cUnit);
+
+ //TODO: restore oat incoming liveness optimization
+ oatClobberAllRegs(cUnit);
+
+ if (isEntry) {
+ RegLocation* argLocs = (RegLocation*)
+ oatNew(cUnit, sizeof(RegLocation) * cUnit->numIns, true, kAllocMisc);
+ llvm::Function::arg_iterator it(cUnit->func->arg_begin());
+ llvm::Function::arg_iterator it_end(cUnit->func->arg_end());
+ // Skip past Method*
+ it++;
+ for (unsigned i = 0; it != it_end; ++it) {
+ llvm::Value* val = it;
+ argLocs[i++] = valToLoc(cUnit, val);
+ llvm::Type* ty = val->getType();
+ if ((ty == cUnit->irb->getInt64Ty()) || (ty == cUnit->irb->getDoubleTy())) {
+ argLocs[i] = argLocs[i-1];
+ argLocs[i].lowReg = argLocs[i].highReg;
+ argLocs[i].origSReg++;
+ argLocs[i].sRegLow = INVALID_SREG;
+ argLocs[i].highWord = true;
+ i++;
+ }
+ }
+ genEntrySequence(cUnit, argLocs, cUnit->methodLoc);
}
-#ifndef NDEBUG
- /* Reset temp tracking sanity check */
- cUnit->liveSReg = INVALID_SREG;
-#endif
+ // Visit all of the instructions in the block
+ for (llvm::BasicBlock::iterator it = bb->begin(), e = bb->end(); it != e;) {
+ llvm::Instruction* inst = it;
+ llvm::BasicBlock::iterator nextIt = ++it;
+ // Extract the Dalvik offset from the instruction
+ uint32_t opcode = inst->getOpcode();
+ llvm::MDNode* dexOffsetNode = inst->getMetadata("DexOff");
+ if (dexOffsetNode != NULL) {
+ llvm::ConstantInt* dexOffsetValue =
+ static_cast<llvm::ConstantInt*>(dexOffsetNode->getOperand(0));
+ cUnit->currentDalvikOffset = dexOffsetValue->getZExtValue();
+ }
- // TODO: use llvm opcode name here instead of "boundary" if verbose
- LIR* boundaryLIR = markBoundary(cUnit, cUnit->currentDalvikOffset, "boundary");
+ oatResetRegPool(cUnit);
+ if (cUnit->disableOpt & (1 << kTrackLiveTemps)) {
+ oatClobberAllRegs(cUnit);
+ }
- /* Remember the first LIR for thisl block*/
- if (headLIR == NULL) {
- headLIR = boundaryLIR;
- headLIR->defMask = ENCODE_ALL;
- }
+ if (cUnit->disableOpt & (1 << kSuppressLoads)) {
+ oatResetDefTracking(cUnit);
+ }
- switch(opcode) {
+ #ifndef NDEBUG
+ /* Reset temp tracking sanity check */
+ cUnit->liveSReg = INVALID_SREG;
+ #endif
- case llvm::Instruction::ICmp: {
- llvm::Instruction* nextInst = nextIt;
- llvm::BranchInst* brInst = llvm::dyn_cast<llvm::BranchInst>(nextInst);
- if (brInst != NULL /* and... */) {
- cvtICmpBr(cUnit, inst, brInst);
- ++it;
- } else {
- cvtICmp(cUnit, inst);
- }
- }
- break;
+ // TODO: use llvm opcode name here instead of "boundary" if verbose
+ LIR* boundaryLIR = markBoundary(cUnit, cUnit->currentDalvikOffset, "boundary");
- case llvm::Instruction::Call: {
- llvm::CallInst* callInst = llvm::dyn_cast<llvm::CallInst>(inst);
- llvm::Function* callee = callInst->getCalledFunction();
- greenland::IntrinsicHelper::IntrinsicId id =
- cUnit->intrinsic_helper->GetIntrinsicId(callee);
- switch (id) {
- case greenland::IntrinsicHelper::AllocaShadowFrame:
- case greenland::IntrinsicHelper::SetShadowFrameEntry:
- case greenland::IntrinsicHelper::PopShadowFrame:
- // Ignore shadow frame stuff for quick compiler
- break;
- case greenland::IntrinsicHelper::CopyInt:
- case greenland::IntrinsicHelper::CopyObj:
- case greenland::IntrinsicHelper::CopyFloat:
- case greenland::IntrinsicHelper::CopyLong:
- case greenland::IntrinsicHelper::CopyDouble:
- cvtCopy(cUnit, callInst);
- break;
- case greenland::IntrinsicHelper::ConstInt:
- case greenland::IntrinsicHelper::ConstObj:
- case greenland::IntrinsicHelper::ConstLong:
- case greenland::IntrinsicHelper::ConstFloat:
- case greenland::IntrinsicHelper::ConstDouble:
- cvtConst(cUnit, callInst);
- break;
- case greenland::IntrinsicHelper::DivInt:
- case greenland::IntrinsicHelper::DivLong:
- cvtBinOp(cUnit, kOpDiv, inst);
- break;
- case greenland::IntrinsicHelper::RemInt:
- case greenland::IntrinsicHelper::RemLong:
- cvtBinOp(cUnit, kOpRem, inst);
- break;
- case greenland::IntrinsicHelper::MethodInfo:
- // Already dealt with - just ignore it here.
- break;
- case greenland::IntrinsicHelper::CheckSuspend:
- genSuspendTest(cUnit, 0 /* optFlags already applied */);
- break;
- case greenland::IntrinsicHelper::HLInvokeObj:
- case greenland::IntrinsicHelper::HLInvokeFloat:
- case greenland::IntrinsicHelper::HLInvokeDouble:
- case greenland::IntrinsicHelper::HLInvokeLong:
- case greenland::IntrinsicHelper::HLInvokeInt:
- cvtInvoke(cUnit, callInst, false /* isVoid */, false /* newArray */);
- break;
- case greenland::IntrinsicHelper::HLInvokeVoid:
- cvtInvoke(cUnit, callInst, true /* isVoid */, false /* newArray */);
- break;
- case greenland::IntrinsicHelper::FilledNewArray:
- cvtInvoke(cUnit, callInst, false /* isVoid */, true /* newArray */);
- break;
- case greenland::IntrinsicHelper::FillArrayData:
- cvtFillArrayData(cUnit, callInst);
- break;
- case greenland::IntrinsicHelper::ConstString:
- cvtConstObject(cUnit, callInst, true /* isString */);
- break;
- case greenland::IntrinsicHelper::ConstClass:
- cvtConstObject(cUnit, callInst, false /* isString */);
- break;
- case greenland::IntrinsicHelper::CheckCast:
- cvtCheckCast(cUnit, callInst);
- break;
- case greenland::IntrinsicHelper::NewInstance:
- cvtNewInstance(cUnit, callInst);
- break;
- case greenland::IntrinsicHelper::HLSgetObject:
- cvtSget(cUnit, callInst, false /* wide */, true /* Object */);
- break;
- case greenland::IntrinsicHelper::HLSget:
- case greenland::IntrinsicHelper::HLSgetFloat:
- case greenland::IntrinsicHelper::HLSgetBoolean:
- case greenland::IntrinsicHelper::HLSgetByte:
- case greenland::IntrinsicHelper::HLSgetChar:
- case greenland::IntrinsicHelper::HLSgetShort:
- cvtSget(cUnit, callInst, false /* wide */, false /* Object */);
- break;
- case greenland::IntrinsicHelper::HLSgetWide:
- case greenland::IntrinsicHelper::HLSgetDouble:
- cvtSget(cUnit, callInst, true /* wide */, false /* Object */);
- break;
- case greenland::IntrinsicHelper::HLSput:
- case greenland::IntrinsicHelper::HLSputFloat:
- case greenland::IntrinsicHelper::HLSputBoolean:
- case greenland::IntrinsicHelper::HLSputByte:
- case greenland::IntrinsicHelper::HLSputChar:
- case greenland::IntrinsicHelper::HLSputShort:
- cvtSput(cUnit, callInst, false /* wide */, false /* Object */);
- break;
- case greenland::IntrinsicHelper::HLSputWide:
- case greenland::IntrinsicHelper::HLSputDouble:
- cvtSput(cUnit, callInst, true /* wide */, false /* Object */);
- break;
- case greenland::IntrinsicHelper::HLSputObject:
- cvtSput(cUnit, callInst, false /* wide */, true /* Object */);
- break;
- case greenland::IntrinsicHelper::GetException:
- cvtMoveException(cUnit, callInst);
- break;
- case greenland::IntrinsicHelper::Throw:
- cvtThrow(cUnit, callInst);
- break;
- case greenland::IntrinsicHelper::MonitorEnter:
- cvtMonitorEnterExit(cUnit, true /* isEnter */, callInst);
- break;
- case greenland::IntrinsicHelper::MonitorExit:
- cvtMonitorEnterExit(cUnit, false /* isEnter */, callInst);
- break;
- case greenland::IntrinsicHelper::ArrayLength:
- cvtArrayLength(cUnit, callInst);
- break;
- case greenland::IntrinsicHelper::NewArray:
- cvtNewArray(cUnit, callInst);
- break;
- case greenland::IntrinsicHelper::InstanceOf:
- cvtInstanceOf(cUnit, callInst);
- break;
-
- case greenland::IntrinsicHelper::HLArrayGet:
- case greenland::IntrinsicHelper::HLArrayGetObject:
- case greenland::IntrinsicHelper::HLArrayGetFloat:
- cvtAget(cUnit, callInst, kWord, 2);
- break;
- case greenland::IntrinsicHelper::HLArrayGetWide:
- case greenland::IntrinsicHelper::HLArrayGetDouble:
- cvtAget(cUnit, callInst, kLong, 3);
- break;
- case greenland::IntrinsicHelper::HLArrayGetBoolean:
- cvtAget(cUnit, callInst, kUnsignedByte, 0);
- break;
- case greenland::IntrinsicHelper::HLArrayGetByte:
- cvtAget(cUnit, callInst, kSignedByte, 0);
- break;
- case greenland::IntrinsicHelper::HLArrayGetChar:
- cvtAget(cUnit, callInst, kUnsignedHalf, 1);
- break;
- case greenland::IntrinsicHelper::HLArrayGetShort:
- cvtAget(cUnit, callInst, kSignedHalf, 1);
- break;
-
- case greenland::IntrinsicHelper::HLArrayPut:
- case greenland::IntrinsicHelper::HLArrayPutFloat:
- cvtAputPrimitive(cUnit, callInst, kWord, 2);
- break;
- case greenland::IntrinsicHelper::HLArrayPutObject:
- cvtAputObj(cUnit, callInst);
- break;
- case greenland::IntrinsicHelper::HLArrayPutWide:
- case greenland::IntrinsicHelper::HLArrayPutDouble:
- cvtAputPrimitive(cUnit, callInst, kLong, 3);
- break;
- case greenland::IntrinsicHelper::HLArrayPutBoolean:
- cvtAputPrimitive(cUnit, callInst, kUnsignedByte, 0);
- break;
- case greenland::IntrinsicHelper::HLArrayPutByte:
- cvtAputPrimitive(cUnit, callInst, kSignedByte, 0);
- break;
- case greenland::IntrinsicHelper::HLArrayPutChar:
- cvtAputPrimitive(cUnit, callInst, kUnsignedHalf, 1);
- break;
- case greenland::IntrinsicHelper::HLArrayPutShort:
- cvtAputPrimitive(cUnit, callInst, kSignedHalf, 1);
- break;
-
- case greenland::IntrinsicHelper::HLIGet:
- case greenland::IntrinsicHelper::HLIGetFloat:
- cvtIget(cUnit, callInst, kWord, false /* isWide */, false /* obj */);
- break;
- case greenland::IntrinsicHelper::HLIGetObject:
- cvtIget(cUnit, callInst, kWord, false /* isWide */, true /* obj */);
- break;
- case greenland::IntrinsicHelper::HLIGetWide:
- case greenland::IntrinsicHelper::HLIGetDouble:
- cvtIget(cUnit, callInst, kLong, true /* isWide */, false /* obj */);
- break;
- case greenland::IntrinsicHelper::HLIGetBoolean:
- cvtIget(cUnit, callInst, kUnsignedByte, false /* isWide */,
- false /* obj */);
- break;
- case greenland::IntrinsicHelper::HLIGetByte:
- cvtIget(cUnit, callInst, kSignedByte, false /* isWide */,
- false /* obj */);
- break;
- case greenland::IntrinsicHelper::HLIGetChar:
- cvtIget(cUnit, callInst, kUnsignedHalf, false /* isWide */,
- false /* obj */);
- break;
- case greenland::IntrinsicHelper::HLIGetShort:
- cvtIget(cUnit, callInst, kSignedHalf, false /* isWide */,
- false /* obj */);
- break;
-
- case greenland::IntrinsicHelper::HLIPut:
- case greenland::IntrinsicHelper::HLIPutFloat:
- cvtIput(cUnit, callInst, kWord, false /* isWide */, false /* obj */);
- break;
- case greenland::IntrinsicHelper::HLIPutObject:
- cvtIput(cUnit, callInst, kWord, false /* isWide */, true /* obj */);
- break;
- case greenland::IntrinsicHelper::HLIPutWide:
- case greenland::IntrinsicHelper::HLIPutDouble:
- cvtIput(cUnit, callInst, kLong, true /* isWide */, false /* obj */);
- break;
- case greenland::IntrinsicHelper::HLIPutBoolean:
- cvtIput(cUnit, callInst, kUnsignedByte, false /* isWide */,
- false /* obj */);
- break;
- case greenland::IntrinsicHelper::HLIPutByte:
- cvtIput(cUnit, callInst, kSignedByte, false /* isWide */,
- false /* obj */);
- break;
- case greenland::IntrinsicHelper::HLIPutChar:
- cvtIput(cUnit, callInst, kUnsignedHalf, false /* isWide */,
- false /* obj */);
- break;
- case greenland::IntrinsicHelper::HLIPutShort:
- cvtIput(cUnit, callInst, kSignedHalf, false /* isWide */,
- false /* obj */);
- break;
-
- case greenland::IntrinsicHelper::IntToChar:
- cvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_CHAR);
- break;
- case greenland::IntrinsicHelper::IntToShort:
- cvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_SHORT);
- break;
- case greenland::IntrinsicHelper::IntToByte:
- cvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_BYTE);
- break;
-
- case greenland::IntrinsicHelper::CmplFloat:
- cvtFPCompare(cUnit, callInst, Instruction::CMPL_FLOAT);
- break;
- case greenland::IntrinsicHelper::CmpgFloat:
- cvtFPCompare(cUnit, callInst, Instruction::CMPG_FLOAT);
- break;
- case greenland::IntrinsicHelper::CmplDouble:
- cvtFPCompare(cUnit, callInst, Instruction::CMPL_DOUBLE);
- break;
- case greenland::IntrinsicHelper::CmpgDouble:
- cvtFPCompare(cUnit, callInst, Instruction::CMPG_DOUBLE);
- break;
-
- case greenland::IntrinsicHelper::CmpLong:
- cvtLongCompare(cUnit, callInst);
- break;
-
- case greenland::IntrinsicHelper::SHLLong:
- cvtShiftOp(cUnit, Instruction::SHL_LONG, callInst);
- break;
- case greenland::IntrinsicHelper::SHRLong:
- cvtShiftOp(cUnit, Instruction::SHR_LONG, callInst);
- break;
- case greenland::IntrinsicHelper::USHRLong:
- cvtShiftOp(cUnit, Instruction::USHR_LONG, callInst);
- break;
- case greenland::IntrinsicHelper::SHLInt:
- cvtShiftOp(cUnit, Instruction::SHL_INT, callInst);
- break;
- case greenland::IntrinsicHelper::SHRInt:
- cvtShiftOp(cUnit, Instruction::SHR_INT, callInst);
- break;
- case greenland::IntrinsicHelper::USHRInt:
- cvtShiftOp(cUnit, Instruction::USHR_INT, callInst);
- break;
-
- case greenland::IntrinsicHelper::CatchTargets: {
- llvm::SwitchInst* swInst =
- llvm::dyn_cast<llvm::SwitchInst>(nextIt);
- DCHECK(swInst != NULL);
- /*
- * Discard the edges and the following conditional branch.
- * Do a direct branch to the default target (which is the
- * "work" portion of the pair.
- * TODO: awful code layout - rework
- */
- llvm::BasicBlock* targetBB = swInst->getDefaultDest();
- DCHECK(targetBB != NULL);
- opUnconditionalBranch(cUnit,
- cUnit->blockToLabelMap.Get(targetBB));
- ++it;
- }
- break;
-
- default:
- LOG(FATAL) << "Unexpected intrinsic " << (int)id << ", "
- << cUnit->intrinsic_helper->GetName(id);
- }
- }
- break;
+ /* Remember the first LIR for thisl block*/
+ if (headLIR == NULL) {
+ headLIR = boundaryLIR;
+ headLIR->defMask = ENCODE_ALL;
+ }
- case llvm::Instruction::Br: cvtBr(cUnit, inst); break;
- case llvm::Instruction::Add: cvtBinOp(cUnit, kOpAdd, inst); break;
- case llvm::Instruction::Sub: cvtBinOp(cUnit, kOpSub, inst); break;
- case llvm::Instruction::Mul: cvtBinOp(cUnit, kOpMul, inst); break;
- case llvm::Instruction::SDiv: cvtBinOp(cUnit, kOpDiv, inst); break;
- case llvm::Instruction::SRem: cvtBinOp(cUnit, kOpRem, inst); break;
- case llvm::Instruction::And: cvtBinOp(cUnit, kOpAnd, inst); break;
- case llvm::Instruction::Or: cvtBinOp(cUnit, kOpOr, inst); break;
- case llvm::Instruction::Xor: cvtBinOp(cUnit, kOpXor, inst); break;
- case llvm::Instruction::PHI: cvtPhi(cUnit, inst); break;
- case llvm::Instruction::Ret: cvtRet(cUnit, inst); break;
- case llvm::Instruction::FAdd: cvtBinFPOp(cUnit, kOpAdd, inst); break;
- case llvm::Instruction::FSub: cvtBinFPOp(cUnit, kOpSub, inst); break;
- case llvm::Instruction::FMul: cvtBinFPOp(cUnit, kOpMul, inst); break;
- case llvm::Instruction::FDiv: cvtBinFPOp(cUnit, kOpDiv, inst); break;
- case llvm::Instruction::FRem: cvtBinFPOp(cUnit, kOpRem, inst); break;
- case llvm::Instruction::SIToFP: cvtIntToFP(cUnit, inst); break;
- case llvm::Instruction::FPToSI: cvtFPToInt(cUnit, inst); break;
- case llvm::Instruction::FPTrunc: cvtDoubleToFloat(cUnit, inst); break;
- case llvm::Instruction::FPExt: cvtFloatToDouble(cUnit, inst); break;
- case llvm::Instruction::Trunc: cvtTrunc(cUnit, inst); break;
-
- case llvm::Instruction::ZExt: cvtIntExt(cUnit, inst, false /* signed */);
- break;
- case llvm::Instruction::SExt: cvtIntExt(cUnit, inst, true /* signed */);
- break;
+ switch(opcode) {
- case llvm::Instruction::Switch: cvtSwitch(cUnit, inst); break;
-
- case llvm::Instruction::Unreachable:
- break; // FIXME: can we really ignore these?
-
- case llvm::Instruction::Shl:
- case llvm::Instruction::LShr:
- case llvm::Instruction::AShr:
- case llvm::Instruction::Invoke:
- case llvm::Instruction::FPToUI:
- case llvm::Instruction::UIToFP:
- case llvm::Instruction::PtrToInt:
- case llvm::Instruction::IntToPtr:
- case llvm::Instruction::FCmp:
- case llvm::Instruction::URem:
- case llvm::Instruction::UDiv:
- case llvm::Instruction::Resume:
- case llvm::Instruction::Alloca:
- case llvm::Instruction::GetElementPtr:
- case llvm::Instruction::Fence:
- case llvm::Instruction::AtomicCmpXchg:
- case llvm::Instruction::AtomicRMW:
- case llvm::Instruction::BitCast:
- case llvm::Instruction::VAArg:
- case llvm::Instruction::Select:
- case llvm::Instruction::UserOp1:
- case llvm::Instruction::UserOp2:
- case llvm::Instruction::ExtractElement:
- case llvm::Instruction::InsertElement:
- case llvm::Instruction::ShuffleVector:
- case llvm::Instruction::ExtractValue:
- case llvm::Instruction::InsertValue:
- case llvm::Instruction::LandingPad:
- case llvm::Instruction::IndirectBr:
- case llvm::Instruction::Load:
- case llvm::Instruction::Store:
- LOG(FATAL) << "Unexpected llvm opcode: " << opcode; break;
-
- default:
- LOG(FATAL) << "Unknown llvm opcode: " << inst->getOpcodeName();
- break;
+ case llvm::Instruction::ICmp: {
+ llvm::Instruction* nextInst = nextIt;
+ llvm::BranchInst* brInst = llvm::dyn_cast<llvm::BranchInst>(nextInst);
+ if (brInst != NULL /* and... */) {
+ cvtICmpBr(cUnit, inst, brInst);
+ ++it;
+ } else {
+ cvtICmp(cUnit, inst);
+ }
+ }
+ break;
+
+ case llvm::Instruction::Call: {
+ llvm::CallInst* callInst = llvm::dyn_cast<llvm::CallInst>(inst);
+ llvm::Function* callee = callInst->getCalledFunction();
+ greenland::IntrinsicHelper::IntrinsicId id =
+ cUnit->intrinsic_helper->GetIntrinsicId(callee);
+ switch (id) {
+ case greenland::IntrinsicHelper::AllocaShadowFrame:
+ case greenland::IntrinsicHelper::SetShadowFrameEntry:
+ case greenland::IntrinsicHelper::PopShadowFrame:
+ // Ignore shadow frame stuff for quick compiler
+ break;
+ case greenland::IntrinsicHelper::CopyInt:
+ case greenland::IntrinsicHelper::CopyObj:
+ case greenland::IntrinsicHelper::CopyFloat:
+ case greenland::IntrinsicHelper::CopyLong:
+ case greenland::IntrinsicHelper::CopyDouble:
+ cvtCopy(cUnit, callInst);
+ break;
+ case greenland::IntrinsicHelper::ConstInt:
+ case greenland::IntrinsicHelper::ConstObj:
+ case greenland::IntrinsicHelper::ConstLong:
+ case greenland::IntrinsicHelper::ConstFloat:
+ case greenland::IntrinsicHelper::ConstDouble:
+ cvtConst(cUnit, callInst);
+ break;
+ case greenland::IntrinsicHelper::DivInt:
+ case greenland::IntrinsicHelper::DivLong:
+ cvtBinOp(cUnit, kOpDiv, inst);
+ break;
+ case greenland::IntrinsicHelper::RemInt:
+ case greenland::IntrinsicHelper::RemLong:
+ cvtBinOp(cUnit, kOpRem, inst);
+ break;
+ case greenland::IntrinsicHelper::MethodInfo:
+ // Already dealt with - just ignore it here.
+ break;
+ case greenland::IntrinsicHelper::CheckSuspend:
+ genSuspendTest(cUnit, 0 /* optFlags already applied */);
+ break;
+ case greenland::IntrinsicHelper::HLInvokeObj:
+ case greenland::IntrinsicHelper::HLInvokeFloat:
+ case greenland::IntrinsicHelper::HLInvokeDouble:
+ case greenland::IntrinsicHelper::HLInvokeLong:
+ case greenland::IntrinsicHelper::HLInvokeInt:
+ cvtInvoke(cUnit, callInst, false /* isVoid */, false /* newArray */);
+ break;
+ case greenland::IntrinsicHelper::HLInvokeVoid:
+ cvtInvoke(cUnit, callInst, true /* isVoid */, false /* newArray */);
+ break;
+ case greenland::IntrinsicHelper::FilledNewArray:
+ cvtInvoke(cUnit, callInst, false /* isVoid */, true /* newArray */);
+ break;
+ case greenland::IntrinsicHelper::FillArrayData:
+ cvtFillArrayData(cUnit, callInst);
+ break;
+ case greenland::IntrinsicHelper::ConstString:
+ cvtConstObject(cUnit, callInst, true /* isString */);
+ break;
+ case greenland::IntrinsicHelper::ConstClass:
+ cvtConstObject(cUnit, callInst, false /* isString */);
+ break;
+ case greenland::IntrinsicHelper::CheckCast:
+ cvtCheckCast(cUnit, callInst);
+ break;
+ case greenland::IntrinsicHelper::NewInstance:
+ cvtNewInstance(cUnit, callInst);
+ break;
+ case greenland::IntrinsicHelper::HLSgetObject:
+ cvtSget(cUnit, callInst, false /* wide */, true /* Object */);
+ break;
+ case greenland::IntrinsicHelper::HLSget:
+ case greenland::IntrinsicHelper::HLSgetFloat:
+ case greenland::IntrinsicHelper::HLSgetBoolean:
+ case greenland::IntrinsicHelper::HLSgetByte:
+ case greenland::IntrinsicHelper::HLSgetChar:
+ case greenland::IntrinsicHelper::HLSgetShort:
+ cvtSget(cUnit, callInst, false /* wide */, false /* Object */);
+ break;
+ case greenland::IntrinsicHelper::HLSgetWide:
+ case greenland::IntrinsicHelper::HLSgetDouble:
+ cvtSget(cUnit, callInst, true /* wide */, false /* Object */);
+ break;
+ case greenland::IntrinsicHelper::HLSput:
+ case greenland::IntrinsicHelper::HLSputFloat:
+ case greenland::IntrinsicHelper::HLSputBoolean:
+ case greenland::IntrinsicHelper::HLSputByte:
+ case greenland::IntrinsicHelper::HLSputChar:
+ case greenland::IntrinsicHelper::HLSputShort:
+ cvtSput(cUnit, callInst, false /* wide */, false /* Object */);
+ break;
+ case greenland::IntrinsicHelper::HLSputWide:
+ case greenland::IntrinsicHelper::HLSputDouble:
+ cvtSput(cUnit, callInst, true /* wide */, false /* Object */);
+ break;
+ case greenland::IntrinsicHelper::HLSputObject:
+ cvtSput(cUnit, callInst, false /* wide */, true /* Object */);
+ break;
+ case greenland::IntrinsicHelper::GetException:
+ cvtMoveException(cUnit, callInst);
+ break;
+ case greenland::IntrinsicHelper::Throw:
+ cvtThrow(cUnit, callInst);
+ break;
+ case greenland::IntrinsicHelper::MonitorEnter:
+ cvtMonitorEnterExit(cUnit, true /* isEnter */, callInst);
+ break;
+ case greenland::IntrinsicHelper::MonitorExit:
+ cvtMonitorEnterExit(cUnit, false /* isEnter */, callInst);
+ break;
+ case greenland::IntrinsicHelper::ArrayLength:
+ cvtArrayLength(cUnit, callInst);
+ break;
+ case greenland::IntrinsicHelper::NewArray:
+ cvtNewArray(cUnit, callInst);
+ break;
+ case greenland::IntrinsicHelper::InstanceOf:
+ cvtInstanceOf(cUnit, callInst);
+ break;
+
+ case greenland::IntrinsicHelper::HLArrayGet:
+ case greenland::IntrinsicHelper::HLArrayGetObject:
+ case greenland::IntrinsicHelper::HLArrayGetFloat:
+ cvtAget(cUnit, callInst, kWord, 2);
+ break;
+ case greenland::IntrinsicHelper::HLArrayGetWide:
+ case greenland::IntrinsicHelper::HLArrayGetDouble:
+ cvtAget(cUnit, callInst, kLong, 3);
+ break;
+ case greenland::IntrinsicHelper::HLArrayGetBoolean:
+ cvtAget(cUnit, callInst, kUnsignedByte, 0);
+ break;
+ case greenland::IntrinsicHelper::HLArrayGetByte:
+ cvtAget(cUnit, callInst, kSignedByte, 0);
+ break;
+ case greenland::IntrinsicHelper::HLArrayGetChar:
+ cvtAget(cUnit, callInst, kUnsignedHalf, 1);
+ break;
+ case greenland::IntrinsicHelper::HLArrayGetShort:
+ cvtAget(cUnit, callInst, kSignedHalf, 1);
+ break;
+
+ case greenland::IntrinsicHelper::HLArrayPut:
+ case greenland::IntrinsicHelper::HLArrayPutFloat:
+ cvtAputPrimitive(cUnit, callInst, kWord, 2);
+ break;
+ case greenland::IntrinsicHelper::HLArrayPutObject:
+ cvtAputObj(cUnit, callInst);
+ break;
+ case greenland::IntrinsicHelper::HLArrayPutWide:
+ case greenland::IntrinsicHelper::HLArrayPutDouble:
+ cvtAputPrimitive(cUnit, callInst, kLong, 3);
+ break;
+ case greenland::IntrinsicHelper::HLArrayPutBoolean:
+ cvtAputPrimitive(cUnit, callInst, kUnsignedByte, 0);
+ break;
+ case greenland::IntrinsicHelper::HLArrayPutByte:
+ cvtAputPrimitive(cUnit, callInst, kSignedByte, 0);
+ break;
+ case greenland::IntrinsicHelper::HLArrayPutChar:
+ cvtAputPrimitive(cUnit, callInst, kUnsignedHalf, 1);
+ break;
+ case greenland::IntrinsicHelper::HLArrayPutShort:
+ cvtAputPrimitive(cUnit, callInst, kSignedHalf, 1);
+ break;
+
+ case greenland::IntrinsicHelper::HLIGet:
+ case greenland::IntrinsicHelper::HLIGetFloat:
+ cvtIget(cUnit, callInst, kWord, false /* isWide */, false /* obj */);
+ break;
+ case greenland::IntrinsicHelper::HLIGetObject:
+ cvtIget(cUnit, callInst, kWord, false /* isWide */, true /* obj */);
+ break;
+ case greenland::IntrinsicHelper::HLIGetWide:
+ case greenland::IntrinsicHelper::HLIGetDouble:
+ cvtIget(cUnit, callInst, kLong, true /* isWide */, false /* obj */);
+ break;
+ case greenland::IntrinsicHelper::HLIGetBoolean:
+ cvtIget(cUnit, callInst, kUnsignedByte, false /* isWide */,
+ false /* obj */);
+ break;
+ case greenland::IntrinsicHelper::HLIGetByte:
+ cvtIget(cUnit, callInst, kSignedByte, false /* isWide */,
+ false /* obj */);
+ break;
+ case greenland::IntrinsicHelper::HLIGetChar:
+ cvtIget(cUnit, callInst, kUnsignedHalf, false /* isWide */,
+ false /* obj */);
+ break;
+ case greenland::IntrinsicHelper::HLIGetShort:
+ cvtIget(cUnit, callInst, kSignedHalf, false /* isWide */,
+ false /* obj */);
+ break;
+
+ case greenland::IntrinsicHelper::HLIPut:
+ case greenland::IntrinsicHelper::HLIPutFloat:
+ cvtIput(cUnit, callInst, kWord, false /* isWide */, false /* obj */);
+ break;
+ case greenland::IntrinsicHelper::HLIPutObject:
+ cvtIput(cUnit, callInst, kWord, false /* isWide */, true /* obj */);
+ break;
+ case greenland::IntrinsicHelper::HLIPutWide:
+ case greenland::IntrinsicHelper::HLIPutDouble:
+ cvtIput(cUnit, callInst, kLong, true /* isWide */, false /* obj */);
+ break;
+ case greenland::IntrinsicHelper::HLIPutBoolean:
+ cvtIput(cUnit, callInst, kUnsignedByte, false /* isWide */,
+ false /* obj */);
+ break;
+ case greenland::IntrinsicHelper::HLIPutByte:
+ cvtIput(cUnit, callInst, kSignedByte, false /* isWide */,
+ false /* obj */);
+ break;
+ case greenland::IntrinsicHelper::HLIPutChar:
+ cvtIput(cUnit, callInst, kUnsignedHalf, false /* isWide */,
+ false /* obj */);
+ break;
+ case greenland::IntrinsicHelper::HLIPutShort:
+ cvtIput(cUnit, callInst, kSignedHalf, false /* isWide */,
+ false /* obj */);
+ break;
+
+ case greenland::IntrinsicHelper::IntToChar:
+ cvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_CHAR);
+ break;
+ case greenland::IntrinsicHelper::IntToShort:
+ cvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_SHORT);
+ break;
+ case greenland::IntrinsicHelper::IntToByte:
+ cvtIntNarrowing(cUnit, callInst, Instruction::INT_TO_BYTE);
+ break;
+
+ case greenland::IntrinsicHelper::CmplFloat:
+ cvtFPCompare(cUnit, callInst, Instruction::CMPL_FLOAT);
+ break;
+ case greenland::IntrinsicHelper::CmpgFloat:
+ cvtFPCompare(cUnit, callInst, Instruction::CMPG_FLOAT);
+ break;
+ case greenland::IntrinsicHelper::CmplDouble:
+ cvtFPCompare(cUnit, callInst, Instruction::CMPL_DOUBLE);
+ break;
+ case greenland::IntrinsicHelper::CmpgDouble:
+ cvtFPCompare(cUnit, callInst, Instruction::CMPG_DOUBLE);
+ break;
+
+ case greenland::IntrinsicHelper::CmpLong:
+ cvtLongCompare(cUnit, callInst);
+ break;
+
+ case greenland::IntrinsicHelper::SHLLong:
+ cvtShiftOp(cUnit, Instruction::SHL_LONG, callInst);
+ break;
+ case greenland::IntrinsicHelper::SHRLong:
+ cvtShiftOp(cUnit, Instruction::SHR_LONG, callInst);
+ break;
+ case greenland::IntrinsicHelper::USHRLong:
+ cvtShiftOp(cUnit, Instruction::USHR_LONG, callInst);
+ break;
+ case greenland::IntrinsicHelper::SHLInt:
+ cvtShiftOp(cUnit, Instruction::SHL_INT, callInst);
+ break;
+ case greenland::IntrinsicHelper::SHRInt:
+ cvtShiftOp(cUnit, Instruction::SHR_INT, callInst);
+ break;
+ case greenland::IntrinsicHelper::USHRInt:
+ cvtShiftOp(cUnit, Instruction::USHR_INT, callInst);
+ break;
+
+ case greenland::IntrinsicHelper::CatchTargets: {
+ llvm::SwitchInst* swInst =
+ llvm::dyn_cast<llvm::SwitchInst>(nextIt);
+ DCHECK(swInst != NULL);
+ /*
+ * Discard the edges and the following conditional branch.
+ * Do a direct branch to the default target (which is the
+ * "work" portion of the pair.
+ * TODO: awful code layout - rework
+ */
+ llvm::BasicBlock* targetBB = swInst->getDefaultDest();
+ DCHECK(targetBB != NULL);
+ opUnconditionalBranch(cUnit,
+ cUnit->blockToLabelMap.Get(targetBB));
+ ++it;
+ // Set next bb to default target - improves code layout
+ nextBB = targetBB;
+ }
+ break;
+
+ default:
+ LOG(FATAL) << "Unexpected intrinsic " << (int)id << ", "
+ << cUnit->intrinsic_helper->GetName(id);
+ }
+ }
+ break;
+
+ case llvm::Instruction::Br: cvtBr(cUnit, inst); break;
+ case llvm::Instruction::Add: cvtBinOp(cUnit, kOpAdd, inst); break;
+ case llvm::Instruction::Sub: cvtBinOp(cUnit, kOpSub, inst); break;
+ case llvm::Instruction::Mul: cvtBinOp(cUnit, kOpMul, inst); break;
+ case llvm::Instruction::SDiv: cvtBinOp(cUnit, kOpDiv, inst); break;
+ case llvm::Instruction::SRem: cvtBinOp(cUnit, kOpRem, inst); break;
+ case llvm::Instruction::And: cvtBinOp(cUnit, kOpAnd, inst); break;
+ case llvm::Instruction::Or: cvtBinOp(cUnit, kOpOr, inst); break;
+ case llvm::Instruction::Xor: cvtBinOp(cUnit, kOpXor, inst); break;
+ case llvm::Instruction::PHI: cvtPhi(cUnit, inst); break;
+ case llvm::Instruction::Ret: cvtRet(cUnit, inst); break;
+ case llvm::Instruction::FAdd: cvtBinFPOp(cUnit, kOpAdd, inst); break;
+ case llvm::Instruction::FSub: cvtBinFPOp(cUnit, kOpSub, inst); break;
+ case llvm::Instruction::FMul: cvtBinFPOp(cUnit, kOpMul, inst); break;
+ case llvm::Instruction::FDiv: cvtBinFPOp(cUnit, kOpDiv, inst); break;
+ case llvm::Instruction::FRem: cvtBinFPOp(cUnit, kOpRem, inst); break;
+ case llvm::Instruction::SIToFP: cvtIntToFP(cUnit, inst); break;
+ case llvm::Instruction::FPToSI: cvtFPToInt(cUnit, inst); break;
+ case llvm::Instruction::FPTrunc: cvtDoubleToFloat(cUnit, inst); break;
+ case llvm::Instruction::FPExt: cvtFloatToDouble(cUnit, inst); break;
+ case llvm::Instruction::Trunc: cvtTrunc(cUnit, inst); break;
+
+ case llvm::Instruction::ZExt: cvtIntExt(cUnit, inst, false /* signed */);
+ break;
+ 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?
+
+ case llvm::Instruction::Shl:
+ case llvm::Instruction::LShr:
+ case llvm::Instruction::AShr:
+ case llvm::Instruction::Invoke:
+ case llvm::Instruction::FPToUI:
+ case llvm::Instruction::UIToFP:
+ case llvm::Instruction::PtrToInt:
+ case llvm::Instruction::IntToPtr:
+ case llvm::Instruction::FCmp:
+ case llvm::Instruction::URem:
+ case llvm::Instruction::UDiv:
+ case llvm::Instruction::Resume:
+ case llvm::Instruction::Alloca:
+ case llvm::Instruction::GetElementPtr:
+ case llvm::Instruction::Fence:
+ case llvm::Instruction::AtomicCmpXchg:
+ case llvm::Instruction::AtomicRMW:
+ case llvm::Instruction::BitCast:
+ case llvm::Instruction::VAArg:
+ case llvm::Instruction::Select:
+ case llvm::Instruction::UserOp1:
+ case llvm::Instruction::UserOp2:
+ case llvm::Instruction::ExtractElement:
+ case llvm::Instruction::InsertElement:
+ case llvm::Instruction::ShuffleVector:
+ case llvm::Instruction::ExtractValue:
+ case llvm::Instruction::InsertValue:
+ case llvm::Instruction::LandingPad:
+ case llvm::Instruction::IndirectBr:
+ case llvm::Instruction::Load:
+ case llvm::Instruction::Store:
+ LOG(FATAL) << "Unexpected llvm opcode: " << opcode; break;
+
+ default:
+ LOG(FATAL) << "Unknown llvm opcode: " << inst->getOpcodeName();
+ break;
+ }
}
- }
- if (headLIR != NULL) {
- oatApplyLocalOptimizations(cUnit, headLIR, cUnit->lastLIRInsn);
+ if (headLIR != NULL) {
+ oatApplyLocalOptimizations(cUnit, headLIR, cUnit->lastLIRInsn);
+ }
+ if (nextBB != NULL) {
+ bb = nextBB;
+ nextBB = NULL;
+ }
}
return false;
}