<div dir="ltr"><div dir="ltr"><div dir="ltr"><div><span style="font-family:monospace,monospace">Here is some timing information from running the Zig standard library tests:<br></span></div><div dir="ltr"><span style="font-family:monospace,monospace"><br></span></div><div dir="ltr"><span style="font-family:monospace,monospace">$ ./zig test ../std/index.zig --enable-timing-info<br>                Name       Start         End    Duration     Percent<br>          Initialize      0.0000      0.0010      0.0010      0.0001<br>   Semantic Analysis      0.0010      0.9968      0.9958      0.1192<br>     Code Generation      0.9968      1.4000      0.4032      0.0483<br>    LLVM Emit Output      1.4000      8.1759      6.7760      0.8112<br>  Build Dependencies      8.1759      8.3341      0.1581      0.0189<br>           LLVM Link      8.3341      8.3530      0.0189      0.0023<br>               Total      0.0000      8.3530      8.3530      1.0000<br></span></div><div dir="ltr"><span style="font-family:monospace,monospace"><br></span></div><div><span style="font-family:monospace,monospace">81% of the time was spent waiting for LLVM to turn a Module into an object file. This is with optimizations off, FastISel, no module verification, etc.</span></div><div><span style="font-family:monospace,monospace"><br></span></div><div><span style="font-family:monospace,monospace">How can I speed this up? Any tips or things to look into?<br></span></div><div><span style="font-family:monospace,monospace"><br></span></div><div><span style="font-family:monospace,monospace">Here's the function that 81% of the time is spent inside:<br></span></div><div><span style="font-family:monospace,monospace"><br></span></div><div><span style="font-family:monospace,monospace">bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMModuleRef module_ref,<br>        const char *filename, ZigLLVM_EmitOutputType output_type, char **error_message, bool is_debug, bool is_small)<br>{<br>    std::error_code EC;<br>    raw_fd_ostream dest(filename, EC, sys::fs::F_None);<br>    if (EC) {<br>        *error_message = strdup((const char *)StringRef(EC.message()).bytes_begin());<br>        return true;<br>    }<br>    TargetMachine* target_machine = reinterpret_cast<TargetMachine*>(targ_machine_ref);<br>    target_machine->setO0WantsFastISel(true);<br><br>    Module* module = unwrap(module_ref);<br><br>    PassManagerBuilder *PMBuilder = new(std::nothrow) PassManagerBuilder();<br>    if (PMBuilder == nullptr) {<br>        *error_message = strdup("memory allocation failure");<br>        return true;<br>    }<br>    PMBuilder->OptLevel = target_machine->getOptLevel();<br>    PMBuilder->SizeLevel = is_small ? 2 : 0;<br><br>    PMBuilder->DisableTailCalls = is_debug;<br>    PMBuilder->DisableUnitAtATime = is_debug;<br>    PMBuilder->DisableUnrollLoops = is_debug;<br>    PMBuilder->SLPVectorize = !is_debug;<br>    PMBuilder->LoopVectorize = !is_debug;<br>    PMBuilder->RerollLoops = !is_debug;<br>    // Leaving NewGVN as default (off) because when on it caused issue #673<br>    //PMBuilder->NewGVN = !is_debug;<br>    PMBuilder->DisableGVNLoadPRE = is_debug;<br>    PMBuilder->VerifyInput = assertions_on;<br>    PMBuilder->VerifyOutput = assertions_on;<br>    PMBuilder->MergeFunctions = !is_debug;<br>    PMBuilder->PrepareForLTO = false;<br>    PMBuilder->PrepareForThinLTO = false;<br>    PMBuilder->PerformThinLTO = false;<br><br>    TargetLibraryInfoImpl tlii(Triple(module->getTargetTriple()));<br>    PMBuilder->LibraryInfo = &tlii;<br><br>    if (is_debug) {<br>        PMBuilder->Inliner = createAlwaysInlinerLegacyPass(false);<br>    } else {<br>        target_machine->adjustPassManager(*PMBuilder);<br><br>        PMBuilder->addExtension(PassManagerBuilder::EP_EarlyAsPossible, addDiscriminatorsPass);<br>        PMBuilder->Inliner = createFunctionInliningPass(PMBuilder->OptLevel, PMBuilder->SizeLevel, false);<br>    }<br><br>    addCoroutinePassesToExtensionPoints(*PMBuilder);<br><br>    // Set up the per-function pass manager.<br>    legacy::FunctionPassManager FPM = legacy::FunctionPassManager(module);<br>    auto tliwp = new(std::nothrow) TargetLibraryInfoWrapperPass(tlii);<br>    FPM.add(tliwp);<br>    FPM.add(createTargetTransformInfoWrapperPass(target_machine->getTargetIRAnalysis()));<br>    if (assertions_on) {<br>        FPM.add(createVerifierPass());<br>    }<br>    PMBuilder->populateFunctionPassManager(FPM);<br><br>    // Set up the per-module pass manager.<br>    legacy::PassManager MPM;<br>    MPM.add(createTargetTransformInfoWrapperPass(target_machine->getTargetIRAnalysis()));<br>    PMBuilder->populateModulePassManager(MPM);<br><br>    // Set output pass.<br>    TargetMachine::CodeGenFileType ft;<br>    if (output_type != ZigLLVM_EmitLLVMIr) {<br>        switch (output_type) {<br>            case ZigLLVM_EmitAssembly:<br>                ft = TargetMachine::CGFT_AssemblyFile;<br>                break;<br>            case ZigLLVM_EmitBinary:<br>                ft = TargetMachine::CGFT_ObjectFile;<br>                break;<br>            default:<br>                abort();<br>        }<br><br>        if (target_machine->addPassesToEmitFile(MPM, dest, ft)) {<br>            *error_message = strdup("TargetMachine can't emit a file of this type");<br>            return true;<br>        }<br>    }<br><br>    // run per function optimization passes<br>    FPM.doInitialization();<br>    for (Function &F : *module)<br>      if (!F.isDeclaration())<br>        FPM.run(F);<br>    FPM.doFinalization();<br><br>    MPM.run(*module);<br><br>    if (output_type == ZigLLVM_EmitLLVMIr) {<br>        if (LLVMPrintModuleToFile(module_ref, filename, error_message)) {<br>            return true;<br>        }<br>    }<br><br>    return false;<br>}<br><br></span></div></div></div></div>