static void maybe_print_statistics(llvm::Module *M, const char *prefix = nullptr) { if (!statistics) return; using namespace llvm; uint64_t inum, bnum, fnum, gnum; inum = bnum = fnum = gnum = 0; for (auto I = M->begin(), E = M->end(); I != E; ++I) { // don't count in declarations if (I->size() == 0) continue; ++fnum; for (const BasicBlock& B : *I) { ++bnum; inum += B.size(); } } for (auto I = M->global_begin(), E = M->global_end(); I != E; ++I) ++gnum; if (prefix) errs() << prefix; errs() << "Globals/Functions/Blocks/Instr.: " << gnum << " " << fnum << " " << bnum << " " << inum << "\n"; }
void BinMapOutput::InnerSectionsSymbols(const BinGroups& groups) { for (BinGroups::const_iterator group = groups.begin(), end=groups.end(); group != end; ++group) { if (CountSymbols(m_object, &group->m_section) > 0) { StringRef name = group->m_section.getName(); m_os << "---- Section " << name << ' '; for (size_t i=0; i<65-name.size(); ++i) m_os << '-'; m_os << "\n\n"; m_os << format("%-*s", m_bytes*2+2, (const char*)"Real"); m_os << format("%-*s", m_bytes*2+2, (const char*)"Virtual"); m_os << "Name\n"; OutputSymbols(&group->m_section); m_os << "\n\n"; } // Recurse to loop through follow groups InnerSectionsSymbols(group->m_follow_groups); } }
std::string RewriteBlocks::SynthesizeBlockHelperFuncs(BlockExpr *CE, int i, const char *funcName, std::string Tag) { std::string StructRef = "struct " + Tag; std::string S = "static void __"; S += funcName; S += "_block_copy_" + utostr(i); S += "(" + StructRef; S += "*dst, " + StructRef; S += "*src) {"; for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = ImportedBlockDecls.begin(), E = ImportedBlockDecls.end(); I != E; ++I) { S += "_Block_copy_assign(&dst->"; S += (*I)->getNameAsString(); S += ", src->"; S += (*I)->getNameAsString(); S += ");}"; } S += "\nstatic void __"; S += funcName; S += "_block_dispose_" + utostr(i); S += "(" + StructRef; S += "*src) {"; for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = ImportedBlockDecls.begin(), E = ImportedBlockDecls.end(); I != E; ++I) { S += "_Block_destroy(src->"; S += (*I)->getNameAsString(); S += ");"; } S += "}\n"; return S; }
std::string tesla::ShortName(const Location& Loc) { return (Twine() + Loc.filename() + ":" + Twine(Loc.line()) + "#" + Twine(Loc.counter()) ).str(); }
Interval FlatStoreManager::RegionToInterval(const MemRegion *R) { switch (R->getKind()) { case MemRegion::VarRegionKind: { QualType T = cast<VarRegion>(R)->getValueType(Ctx); uint64_t Size = Ctx.getTypeSize(T); return Interval(0, Size-1); } default: llvm_unreachable("Region kind unhandled."); return Interval(0, 0); } }
CodeGenerator::CodeGenerator() { InitializeNativeTarget(); builder_=new IRBuilder<>(llvm::getGlobalContext()); module_=new Module("my cool jit", llvm::getGlobalContext()); fpm_=new FunctionPassManager (module_); fpm_->add(llvm::createCFGSimplificationPass()); fpm_->add(llvm::createDeadCodeEliminationPass()); fpm_->add(llvm::createMemCpyOptPass()); engine_ = EngineBuilder(module_).create(); assert(engine_); }
uint64_t ExternalCommand::getSignature() { // FIXME: Use a more appropriate hashing infrastructure. using llvm::hash_combine; llvm::hash_code code = hash_value(getName()); for (const auto* input: inputs) { code = hash_combine(code, input->getName()); } for (const auto* output: outputs) { code = hash_combine(code, output->getName()); } code = hash_combine(code, allowMissingInputs); code = hash_combine(code, allowModifiedOutputs); code = hash_combine(code, alwaysOutOfDate); return size_t(code); }
static StringRef input(StringRef scalar, void*, VMProtect &value) { value = 0; if (scalar.size() != 3) return "segment access protection must be three chars (e.g. \"r-x\")"; switch (scalar[0]) { case 'r': value = llvm::MachO::VM_PROT_READ; break; case '-': break; default: return "segment access protection first char must be 'r' or '-'"; } switch (scalar[1]) { case 'w': value = value | llvm::MachO::VM_PROT_WRITE; break; case '-': break; default: return "segment access protection second char must be 'w' or '-'"; } switch (scalar[2]) { case 'x': value = value | llvm::MachO::VM_PROT_EXECUTE; break; case '-': break; default: return "segment access protection third char must be 'x' or '-'"; } // Return the empty string on success, return StringRef(); }
void Util::addExportInfo(const lld::File &atomFile, NormalizedFile &nFile) { if (_ctx.outputMachOType() == llvm::MachO::MH_OBJECT) return; for (SectionInfo *sect : _sectionInfos) { for (const AtomInfo &info : sect->atomsAndOffsets) { const DefinedAtom *atom = info.atom; if (atom->scope() != Atom::scopeGlobal) continue; if (_ctx.exportRestrictMode()) { if (!_ctx.exportSymbolNamed(atom->name())) continue; } Export exprt; exprt.name = atom->name(); exprt.offset = _atomToAddress[atom] - _ctx.baseAddress(); exprt.kind = EXPORT_SYMBOL_FLAGS_KIND_REGULAR; if (atom->merge() == DefinedAtom::mergeAsWeak) exprt.flags = EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION; else exprt.flags = 0; exprt.otherOffset = 0; exprt.otherName = StringRef(); nFile.exportInfo.push_back(exprt); } } }
void BinMapOutput::OutputSectionsSymbols() { m_os << "-- Symbols "; for (int i=0; i<68; ++i) m_os << '-'; m_os << "\n\n"; // We do two passes for EQU and each section; the first pass // determines the byte width to use for the value and whether any // symbols are present, the second pass actually outputs the text. // EQUs if (CountSymbols(m_object, 0) > 0) { m_os << "---- No Section "; for (int i=0; i<63; ++i) m_os << '-'; m_os << "\n\n"; m_os << format("%-*s", m_bytes*2+2, (const char*)"Value"); m_os << "Name\n"; OutputSymbols(0); m_os << "\n\n"; } // Other sections InnerSectionsSymbols(m_groups); }
int verifyAndWriteModule() { if (!verifyModule()) { errs() << "ERR: Verifying module failed, the IR is not valid\n"; errs() << "INFO: Saving anyway so that you can check it\n"; return 1; } if (!writeModule()) { errs() << "Saving sliced module failed\n"; return 1; } // exit code return 0; }
bool writeModule() { // compose name if not given std::string fl; if (!options.outputFile.empty()) { fl = options.outputFile; } else { fl = options.inputFile; replace_suffix(fl, ".sliced"); } // open stream to write to std::ofstream ofs(fl); llvm::raw_os_ostream ostream(ofs); // write the module errs() << "INFO: saving sliced module to: " << fl.c_str() << "\n"; #if (LLVM_VERSION_MAJOR > 6) llvm::WriteBitcodeToFile(*M, ostream); #else llvm::WriteBitcodeToFile(M, ostream); #endif return true; }
void RewriteBlocks::SynthesizeBlockLiterals(SourceLocation FunLocStart, const char *FunName) { // Insert closures that were part of the function. for (unsigned i = 0; i < Blocks.size(); i++) { CollectBlockDeclRefInfo(Blocks[i]); std::string Tag = "__" + std::string(FunName) + "_block_impl_" + utostr(i); std::string CI = SynthesizeBlockImpl(Blocks[i], Tag, ImportedBlockDecls.size() > 0); InsertText(FunLocStart, CI.c_str(), CI.size()); std::string CF = SynthesizeBlockFunc(Blocks[i], i, FunName, Tag); InsertText(FunLocStart, CF.c_str(), CF.size()); if (ImportedBlockDecls.size()) { std::string HF = SynthesizeBlockHelperFuncs(Blocks[i], i, FunName, Tag); InsertText(FunLocStart, HF.c_str(), HF.size()); } BlockDeclRefs.clear(); BlockByRefDecls.clear(); BlockByCopyDecls.clear(); BlockCallExprs.clear(); ImportedBlockDecls.clear(); } Blocks.clear(); RewrittenBlockExprs.clear(); }
void optimize( shared_ptr<module_vmcode> code, vector<optimization_options> opt_options ) { Module* mod = code->get_vm_module(); FunctionPassManager fpm(mod); for( optimization_options opt_option: opt_options ){ switch ( opt_option ){ case opt_verify: for( Function& f: mod->getFunctionList() ){ if(!f.empty()){ verifyFunction(f, PrintMessageAction); } } break; case opt_preset_std_for_function: // createStandardFunctionPasses( &fpm, 1 ); break; } } fpm.doInitialization(); for( Function& f: mod->getFunctionList() ){ if(!f.empty()){ fpm.run(f); } } }
static std::string ConstantName(const tesla::Argument* A) { assert(A->type() == tesla::Argument::Constant); if (A->has_name()) return A->name(); else return Twine(A->value()).str(); }
void Command::Print(raw_ostream &OS, const char *Terminator, bool Quote, CrashReportInfo *CrashInfo) const { // Always quote the exe. OS << ' '; printArg(OS, Executable, /*Quote=*/true); llvm::ArrayRef<const char *> Args = Arguments; llvm::SmallVector<const char *, 128> ArgsRespFile; if (ResponseFile != nullptr) { buildArgvForResponseFile(ArgsRespFile); Args = ArrayRef<const char *>(ArgsRespFile).slice(1); // no executable name } bool HaveCrashVFS = CrashInfo && !CrashInfo->VFSPath.empty(); for (size_t i = 0, e = Args.size(); i < e; ++i) { const char *const Arg = Args[i]; if (CrashInfo) { if (int Skip = skipArgs(Arg, HaveCrashVFS)) { i += Skip - 1; continue; } auto Found = std::find_if(InputFilenames.begin(), InputFilenames.end(), [&Arg](StringRef IF) { return IF == Arg; }); if (Found != InputFilenames.end() && (i == 0 || StringRef(Args[i - 1]) != "-main-file-name")) { // Replace the input file name with the crashinfo's file name. OS << ' '; StringRef ShortName = llvm::sys::path::filename(CrashInfo->Filename); printArg(OS, ShortName.str().c_str(), Quote); continue; } } OS << ' '; printArg(OS, Arg, Quote); } if (CrashInfo && HaveCrashVFS) { OS << ' '; printArg(OS, "-ivfsoverlay", Quote); OS << ' '; printArg(OS, CrashInfo->VFSPath.str().c_str(), Quote); } if (ResponseFile != nullptr) { OS << "\n Arguments passed via response file:\n"; writeResponseFile(OS); // Avoiding duplicated newline terminator, since FileLists are // newline-separated. if (Creator.getResponseFilesSupport() != Tool::RF_FileList) OS << "\n"; OS << " (end of response file)"; } OS << Terminator; }
bool readString(RemoteAddress address, std::string &dest) override { if (!isAddressValid(address, 1)) return false; // TODO: Account for running off the edge of an object, offset in ELF // binaries auto cString = StringRef((const char*)address.getAddressData()); dest.append(cString.begin(), cString.end()); return true; }
// Called with Mutex held to protect Cons, Prod, and Bytes void QueueStreamer::queuePut(unsigned char *buf, size_t len) { size_t EndSpace = std::min(len, Bytes.size() - Prod); DEBUG(dbgs() << "put, len " << len << " Endspace " << EndSpace << " p " << Prod << " c " << Cons << "\n"); // Copy up to the end of the buffer memcpy(&Bytes[Prod], buf, EndSpace); // Wrap around if necessary memcpy(&Bytes[0], buf + EndSpace, len - EndSpace); Prod = (Prod + len) % Bytes.size(); }
/// Target Pointer Size information... Module::PointerSize Module::getPointerSize() const { std::string temp = DataLayout; Module::PointerSize ret = AnyPointerSize; while (!temp.empty()) { std::string token = getToken(temp, "-"); char signal = getToken(token, ":")[0]; if (signal == 'p') { int size = atoi(getToken(token, ":").c_str()); if (size == 32) ret = Pointer32; else if (size == 64) ret = Pointer64; } } return ret; }
static void mapping(IO &io, Export &exp) { io.mapRequired("name", exp.name); io.mapOptional("offset", exp.offset); io.mapOptional("kind", exp.kind, llvm::MachO::EXPORT_SYMBOL_FLAGS_KIND_REGULAR); if (!io.outputting() || exp.flags) io.mapOptional("flags", exp.flags); io.mapOptional("other", exp.otherOffset, Hex32(0)); io.mapOptional("other-name", exp.otherName, StringRef()); }
// Called with Mutex held to protect Cons, Prod, and Bytes void QueueStreamer::queueGet(unsigned char *buf, size_t len) { assert(len <= queueSize()); size_t EndSpace = std::min(len, Bytes.size() - Cons); DEBUG(dbgs() << "get, len " << len << " Endspace " << EndSpace << " p " << Prod << " c " << Cons << "\n"); // Copy up to the end of the buffer memcpy(buf, &Bytes[Cons], EndSpace); // Wrap around if necessary memcpy(buf + EndSpace, &Bytes[0], len - EndSpace); Cons = (Cons + len) % Bytes.size(); }
// Double the size of the queue. Called with Mutex to protect Cons/Prod/Bytes. void QueueStreamer::queueResize() { int leftover = Bytes.size() - Cons; DEBUG(dbgs() << "resizing to " << Bytes.size() * 2 << " " << leftover << " " << Prod << " " << Cons << "\n"); Bytes.resize(Bytes.size() * 2); if (Cons > Prod) { // There are unread bytes left between Cons and the previous end of the // buffer. Move them to the new end of the buffer. memmove(&Bytes[Bytes.size() - leftover], &Bytes[Cons], leftover); Cons = Bytes.size() - leftover; } }
Value* cg_extension::safe_idiv_imod_sv( Value* lhs, Value* rhs, binary_intrin_functor div_or_mod_sv ) { Type* rhs_ty = rhs->getType(); Type* rhs_scalar_ty = rhs_ty->getScalarType(); assert( rhs_scalar_ty->isIntegerTy() ); Value* zero = Constant::getNullValue( rhs_ty ); Value* is_zero = builder_->CreateICmpEQ( rhs, zero ); Value* one_value = Constant::getIntegerValue( rhs_ty, APInt(rhs_scalar_ty->getIntegerBitWidth(), 1) ); Value* non_zero_rhs = builder_->CreateSelect( is_zero, one_value, rhs ); return div_or_mod_sv( lhs, non_zero_rhs ); }
void annotate(const std::set<LLVMNode *> *criteria = nullptr) { // compose name std::string fl(options.inputFile); fl.replace(fl.end() - 3, fl.end(), "-debug.ll"); // open stream to write to std::ofstream ofs(fl); llvm::raw_os_ostream outputstream(ofs); std::string module_comment = "; -- Generated by llvm-slicer --\n" "; * slicing criteria: '" + options.slicingCriteria + "'\n" + "; * forward slice: '" + std::to_string(options.forwardSlicing) + "'\n" + "; * remove slicing criteria: '" + std::to_string(options.removeSlicingCriteria) + "'\n" + "; * undefined are pure: '" + std::to_string(options.dgOptions.RDAOptions.undefinedArePure) + "'\n" + "; * pointer analysis: "; if (options.dgOptions.PTAOptions.analysisType == LLVMPointerAnalysisOptions::AnalysisType::fi) module_comment += "flow-insensitive\n"; else if (options.dgOptions.PTAOptions.analysisType == LLVMPointerAnalysisOptions::AnalysisType::fs) module_comment += "flow-sensitive\n"; else if (options.dgOptions.PTAOptions.analysisType == LLVMPointerAnalysisOptions::AnalysisType::inv) module_comment += "flow-sensitive with invalidate\n"; module_comment+= "; * PTA field sensitivity: "; if (options.dgOptions.PTAOptions.fieldSensitivity == Offset::UNKNOWN) module_comment += "full\n\n"; else module_comment += std::to_string(*options.dgOptions.PTAOptions.fieldSensitivity) + "\n\n"; errs() << "INFO: Saving IR with annotations to " << fl << "\n"; auto annot = new dg::debug::LLVMDGAssemblyAnnotationWriter(annotationOptions, dg->getPTA(), dg->getRDA(), criteria); annot->emitModuleComment(std::move(module_comment)); llvm::Module *M = dg->getModule(); M->print(outputstream, annot); delete annot; }
int main(int argc, char *argv[]) { PROGRAM_START(argc, argv); llvm::cl::ParseCommandLineOptions(argc, argv, "Swift Syntax Test\n"); int ExitCode = EXIT_SUCCESS; if (options::InputSourceFilename.empty() && options::InputSourceDirectory.empty()) { llvm::errs() << "input source file is required\n"; ExitCode = EXIT_FAILURE; } if (!options::InputSourceFilename.empty() && !options::InputSourceDirectory.empty()) { llvm::errs() << "input-source-filename and input-source-directory cannot " "be used together\n\n"; ExitCode = EXIT_FAILURE; } if (options::Action == ActionType::None) { llvm::errs() << "an action is required\n"; ExitCode = EXIT_FAILURE; } if (ExitCode == EXIT_FAILURE) { llvm::cl::PrintHelpMessage(); return ExitCode; } if (!options::InputSourceFilename.empty()) { ExitCode = invokeCommand(argv[0], options::InputSourceFilename); } else { assert(!options::InputSourceDirectory.empty()); std::error_code errorCode; llvm::sys::fs::recursive_directory_iterator DI(options::InputSourceDirectory, errorCode); llvm::sys::fs::recursive_directory_iterator endIterator; for (; DI != endIterator; DI.increment(errorCode)) { auto entry = *DI; auto path = entry.path(); if (!llvm::sys::fs::is_directory(path) && StringRef(path).endswith(".swift")) { ExitCode = invokeCommand(argv[0], path); } } } return ExitCode; }
/// Target endian information... Module::Endianness Module::getEndianness() const { std::string temp = DataLayout; Module::Endianness ret = AnyEndianness; while (!temp.empty()) { std::string token = getToken(temp, "-"); if (token[0] == 'e') { ret = LittleEndian; } else if (token[0] == 'E') { ret = BigEndian; } } return ret; }
std::string CompilerInvocation::getPCHHash() const { using llvm::hash_code; using llvm::hash_value; using llvm::hash_combine; auto Code = hash_value(LangOpts.getPCHHashComponents()); Code = hash_combine(Code, FrontendOpts.getPCHHashComponents()); Code = hash_combine(Code, ClangImporterOpts.getPCHHashComponents()); Code = hash_combine(Code, SearchPathOpts.getPCHHashComponents()); Code = hash_combine(Code, DiagnosticOpts.getPCHHashComponents()); Code = hash_combine(Code, SILOpts.getPCHHashComponents()); Code = hash_combine(Code, IRGenOpts.getPCHHashComponents()); return llvm::APInt(64, Code).toString(36, /*Signed=*/false); }
void dumpToDot(const char *suffix = nullptr) { // compose new name std::string fl(options.inputFile); if (suffix) replace_suffix(fl, suffix); else replace_suffix(fl, ".dot"); errs() << "INFO: Dumping DG to to " << fl << "\n"; if (bb_only) { debug::LLVMDGDumpBlocks dumper(dg, dump_opts, fl.c_str()); dumper.dump(); } else { debug::LLVMDG2Dot dumper(dg, dump_opts, fl.c_str()); dumper.dump(); } }
size_t QueueStreamer::GetBytes(unsigned char *buf, size_t len) { size_t total_copied = 0; pthread_mutex_lock(&Mutex); while (!Done && queueSize() < len - total_copied) { size_t size = queueSize(); DEBUG(dbgs() << "QueueStreamer::GetBytes len " << len << " size " << size << " << waiting\n"); queueGet(buf + total_copied, size); total_copied += size; pthread_cond_signal(&Cond); pthread_cond_wait(&Cond, &Mutex); } // If this is the last partial chunk, adjust len such that the amount we // fetch will be just the remaining bytes. if (Done && queueSize() < len - total_copied) { len = queueSize() + total_copied; } queueGet(buf + total_copied, len - total_copied); pthread_cond_signal(&Cond); pthread_mutex_unlock(&Mutex); return len; }
void BinMapOutput::OutputSectionsSummary() { m_os << "-- Sections (summary) "; for (int i=0; i<57; ++i) m_os << '-'; m_os << "\n\n"; m_os << format("%-*s", m_bytes*2+2, (const char*)"Vstart"); m_os << format("%-*s", m_bytes*2+2, (const char*)"Vstop"); m_os << format("%-*s", m_bytes*2+2, (const char*)"Start"); m_os << format("%-*s", m_bytes*2+2, (const char*)"Stop"); m_os << format("%-*s", m_bytes*2+2, (const char*)"Length"); m_os << format("%-10s", (const char*)"Class"); m_os << "Name\n"; InnerSectionsSummary(m_groups); m_os << '\n'; }