This is an archive of the discontinued LLVM Phabricator instance.

Not for review -- test for not spawning subprocess for -cc1
Needs ReviewPublic

Authored by thakis on Sep 24 2018, 5:23 AM.
This revision needs review, but there are no reviewers specified.

Details

Reviewers
None
Summary

Instead, let driver directly call Frontend's main()

Diff Detail

Event Timeline

thakis created this revision.Sep 24 2018, 5:23 AM
aganea added a subscriber: aganea.Oct 10 2018, 11:31 AM

This patch doesn't link on Windows/VS2017 as main() is not in the same library as clangDriver. So I went ahead and added the following in clang/trunk/tools/driver/driver.cpp:

int main(int argc_, const char **argv_) {
  llvm::InitLLVM X(argc_, argv_);
  SmallVector<const char *, 256> argv(argv_, argv_ + argc_);

  if (llvm::sys::Process::FixupStandardFileDescriptors())
    return (int)llvm::sys::ProgramReturnCode::Failure;

  llvm::InitializeAllTargets();
  auto TargetAndMode = ToolChain::getTargetAndModeFromProgramName(argv[0]);

  llvm::BumpPtrAllocator A;
  llvm::StringSaver Saver(A);

  llvm::sys::DynamicLibrary::AddSymbol("main", &main); /////////////////////////////////////// here

  // Parse response files using the GNU syntax, unless we're in CL mode. There
  // are two ways to put clang in CL compatibility mode: argv[0] is either
  // clang-cl or cl, or --driver-mode=cl is on the command line. The normal
  // command line parsing can't happen until after response file parsing, so we
  // have to manually search for a --driver-mode=cl argument the hard way.
  // Finally, our -cc1 tools don't care which tokenization mode we use because
  // response files written by clang will tokenize the same way in either mode.

Then I've called it from Compilation.cpp with:

void Compilation::ExecuteJobs(const JobList &Jobs,
                              FailingCommandList &FailingCommands) const {
  if (Jobs.size() == 1) {
    Command &C = *Jobs.begin();
    if (C.getExecutable() == getDriver().getClangProgramPath()) {
      ArgStringList Args = C.getArguments();
      Args.insert(Args.begin(), C.getExecutable());
      //main(Args.size(), const_cast<const char **>(&Args[0]));

      MainFn M = FuncPtr<MainFn>(llvm::sys::DynamicLibrary::SearchForAddressOfSymbol("main"));
      M(Args.size(), const_cast<const char **>(&Args[0]));
    }
    return;
  }

Cross referencing https://reviews.llvm.org/D52193#1260825 here:

Updated tests again. This time I've closed all applications, all unused services, and tried to have a "clean" machine.

New timings without the child clang-cl.exe being invoked (hacked from D52411). The test consists in building Clang+LLVM+LLD at r343846 using the compiler specified on each line of the table.

Config 1: Intel Xeon Haswell 6 cores / 12 HW threads, 3.5 GHz, 15 MB cache, 128 GB RAM, SSD 550 MB/s (Windows 10 Fall Creators update 1709)

Ninja:

MSVC 15.8.6 (cl + link)29 min 4 sec
clang-cl + lld-link 7.0 official release25 min 45 sec
clang-cl + lld-link 8.0 r343846 built with clang-cl 7.0 official (+D52411, no child)23 min 27 sec

Config 2: Intel Xeon Skylake 18 cores / 36 HW threads, x2 (Dual CPU), 72 HW threads total, 2.3 GHz, 24.75 MB cache each, 128 GB RAM, NVMe SSD 4.6 GB/s (Windows 10 Fall Creators update 1709)

Ninja:

MSVC 15.8.6 (cl + link)6 min 40 sec
clang-cl + lld-link 7.0 official release6 min 24 sec
clang-cl + lld-link 8.0 r343846 built with clang-cl 7.0 official (+D52411, no child)5 min 10 sec

I'm wondering if the improvement is of the same order on Linux. I'd be interested to see your build times, out of curiosity? Can any of you try it with and without D52411?

This patch doesn't link on Windows/VS2017 as main() is not in the same library as clangDriver

Huh, I would've expected this to not matter. Are you building all the parts of clang as different .dlls? clangDriver should just become a .lib, and then stuff gets all linked together in a single executable at the end.

This patch doesn't link on Windows/VS2017 as main() is not in the same library as clangDriver

Huh, I would've expected this to not matter. Are you building all the parts of clang as different .dlls? clangDriver should just become a .lib, and then stuff gets all linked together in a single executable at the end.

It's actually libclang.dll that doesn't compile - not a big deal.

121>   Creating library F:/svn/build/Release/lib/libclang.lib and object F:/svn/build/Release/lib/libclang.exp
121>clangDriver.lib(Compilation.obj) : error LNK2019: unresolved external symbol main referenced in function "public: void __cdecl clang::driver::Compilation::executeJobs(class llvm::SmallVectorImpl<struct clang::driver::JobExecutionState> &)" (?executeJobs@Compilation@driver@clang@@QEAAXAEAV?$SmallVectorImpl@UJobExecutionState@driver@clang@@@llvm@@@Z)
121>F:\svn\build\Release\bin\libclang.dll : fatal error LNK1120: 1 unresolved externals
lenary added a subscriber: lenary.Sep 14 2019, 5:38 AM