Skip to content

Commit

Permalink
Revert "[clang][IFS] Driver pipeline: generate interface stubs after …
Browse files Browse the repository at this point in the history
…standard pipeline."

This reverts commit 58ea00b.

Test for .o + .ifs sidecar files is brittle and failing on bots.
Reverting to unblock.
  • Loading branch information
plotfi committed Nov 19, 2019
1 parent 58ea00b commit d044dcc
Show file tree
Hide file tree
Showing 6 changed files with 37 additions and 123 deletions.
77 changes: 8 additions & 69 deletions clang/lib/Driver/Driver.cpp
Expand Up @@ -292,6 +292,10 @@ phases::ID Driver::getFinalPhase(const DerivedArgList &DAL,
(PhaseArg = DAL.getLastArg(options::OPT_emit_ast))) {
FinalPhase = phases::Compile;

// clang interface stubs
} else if ((PhaseArg = DAL.getLastArg(options::OPT_emit_interface_stubs))) {
FinalPhase = phases::IfsMerge;

// -S only runs up to the backend.
} else if ((PhaseArg = DAL.getLastArg(options::OPT_S))) {
FinalPhase = phases::Backend;
Expand Down Expand Up @@ -3498,68 +3502,6 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args,
Actions.push_back(
C.MakeAction<IfsMergeJobAction>(MergerInputs, types::TY_Image));

if (Arg *A = Args.getLastArg(options::OPT_emit_interface_stubs)) {
llvm::SmallVector<phases::ID, phases::MaxNumberOfPhases> PhaseList;
if (Args.hasArg(options::OPT_c)) {
llvm::SmallVector<phases::ID, phases::MaxNumberOfPhases> CompilePhaseList;
types::getCompilationPhases(types::TY_IFS_CPP, CompilePhaseList);
llvm::copy_if(PhaseList, std::back_inserter(CompilePhaseList),
[&](phases::ID Phase) { return Phase <= phases::Compile; });
} else {
types::getCompilationPhases(types::TY_IFS_CPP, PhaseList);
}

ActionList MergerInputs;

for (auto &I : Inputs) {
types::ID InputType = I.first;
const Arg *InputArg = I.second;

// Currently clang and the llvm assembler do not support generating symbol
// stubs from assembly, so we skip the input on asm files. For ifs files
// we rely on the normal pipeline setup in the pipeline setup code above.
if (InputType == types::TY_IFS || InputType == types::TY_PP_Asm ||
InputType == types::TY_Asm)
continue;

Action *Current = C.MakeAction<InputAction>(*InputArg, InputType);

for (auto Phase : PhaseList) {
switch (Phase) {
default:
llvm_unreachable(
"IFS Pipeline can only consist of Compile followed by IfsMerge.");
case phases::Compile: {
// Only IfsMerge (llvm-ifs) can handle .o files by looking for ifs
// files where the .o file is located. The compile action can not
// handle this.
if (InputType == types::TY_Object)
break;

Current = C.MakeAction<CompileJobAction>(Current, types::TY_IFS_CPP);
break;
}
case phases::IfsMerge: {
assert(Phase == PhaseList.back() &&
"merging must be final compilation step.");
MergerInputs.push_back(Current);
Current = nullptr;
break;
}
}
}

// If we ended with something, add to the output list.
if (Current)
Actions.push_back(Current);
}

// Add an interface stubs merge action if necessary.
if (!MergerInputs.empty())
Actions.push_back(
C.MakeAction<IfsMergeJobAction>(MergerInputs, types::TY_Image));
}

// If --print-supported-cpus, -mcpu=? or -mtune=? is specified, build a custom
// Compile phase that prints out supported cpu models and quits.
if (Arg *A = Args.getLastArg(options::OPT_print_supported_cpus)) {
Expand Down Expand Up @@ -3661,6 +3603,8 @@ Action *Driver::ConstructPhaseAction(
return C.MakeAction<CompileJobAction>(Input, types::TY_ModuleFile);
if (Args.hasArg(options::OPT_verify_pch))
return C.MakeAction<VerifyPCHJobAction>(Input, types::TY_Nothing);
if (Args.hasArg(options::OPT_emit_interface_stubs))
return C.MakeAction<CompileJobAction>(Input, types::TY_IFS_CPP);
return C.MakeAction<CompileJobAction>(Input, types::TY_LLVM_BC);
}
case phases::Backend: {
Expand Down Expand Up @@ -3689,16 +3633,11 @@ void Driver::BuildJobs(Compilation &C) const {
Arg *FinalOutput = C.getArgs().getLastArg(options::OPT_o);

// It is an error to provide a -o option if we are making multiple output
// files. There is one exception, IfsMergeJob: when generating interface stubs
// enabled we want to be able to generate the stub file at the same time that
// we generate the real library/a.out. So when a .o, .so, etc are the output,
// with clang interface stubs there will also be a .ifs and .ifso at the same
// location.
// files.
if (FinalOutput) {
unsigned NumOutputs = 0;
for (const Action *A : C.getActions())
if (A->getType() != types::TY_Nothing &&
A->getKind() != Action::IfsMergeJobClass)
if (A->getType() != types::TY_Nothing)
++NumOutputs;

if (NumOutputs > 1) {
Expand Down
36 changes: 6 additions & 30 deletions clang/lib/Driver/ToolChains/InterfaceStubs.cpp
Expand Up @@ -9,7 +9,6 @@
#include "InterfaceStubs.h"
#include "CommonArgs.h"
#include "clang/Driver/Compilation.h"
#include "llvm/Support/Path.h"

namespace clang {
namespace driver {
Expand All @@ -22,36 +21,13 @@ void Merger::ConstructJob(Compilation &C, const JobAction &JA,
std::string Merger = getToolChain().GetProgramPath(getShortName());
llvm::opt::ArgStringList CmdArgs;
CmdArgs.push_back("-action");
const bool WriteBin = !Args.getLastArg(options::OPT_emit_merged_ifs);
CmdArgs.push_back(WriteBin ? "write-bin" : "write-ifs");
CmdArgs.push_back(Args.getLastArg(options::OPT_emit_merged_ifs)
? "write-ifs"
: "write-bin");
CmdArgs.push_back("-o");

// Normally we want to write to a side-car file ending in ".ifso" so for
// example if `clang -emit-interface-stubs -shared -o libhello.so` were
// invoked then we would like to get libhello.so and libhello.ifso. If the
// stdout stream is given as the output file (ie `-o -`), that is the one
// exception where we will just append to the same filestream as the normal
// output.
SmallString<128> OutputFilename(Output.getFilename());
if (OutputFilename != "-") {
if (Args.hasArg(options::OPT_shared))
llvm::sys::path::replace_extension(OutputFilename,
(WriteBin ? "ifso" : "ifs"));
else
OutputFilename += ".ifso";
}

CmdArgs.push_back(Args.MakeArgString(OutputFilename.c_str()));

// Here we append the input files. If the input files are object files, then
// we look for .ifs files present in the same location as the object files.
for (const auto &Input : Inputs) {
SmallString<128> InputFilename(Input.getFilename());
if (Input.getType() == types::TY_Object)
llvm::sys::path::replace_extension(InputFilename, ".ifs");
CmdArgs.push_back(Args.MakeArgString(InputFilename.c_str()));
}

CmdArgs.push_back(Output.getFilename());
for (const auto &Input : Inputs)
CmdArgs.push_back(Input.getFilename());
C.addCommand(std::make_unique<Command>(JA, *this, Args.MakeArgString(Merger),
CmdArgs, Inputs));
}
Expand Down
16 changes: 16 additions & 0 deletions clang/lib/Driver/Types.cpp
Expand Up @@ -330,6 +330,22 @@ void types::getCompilationPhases(const clang::driver::Driver &Driver,
llvm::copy_if(PhaseList, std::back_inserter(P),
[](phases::ID Phase) { return Phase <= phases::Precompile; });

// Treat Interface Stubs like its own compilation mode.
else if (DAL.getLastArg(options::OPT_emit_interface_stubs)) {
llvm::SmallVector<phases::ID, phases::MaxNumberOfPhases> IfsModePhaseList;
llvm::SmallVector<phases::ID, phases::MaxNumberOfPhases> &PL = PhaseList;
phases::ID LastPhase = phases::IfsMerge;
if (Id != types::TY_IFS) {
if (DAL.hasArg(options::OPT_c))
LastPhase = phases::Compile;
PL = IfsModePhaseList;
types::getCompilationPhases(types::TY_IFS_CPP, PL);
}
llvm::copy_if(PL, std::back_inserter(P), [&](phases::ID Phase) {
return Phase <= LastPhase;
});
}

// -{fsyntax-only,-analyze,emit-ast} only run up to the compiler.
else if (DAL.getLastArg(options::OPT_fsyntax_only) ||
DAL.getLastArg(options::OPT_print_supported_cpus) ||
Expand Down
14 changes: 6 additions & 8 deletions clang/test/InterfaceStubs/driver-test.c
@@ -1,13 +1,11 @@
// REQUIRES: x86-registered-target

// RUN: %clang -target x86_64-unknown-linux-gnu -x c -o %t1 -emit-interface-stubs %s %S/object.c %S/weak.cpp
// RUN: llvm-nm %t1 2>&1 | FileCheck %s
// RUN: llvm-nm %t1.ifso 2>&1 | FileCheck %s
// RUN: %clang -target x86_64-unknown-linux-gnu -x c -o %t1.so -emit-interface-stubs %s %S/object.c %S/weak.cpp && \
// RUN: llvm-nm %t1.so 2>&1 | FileCheck --check-prefix=CHECK-IFS %s

// CHECK-DAG: data
// CHECK-DAG: foo
// CHECK-DAG: strongFunc
// CHECK-DAG: weakFunc
// CHECK-IFS-DAG: data
// CHECK-IFS-DAG: foo
// CHECK-IFS-DAG: strongFunc
// CHECK-IFS-DAG: weakFunc

int foo(int bar) { return 42 + 1844; }
int main() { return foo(23); }
14 changes: 0 additions & 14 deletions clang/test/InterfaceStubs/driver-test2.c

This file was deleted.

3 changes: 1 addition & 2 deletions clang/test/InterfaceStubs/windows.cpp
@@ -1,7 +1,6 @@
// REQUIRES: x86-registered-target
// RUN: %clang_cc1 -triple x86_64-windows-msvc -o - %s -emit-interface-stubs | FileCheck -check-prefix=CHECK-CC1 %s
// RUN: %clang -target x86_64-windows-msvc -o - %s -emit-interface-stubs -emit-merged-ifs -S | FileCheck -check-prefix=CHECK-IFS %s
// note: -S is added here to prevent clang from invoking link.exe
// RUN: %clang -target x86_64-windows-msvc -o - %s -emit-interface-stubs -emit-merged-ifs | FileCheck -check-prefix=CHECK-IFS %s

// CHECK-CC1: Symbols:
// CHECK-CC1-NEXT: ?helloWindowsMsvc@@YAHXZ
Expand Down

0 comments on commit d044dcc

Please sign in to comment.