std::ostream& operator << (std::ostream& os, const llvm::Type* type) { std::string str; llvm::raw_string_ostream rso(str); type->print(rso); os << rso.str(); return os; }
IComparison* Comparisons::NewEx(LPCTSTR originalDocId, LPCTSTR modifiedDocId, VARIANT &renderingSet, LONG comparisonMode, VARIANT_BOOL showSelectorDialog, BSTR originalDescription, BSTR modifiedDescription) { AFX_MANAGE_STATE(AfxGetAppModuleState()); AutomationInteractionSuppressor ais; CDeltaViewCommandLineInfo cmdInfo; cmdInfo.m_sOriginal = EnsureDocId(originalDocId); cmdInfo.m_sModified = EnsureDocId(modifiedDocId); cmdInfo.m_sOriginalDisplayName = originalDescription; cmdInfo.m_sModifiedDisplayName = modifiedDescription; cmdInfo.m_bShowSelector = showSelectorDialog != VARIANT_FALSE; CStdString selectedRenderingSet = RenderingSet::GetCurrentRenderingSet(); _variant_t vrenderSet = renderingSet; if (vrenderSet.vt == VT_BSTR) { selectedRenderingSet = _bstr_t(vrenderSet); } RenderingSetOverride rso(selectedRenderingSet); cmdInfo.m_comparisonOption = comparisonMode; cmdInfo.m_bSilentMode = showSelectorDialog == VARIANT_FALSE; COptionsDlgSelector optSelector; if(optSelector.SetDlgInformation(cmdInfo) == S_FALSE) return FALSE; if( cmdInfo.ShouldShowDocumentSelectorDlg() ) { if( !optSelector.ShowDialog() ) { // Dialog might have returned false because it was cancelled during a right-click op. // If so, don't display a 'unable to compare' error. ST2085 if( !optSelector.Cancelled() ) { AfxThrowOleDispatchException(1105, L"Comparison failed."); } AfxThrowOleDispatchException(1106, L"Cancelled."); } } else { if (!optSelector.StartComparisons()) { AfxThrowOleDispatchException(1105, L"Comparison failed."); } } // TODO - can we get the frame in a better way CMDIFrameWnd* pMainFrame = DYNAMIC_DOWNCAST(CMDIFrameWnd, AfxGetMainWnd()); CChildFrame *pFrame = DYNAMIC_DOWNCAST( CChildFrame, pMainFrame->MDIGetActive() ); CDeltaVwDoc* pDoc = pFrame->GetDocument(); UpdateOpenList(); return FindComObject(pDoc); }
bool fuseKernels(bcc::BCCContext& Context, const std::vector<Source *>& sources, const std::vector<int>& slots, const std::string& fusedName, Module* mergedModule) { bccAssert(sources.size() == slots.size() && "sources and slots differ in size"); uint32_t fusedFunctionSignature; llvm::FunctionType* fusedType = getFusedFuncType(Context, sources, slots, mergedModule, &fusedFunctionSignature); if (fusedType == nullptr) { return false; } Function* fusedKernel = (Function*)(mergedModule->getOrInsertFunction(fusedName, fusedType)); llvm::LLVMContext& ctxt = Context.getLLVMContext(); llvm::BasicBlock* block = llvm::BasicBlock::Create(ctxt, "entry", fusedKernel); llvm::IRBuilder<> builder(block); Function::arg_iterator argIter = fusedKernel->arg_begin(); llvm::Value* dataElement = nullptr; if (bcinfo::MetadataExtractor::hasForEachSignatureIn(fusedFunctionSignature)) { dataElement = &*(argIter++); dataElement->setName("DataIn"); } llvm::Value* X = nullptr; if (bcinfo::MetadataExtractor::hasForEachSignatureX(fusedFunctionSignature)) { X = &*(argIter++); X->setName("x"); } llvm::Value* Y = nullptr; if (bcinfo::MetadataExtractor::hasForEachSignatureY(fusedFunctionSignature)) { Y = &*(argIter++); Y->setName("y"); } llvm::Value* Z = nullptr; if (bcinfo::MetadataExtractor::hasForEachSignatureZ(fusedFunctionSignature)) { Z = &*(argIter++); Z->setName("z"); } auto slotIter = slots.begin(); for (const Source* source : sources) { int slot = *slotIter; uint32_t inputFunctionSignature; const Function* inputFunction = getFunction(mergedModule, source, slot, &inputFunctionSignature); if (inputFunction == nullptr) { // Either failed to find the kernel function, or the function has multiple inputs. return false; } // Don't try to fuse a non-kernel if (!bcinfo::MetadataExtractor::hasForEachSignatureKernel(inputFunctionSignature)) { ALOGE("Kernel fusion (module %s function %s): not a kernel", source->getName().c_str(), inputFunction->getName().str().c_str()); return false; } std::vector<llvm::Value*> args; if (bcinfo::MetadataExtractor::hasForEachSignatureIn(inputFunctionSignature)) { if (dataElement == nullptr) { ALOGE("Kernel fusion (module %s function %s): expected input, but got null", source->getName().c_str(), inputFunction->getName().str().c_str()); return false; } const llvm::FunctionType* funcTy = inputFunction->getFunctionType(); llvm::Type* firstArgType = funcTy->getParamType(0); if (dataElement->getType() != firstArgType) { std::string msg; llvm::raw_string_ostream rso(msg); rso << "Mismatching argument type, expected "; firstArgType->print(rso); rso << ", received "; dataElement->getType()->print(rso); ALOGE("Kernel fusion (module %s function %s): %s", source->getName().c_str(), inputFunction->getName().str().c_str(), rso.str().c_str()); return false; } args.push_back(dataElement); } else { // Only the first kernel in a batch is allowed to have no input if (slotIter != slots.begin()) { ALOGE("Kernel fusion (module %s function %s): function not first in batch takes no input", source->getName().c_str(), inputFunction->getName().str().c_str()); return false; } } if (bcinfo::MetadataExtractor::hasForEachSignatureX(inputFunctionSignature)) { args.push_back(X); } if (bcinfo::MetadataExtractor::hasForEachSignatureY(inputFunctionSignature)) { args.push_back(Y); } if (bcinfo::MetadataExtractor::hasForEachSignatureZ(inputFunctionSignature)) { args.push_back(Z); } dataElement = builder.CreateCall((llvm::Value*)inputFunction, args); slotIter++; } if (fusedKernel->getReturnType()->isVoidTy()) { builder.CreateRetVoid(); } else { builder.CreateRet(dataElement); } llvm::NamedMDNode* ExportForEachNameMD = mergedModule->getOrInsertNamedMetadata("#rs_export_foreach_name"); llvm::MDString* nameMDStr = llvm::MDString::get(ctxt, fusedName); llvm::MDNode* nameMDNode = llvm::MDNode::get(ctxt, nameMDStr); ExportForEachNameMD->addOperand(nameMDNode); llvm::NamedMDNode* ExportForEachMD = mergedModule->getOrInsertNamedMetadata("#rs_export_foreach"); llvm::MDString* sigMDStr = llvm::MDString::get(ctxt, llvm::utostr(fusedFunctionSignature)); llvm::MDNode* sigMDNode = llvm::MDNode::get(ctxt, sigMDStr); ExportForEachMD->addOperand(sigMDNode); return true; }
void AAAnalyzer::printCallGraph(const string& mIdentifier) { string dotfilename(""); dotfilename.append(mIdentifier); dotfilename.append(".maycg.dot"); FILE * fout = fopen(dotfilename.data(), "w+"); fprintf(fout, "digraph maycg {\n"); for (ilist_iterator<Function> iterF = module->getFunctionList().begin(); iterF != module->getFunctionList().end(); iterF++) { Function* f = iterF; if (f->isIntrinsic()) { continue; } if (wrapped_functions_map.count(f)) { FunctionWrapper * fw = wrapped_functions_map[f]; fprintf(fout, "\tf%d[label=\"%s\"]\n", fw->getIndex(), f->getName().data()); } else { errs() << "ERROR in printCG when declare functions.\n"; exit(-1); } } set<FunctionWrapper*>::iterator fwIt = wrapped_functions.begin(); while (fwIt != wrapped_functions.end()) { FunctionWrapper* fw = *fwIt; set<CommonCall*>* commonCalls = fw->getCommonCallsForCG(); set<CommonCall*>::iterator comIt = commonCalls->begin(); while (comIt != commonCalls->end()) { CommonCall* cc = *comIt; Function * callee = (Function*) cc->calledValue; if (wrapped_functions_map.count(callee)) { Value * ci = cc->ret; std::string s; raw_string_ostream rso(s); if (ci != NULL) { rso << *(ci); } else { rso << "Hidden"; } string& edgelabel = rso.str(); for (unsigned int i = 0; i < edgelabel.length(); i++) { if (edgelabel[i] == '\"') { edgelabel[i] = '`'; } if (edgelabel[i] == '\n') { edgelabel[i] = ' '; } } fprintf(fout, "\tf%d->f%d[label=\"%s\"]\n", fw->getIndex(), wrapped_functions_map[callee]->getIndex(), edgelabel.data()); } else { errs() << "ERROR in printCG when print common function calls.\n"; exit(-1); } comIt++; } set<PointerCall*>* fpCallsMap = fw->getPointerCallsForCG(); set<PointerCall*>::iterator fpIt = fpCallsMap->begin(); while (fpIt != fpCallsMap->end()) { PointerCall* pcall = *fpIt; //Value * callInst = fpIt->first; set<Function*>* mayCalled = &((*fpIt)->handledCallees); Value* calledValue = pcall->calledValue; std::string s; raw_string_ostream rso(s); if (pcall->ret != NULL) { rso << *(pcall->ret); } else { rso << "Hidden"; } string& edgelabel = rso.str(); // edge label is the call inst for (unsigned int i = 0; i < edgelabel.length(); i++) { if (edgelabel[i] == '\"') { edgelabel[i] = '`'; } if (edgelabel[i] == '\n') { edgelabel[i] = ' '; } } set<Function*>::iterator mcIt = mayCalled->begin(); while (mcIt != mayCalled->end()) { Function * mcf = *mcIt; if (wrapped_functions_map.count(mcf)) { int clevel = this->isCompatible((FunctionType*) (mcf->getType()->getPointerElementType()), (FunctionType*) (calledValue->getType()->getPointerElementType())); fprintf(fout, "\tf%d->f%d[label=\"%s\"] // confidence-level = %d\n", fw->getIndex(), wrapped_functions_map[mcf]->getIndex(), edgelabel.data(), clevel); } else { errs() << "ERROR in printCG when print fp calls.\n"; exit(-1); } mcIt++; } fpIt++; } fwIt++; } fprintf(fout, "}\n"); fclose(fout); }
int main(int ac, char **av) { SourceMgr SrcMgr; //LLVMInitializeX86TargetInfo(); llvm::InitializeAllTargetInfos(); //LLVMInitializeX86AsmParser(); llvm::InitializeAllTargetMCs(); //LLVMInitializeX86TargetMC(); llvm::InitializeAllAsmParsers(); //LLVMInitializeX86AsmParser(); llvm::InitializeAllDisassemblers(); //LLVMInitializeX86Disassembler(); // arg0: // llvm::Target encapsulating the "x86_64-apple-darwin14.5.0" information // see /lib/Support/Triple.cpp for the details //spec = llvm::sys::getDefaultTargetTriple(); //std::string machSpec = "x86_64-apple-windows"; // will produce a COFF //std::string machSpec = "x86_64-apple-darwin14.5.0"; // will produce a Mach-O std::string machSpec = "arm-none-none-eabi"; // //std::string machSpec = "x86_64-apple-darwin"; //std::string machSpec = "x86_64-thumb-linux-gnu"; //std::string machSpec = "x86_64-unknown-linux-gnu"; printf("machine spec: %s\n", machSpec.c_str()); machSpec = Triple::normalize(machSpec); printf("machine spec (normalized): %s\n", machSpec.c_str()); Triple TheTriple(machSpec); // Get the target specific parser. std::string Error; const Target *TheTarget = TargetRegistry::lookupTarget(/*arch*/"", TheTriple, Error); if (!TheTarget) { errs() << Error; return -1; } machSpec = TheTriple.getTriple(); printf("machine spec (returned): %s\n", machSpec.c_str()); printf("Target.getName(): %s\n", TheTarget->getName()); printf("Target.getShortDescription(): %s\n", TheTarget->getShortDescription()); /* from the target we get almost everything */ std::unique_ptr<MCRegisterInfo> MRI(TheTarget->createMCRegInfo(machSpec)); std::unique_ptr<MCAsmInfo> MAI(TheTarget->createMCAsmInfo(*MRI, machSpec)); std::unique_ptr<MCInstrInfo> MCII(TheTarget->createMCInstrInfo()); /* describes target instruction set */ MCSubtargetInfo *STI = TheTarget->createMCSubtargetInfo(machSpec, "", ""); /* subtarget instr set */ MCAsmBackend *MAB = TheTarget->createMCAsmBackend(*MRI, machSpec, /* specific CPU */ ""); // arg0: // llvm::SourceMgr (Support/SourceMgr.h) that holds assembler source // has vector of llvm::SrcBuffer encaps (Support/MemoryBuffer.h) and vector of include dirs //std::string asmSrc = ".org 0x100, 0xAA\nfoo:\nxor %eax, %ebx\npush %rbp\njmp foo\nrdtsc\n"; //std::string asmSrc = ".text\n" "ldr pc, data_foo\n" "\n" "data_foo:\n" " .int 0x8\n" "\n" "loop:\n" "b loop\n"; //std::string asmSrc = ".text\n" "mov r2, r1\n"; std::string asmSrc = ".text\n" "ldr pc, data_foo\n" "data_foo:\n" ".int 0x8\n" "loop:\n" "b loop\n"; std::unique_ptr<MemoryBuffer> memBuf = MemoryBuffer::getMemBuffer(asmSrc); SrcMgr.AddNewSourceBuffer(std::move(memBuf), SMLoc()); // arg1: the machine code context MCObjectFileInfo MOFI; MCContext Ctx(MAI.get(), MRI.get(), &MOFI, &SrcMgr); MOFI.InitMCObjectFileInfo(TheTriple, Reloc::Default, CodeModel::Default, Ctx); // this is the assembler interface // -methods per .s statements (emit bytes, handle directive, etc.) // -remembers current section // -implementations that write a .s, or .o in various formats // // 1. the output stream ... a formatted_raw_ostream wraps a raw_ostream to provide // tracking of line and column position for padding and shit // // but raw_ostream is abstract and is implemented by raw_fd_ostream, raw_string_ostream, etc. /* output stream: raw_svector_ostream is a raw_pwrite_stream is a raw_ostream since a SmallString is SmallVector (svector) we can use this and retrieve bytes later with its .data() method */ SmallString<1024> smallString; raw_svector_ostream rso(smallString); /* code emitter needs 1) instruction set info 2) register info */ MCCodeEmitter *CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, Ctx); MCStreamer *as = TheTarget->createMCObjectStreamer( TheTriple, /* Triple */ Ctx, /* the MCContext */ *MAB, /* the AsmBackend, (fixups, relaxation, objs and elfs) */ rso, /* output stream raw_pwrite_stream */ CE, /* code emitter */ *STI, /* subtarget info */ true, /* relax all fixups */ true, /* incremental linker compatible */ false /* DWARFMustBeAtTheEnd */ ); std::string abi = "none"; MCTargetOptions toptions; toptions.MCUseDwarfDirectory = false; toptions.ABIName = abi; printf("trying to assemble, let's go..\n"); AssembleInput(TheTarget, SrcMgr, Ctx, *as, *MAI, *STI, *MCII, toptions); printf("done with AssembleInput()\n"); /* dump to file for debugging */ FILE *fp; fp = fopen("out.bin", "wb"); fwrite(smallString.data(), 1, smallString.size(), fp); fclose(fp); //int n = smallString.size(); int codeOffset=0, codeSize = 0; char *data = smallString.data(); if(*(uint32_t *)data == 0xFEEDFACF) { unsigned int idx = 0; idx += 0x20; /* skip mach_header_64 to first command */ idx += 0x48; /* advance into segment_command_64 to first section */ idx += 0x28; /* advance into section_64 to size */ uint64_t scn_size = *(uint64_t *)(data + idx); idx += 0x8; /* advance into section_64 to offset */ uint64_t scn_offset = *(uint64_t *)(data + idx); codeOffset = scn_offset; codeSize = scn_size; } else if(0==memcmp(data, "\x7F" "ELF\x01\x01\x01\x00", 8)) { /* assume four sections: NULL, .strtab, .text, .symtab */ uint32_t e_shoff = *(uint32_t *)(data + 0x20); uint32_t sh_offset = *(uint32_t *)(data + e_shoff + 2*0x28 + 0x10); /* second shdr */ uint32_t sh_size = *(uint32_t *)(data + e_shoff + 2*0x28 + 0x14); /* second shdr */ codeOffset = sh_offset; codeSize = sh_size; } else { printf("ERROR: couldn't identify type of output file\n"); } dump_bytes((unsigned char *)data + codeOffset, codeSize, 0); return 0; }