diff options
| author | 2012-06-20 15:14:24 -0700 | |
|---|---|---|
| committer | 2012-06-20 15:14:24 -0700 | |
| commit | 83475c208287fe671f12a1c59f914194b2caf1db (patch) | |
| tree | 65d1f065aae991d42d10e055c89de4992652db92 /src/compiler/codegen/MethodBitcode.cc | |
| parent | 4d999fe696d43de5872f7be293e8a749cb69beaf (diff) | |
| parent | ad8f15e0b13383b2eaa2486b230debeae7a55661 (diff) | |
Merge "Milestone: close Quick side channel communication" into ics-mr1-plus-art
Diffstat (limited to 'src/compiler/codegen/MethodBitcode.cc')
| -rw-r--r-- | src/compiler/codegen/MethodBitcode.cc | 151 |
1 files changed, 131 insertions, 20 deletions
diff --git a/src/compiler/codegen/MethodBitcode.cc b/src/compiler/codegen/MethodBitcode.cc index f13a473be5..66823c2313 100644 --- a/src/compiler/codegen/MethodBitcode.cc +++ b/src/compiler/codegen/MethodBitcode.cc @@ -27,6 +27,7 @@ #include <llvm/Type.h> #include <llvm/Instructions.h> #include <llvm/Support/Casting.h> +#include <llvm/Support/InstIterator.h> const char* labelFormat = "L0x%x_%d"; @@ -75,6 +76,50 @@ llvm::Type* llvmTypeFromLocRec(CompilationUnit* cUnit, RegLocation loc) return res; } +/* Create an in-memory RegLocation from an llvm Value. */ +void createLocFromValue(CompilationUnit* cUnit, llvm::Value* val) +{ + // NOTE: llvm takes shortcuts with c_str() - get to std::string firstt + std::string s(val->getName().str()); + const char* valName = s.c_str(); + if (cUnit->printMe) { + LOG(INFO) << "Processing llvm Value " << valName; + } + SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val); + DCHECK(it == cUnit->locMap.end()) << " - already defined: " << valName; + int baseSReg = INVALID_SREG; + int subscript = -1; + sscanf(valName, "v%d_%d", &baseSReg, &subscript); + if ((baseSReg == INVALID_SREG) && (!strcmp(valName, "method"))) { + baseSReg = SSA_METHOD_BASEREG; + subscript = 0; + } + if (cUnit->printMe) { + LOG(INFO) << "Base: " << baseSReg << ", Sub: " << subscript; + } + DCHECK_NE(baseSReg, INVALID_SREG); + DCHECK_NE(subscript, -1); + // TODO: redo during C++'ification + RegLocation loc = {kLocDalvikFrame, 0, 0, 0, 0, 0, 0, 0, 0, INVALID_REG, + INVALID_REG, INVALID_SREG, INVALID_SREG}; + llvm::Type* ty = val->getType(); + loc.wide = ((ty == cUnit->irb->getInt64Ty()) || + (ty == cUnit->irb->getDoubleTy())); + loc.defined = true; + if ((ty == cUnit->irb->getFloatTy()) || + (ty == cUnit->irb->getDoubleTy())) { + loc.fp = true; + } else if (ty == cUnit->irb->GetJObjectTy()) { + loc.ref = true; + } else { + loc.core = true; + } + loc.home = false; // Will change during promotion + loc.sRegLow = baseSReg; + loc.origSReg = cUnit->locMap.size(); + cUnit->locMap.Put(val, loc); +} + void initIR(CompilationUnit* cUnit) { cUnit->context = new llvm::LLVMContext(); @@ -1372,19 +1417,25 @@ void oatMethodMIR2Bitcode(CompilationUnit* cUnit) llvm::verifyFunction(*cUnit->func, llvm::PrintMessageAction); - // Write bitcode to file - std::string errmsg; + if (cUnit->enableDebug & (1 << kDebugDumpBitcodeFile)) { + // Write bitcode to file + std::string errmsg; + std::string fname(PrettyMethod(cUnit->method_idx, *cUnit->dex_file)); + oatReplaceSpecialChars(fname); + // TODO: make configurable + fname = StringPrintf("/tmp/%s.bc", fname.c_str()); - llvm::OwningPtr<llvm::tool_output_file> out_file( - new llvm::tool_output_file("/tmp/foo.bc", errmsg, - llvm::raw_fd_ostream::F_Binary)); + llvm::OwningPtr<llvm::tool_output_file> out_file( + new llvm::tool_output_file(fname.c_str(), errmsg, + llvm::raw_fd_ostream::F_Binary)); - if (!errmsg.empty()) { - LOG(ERROR) << "Failed to create bitcode output file: " << errmsg; - } + if (!errmsg.empty()) { + LOG(ERROR) << "Failed to create bitcode output file: " << errmsg; + } - llvm::WriteBitcodeToFile(cUnit->module, out_file->os()); - out_file->keep(); + llvm::WriteBitcodeToFile(cUnit->module, out_file->os()); + out_file->keep(); + } } RegLocation getLoc(CompilationUnit* cUnit, llvm::Value* val) { @@ -1575,11 +1626,6 @@ void cvtCall(CompilationUnit* cUnit, llvm::CallInst* callInst, UNIMPLEMENTED(FATAL); } -void setMethodInfo(CompilationUnit* cUnit, llvm::CallInst* callInst) -{ - UNIMPLEMENTED(WARNING) << "Net setMethodInfo"; -} - void cvtCopy(CompilationUnit* cUnit, llvm::CallInst* callInst) { DCHECK(callInst->getNumArgOperands() == 1); @@ -1670,6 +1716,14 @@ void cvtInvoke(CompilationUnit* cUnit, llvm::CallInst* callInst, genInvoke(cUnit, info); } +/* Look up the RegLocation associated with a Value. Must already be defined */ +RegLocation valToLoc(CompilationUnit* cUnit, llvm::Value* val) +{ + SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val); + DCHECK(it != cUnit->locMap.end()) << "Missing definition"; + return it->second; +} + bool methodBitcodeBlockCodeGen(CompilationUnit* cUnit, llvm::BasicBlock* bb) { bool isEntry = (bb == &cUnit->func->getEntryBlock()); @@ -1697,7 +1751,19 @@ bool methodBitcodeBlockCodeGen(CompilationUnit* cUnit, llvm::BasicBlock* bb) if (isEntry) { cUnit->currentDalvikOffset = 0; - genEntrySequence(cUnit); + 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()); + 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++].sRegLow = INVALID_SREG; + } + } + genEntrySequence(cUnit, argLocs, cUnit->methodLoc); } // Visit all of the instructions in the block @@ -1779,7 +1845,7 @@ bool methodBitcodeBlockCodeGen(CompilationUnit* cUnit, llvm::BasicBlock* bb) cvtConst(cUnit, callInst); break; case greenland::IntrinsicHelper::MethodInfo: - setMethodInfo(cUnit, callInst); + // Already dealt with - just ignore it here. break; case greenland::IntrinsicHelper::CheckSuspend: genSuspendTest(cUnit, 0 /* optFlags already applied */); @@ -1891,17 +1957,62 @@ bool methodBitcodeBlockCodeGen(CompilationUnit* cUnit, llvm::BasicBlock* bb) */ void oatMethodBitcode2LIR(CompilationUnit* cUnit) { - int numBasicBlocks = cUnit->func->getBasicBlockList().size(); + llvm::Function* func = cUnit->func; + int numBasicBlocks = func->getBasicBlockList().size(); // Allocate a list for LIR basic block labels cUnit->blockLabelList = (void*)oatNew(cUnit, sizeof(LIR) * numBasicBlocks, true, kAllocLIR); LIR* labelList = (LIR*)cUnit->blockLabelList; int nextLabel = 0; - for (llvm::Function::iterator i = cUnit->func->begin(), - e = cUnit->func->end(); i != e; ++i) { + for (llvm::Function::iterator i = func->begin(), + e = func->end(); i != e; ++i) { cUnit->blockToLabelMap.Put(static_cast<llvm::BasicBlock*>(i), &labelList[nextLabel++]); } + + /* + * Keep honest - clear regLocations, Value => RegLocation, + * promotion map and VmapTables. + */ + cUnit->locMap.clear(); // Start fresh + cUnit->regLocation = NULL; + for (int i = 0; i < cUnit->numDalvikRegisters + cUnit->numCompilerTemps + 1; + i++) { + cUnit->promotionMap[i].coreLocation = kLocDalvikFrame; + cUnit->promotionMap[i].fpLocation = kLocDalvikFrame; + } + cUnit->coreSpillMask = 0; + cUnit->numCoreSpills = 0; + cUnit->fpSpillMask = 0; + cUnit->numFPSpills = 0; + cUnit->coreVmapTable.clear(); + cUnit->fpVmapTable.clear(); + oatAdjustSpillMask(cUnit); + cUnit->frameSize = oatComputeFrameSize(cUnit); + + /* + * At this point, we've lost all knowledge of register promotion. + * Rebuild that info from the MethodInfo intrinsic (if it + * exists - not required for correctness). + */ + // TODO: find and recover MethodInfo. + + // Create RegLocations for arguments + llvm::Function::arg_iterator it(cUnit->func->arg_begin()); + llvm::Function::arg_iterator it_end(cUnit->func->arg_end()); + for (; it != it_end; ++it) { + llvm::Value* val = it; + createLocFromValue(cUnit, val); + } + // Create RegLocations for all non-argument defintions + for (llvm::inst_iterator i = llvm::inst_begin(func), + e = llvm::inst_end(func); i != e; ++i) { + llvm::Value* val = &*i; + if (val->hasName() && (val->getName().str().c_str()[0] == 'v')) { + createLocFromValue(cUnit, val); + } + } + // Walk the blocks, generating code. for (llvm::Function::iterator i = cUnit->func->begin(), e = cUnit->func->end(); i != e; ++i) { |