From 13864954060a8f0fec7ff419a180e440b8ef795c Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Tue, 24 Mar 2009 20:17:30 +0000 Subject: [PATCH] Driver: Handle -flto, -O4, and tweak -emit-llvm to match llvm-gcc. - -emit-llvm no longer changes what compilation steps are done. - -emit-llvm and -emit-llvm -S write output files with .o and .s suffixes, respectively. - clang-driver should support -O4 and -flto, like llvm-gcc llvm-svn: 67645 --- clang/include/clang/Driver/Options.def | 5 ++++- clang/include/clang/Driver/Types.def | 4 ++-- clang/lib/Driver/Driver.cpp | 11 +++++++++-- clang/lib/Driver/Tools.cpp | 9 ++++++--- clang/test/Driver/lto.c | 25 +++++++++++++++++++++++++ 5 files changed, 46 insertions(+), 8 deletions(-) create mode 100644 clang/test/Driver/lto.c diff --git a/clang/include/clang/Driver/Options.def b/clang/include/clang/Driver/Options.def index e8f156ae91b8..7c98bc06a31d 100644 --- a/clang/include/clang/Driver/Options.def +++ b/clang/include/clang/Driver/Options.def @@ -85,6 +85,7 @@ OPTION("", I_Group, Group, INVALID, INVALID, "", 0) OPTION("", M_Group, Group, INVALID, INVALID, "", 0) OPTION("", T_Group, Group, INVALID, INVALID, "", 0) +OPTION("", O_Group, Group, INVALID, INVALID, "", 0) OPTION("", W_Group, Group, INVALID, INVALID, "", 0) OPTION("", clang_W_Group, Group, W_Group, INVALID, "", 0) OPTION("", X_Group, Group, INVALID, INVALID, "", 0) @@ -247,9 +248,10 @@ OPTION("-MQ", MQ, JoinedOrSeparate, M_Group, INVALID, "", 0) OPTION("-MT", MT, JoinedOrSeparate, M_Group, INVALID, "", 0) OPTION("-Mach", Mach, Flag, INVALID, INVALID, "", 0) OPTION("-M", M, Flag, M_Group, INVALID, "", 0) +OPTION("-O4", O4, Joined, O_Group, INVALID, "", 0) OPTION("-ObjC++", ObjCXX, Flag, INVALID, INVALID, "d", 0) OPTION("-ObjC", ObjC, Flag, INVALID, INVALID, "d", 0) -OPTION("-O", O, Joined, INVALID, INVALID, "", 0) +OPTION("-O", O, Joined, O_Group, INVALID, "", 0) OPTION("-P", P, Flag, INVALID, INVALID, "", 0) OPTION("-Qn", Qn, Flag, INVALID, INVALID, "", 0) OPTION("-Q", Q, Flag, INVALID, INVALID, "", 0) @@ -373,6 +375,7 @@ OPTION("-findirect-virtual-calls", findirect_virtual_calls, Flag, f_Group, INVAL OPTION("-flat_namespace", flat__namespace, Flag, INVALID, INVALID, "", 0) OPTION("-flax-vector-conversions", flax_vector_conversions, Flag, clang_f_Group, INVALID, "", 0) OPTION("-flimited-precision=", flimited_precision_EQ, Joined, f_Group, INVALID, "", 0) +OPTION("-flto", flto, Flag, f_Group, INVALID, "", 0) OPTION("-fmath-errno", fmath_errno, Flag, f_Group, INVALID, "", 0) OPTION("-fmessage-length=", fmessage_length_EQ, Joined, clang_ignored_f_Group, INVALID, "", 0) OPTION("-fms-extensions", fms_extensions, Flag, clang_f_Group, INVALID, "", 0) diff --git a/clang/include/clang/Driver/Types.def b/clang/include/clang/Driver/Types.def index 7b1789f0d8fe..1902d44bfbfa 100644 --- a/clang/include/clang/Driver/Types.def +++ b/clang/include/clang/Driver/Types.def @@ -67,8 +67,8 @@ TYPE("f95-cpp-input", Fortran, PP_Fortran, 0, "u") TYPE("java", Java, INVALID, 0, "u") // Misc. -TYPE("llvm-asm", LLVMAsm, INVALID, "ll", "") -TYPE("llvm-bc", LLVMBC, INVALID, "bc", "") +TYPE("llvm-asm", LLVMAsm, INVALID, "s", "") +TYPE("llvm-bc", LLVMBC, INVALID, "o", "") TYPE("plist", Plist, INVALID, "plist", "") TYPE("precompiled-header", PCH, INVALID, "gch", "A") TYPE("object", Object, INVALID, "o", "") diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index c8ea4f8efe22..2ffd64191014 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -532,7 +532,6 @@ void Driver::BuildActions(const ArgList &Args, ActionList &Actions) const { // -{fsyntax-only,-analyze,emit-llvm,S} only run up to the compiler. } else if ((FinalPhaseArg = Args.getLastArg(options::OPT_fsyntax_only)) || (FinalPhaseArg = Args.getLastArg(options::OPT__analyze)) || - (FinalPhaseArg = Args.getLastArg(options::OPT_emit_llvm)) || (FinalPhaseArg = Args.getLastArg(options::OPT_S))) { FinalPhase = phases::Compile; @@ -588,6 +587,12 @@ void Driver::BuildActions(const ArgList &Args, ActionList &Actions) const { break; } + // Some types skip the assembler phase (e.g., llvm-bc), but we + // can't encode this in the steps because the intermediate type + // depends on arguments. Just special case here. + if (Phase == phases::Assemble && Current->getType() != types::TY_PP_Asm) + continue; + // Otherwise construct the appropriate action. Current = ConstructPhaseAction(Args, Phase, Current); if (Current->getType() == types::TY_Nothing) @@ -623,7 +628,9 @@ Action *Driver::ConstructPhaseAction(const ArgList &Args, phases::ID Phase, return new CompileJobAction(Input, types::TY_Nothing); } else if (Args.hasArg(options::OPT__analyze)) { return new AnalyzeJobAction(Input, types::TY_Plist); - } else if (Args.hasArg(options::OPT_emit_llvm)) { + } else if (Args.hasArg(options::OPT_emit_llvm) || + Args.hasArg(options::OPT_flto) || + Args.hasArg(options::OPT_O4)) { types::ID Output = Args.hasArg(options::OPT_S) ? types::TY_LLVMAsm : types::TY_LLVMBC; return new CompileJobAction(Input, Output); diff --git a/clang/lib/Driver/Tools.cpp b/clang/lib/Driver/Tools.cpp index bc5a7cf860ce..afb02fa49b5d 100644 --- a/clang/lib/Driver/Tools.cpp +++ b/clang/lib/Driver/Tools.cpp @@ -278,9 +278,12 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, A->render(Args, CmdArgs); } - // Manually translate -O to -O1; let clang reject others. - if (Arg *A = Args.getLastArg(options::OPT_O)) { - if (A->getValue(Args)[0] == '\0') + // Manually translate -O to -O1 and -O4 to -O3; let clang reject + // others. + if (Arg *A = Args.getLastArg(options::OPT_O_Group)) { + if (A->getOption().getId() == options::OPT_O4) + CmdArgs.push_back("-O3"); + else if (A->getValue(Args)[0] == '\0') CmdArgs.push_back("-O1"); else A->render(Args, CmdArgs); diff --git a/clang/test/Driver/lto.c b/clang/test/Driver/lto.c new file mode 100644 index 000000000000..01ef2ebc2e03 --- /dev/null +++ b/clang/test/Driver/lto.c @@ -0,0 +1,25 @@ +// -emit-llvm, -flto, and -O4 all cause a switch to llvm-bc object +// files. +// RUN: clang -ccc-print-phases -c %s -flto 2> %t.log && +// RUN: grep '2: compiler, {1}, llvm-bc' %t.log && +// RUN: clang -ccc-print-phases -c %s -O4 2> %t.log && +// RUN: grep '2: compiler, {1}, llvm-bc' %t.log && + +// and -emit-llvm doesn't alter pipeline (unfortunately?). +// RUN: clang -ccc-print-phases %s -emit-llvm 2> %t.log && +// RUN: grep '0: input, ".*lto.c", c' %t.log && +// RUN: grep '1: preprocessor, {0}, cpp-output' %t.log && +// RUN: grep '2: compiler, {1}, llvm-bc' %t.log && +// RUN: grep '3: linker, {2}, image' %t.log && + +// llvm-bc and llvm-ll outputs need to match regular suffixes +// (unfortunately). +// RUN: clang %s -emit-llvm -save-temps -### 2> %t.log && +// RUN: grep '"-o" ".*lto\.i" "-x" "c" ".*lto\.c"' %t.log && +// RUN: grep '"-o" ".*lto\.o" .*".*lto\.i"' %t.log && +// RUN: grep '".*a.out" .*".*lto\.o"' %t.log && + +// RUN: clang %s -emit-llvm -S -### 2> %t.log && +// RUN: grep '"-o" ".*lto\.s" "-x" "c" ".*lto\.c"' %t.log && + +// RUN: true