diff --git a/dmd/mars.h b/dmd/mars.h index 1873efd956..9bf63165c3 100644 --- a/dmd/mars.h +++ b/dmd/mars.h @@ -310,7 +310,6 @@ struct Param // Codegen cl options bool singleObj; bool disableRedZone; - bool noVerify; #endif }; diff --git a/dmd2/mars.h b/dmd2/mars.h index 233261de35..36dc7b51d7 100644 --- a/dmd2/mars.h +++ b/dmd2/mars.h @@ -276,7 +276,6 @@ struct Param // Codegen cl options bool singleObj; bool disableRedZone; - bool noVerify; #endif }; diff --git a/driver/cl_options.cpp b/driver/cl_options.cpp index 4374aa330c..6416e89e25 100644 --- a/driver/cl_options.cpp +++ b/driver/cl_options.cpp @@ -375,10 +375,6 @@ static cl::opt > release("release", cl::location(ReleaseSetter), cl::ValueDisallowed); -cl::opt noVerify("noverify", - llvm::cl::desc("Do not run the validation pass before writing bitcode"), - cl::location(global.params.noVerify)); - cl::opt singleObj("singleobj", cl::desc("Create only a single output object file"), cl::location(global.params.singleObj)); diff --git a/driver/main.cpp b/driver/main.cpp index 3e5319b1b2..e570907a12 100644 --- a/driver/main.cpp +++ b/driver/main.cpp @@ -325,8 +325,6 @@ int main(int argc, char** argv) #if LDC_LLVM_VER >= 301 llvm::TargetOptions targetOptions; - // FIXME: Options here are { None, Less, Default, Aggressive } as defined http://llvm.org/docs/doxygen/html/namespacellvm_1_1CodeGenOpt.html - llvm::CodeGenOpt::Level codeGenOptLevel = llvm::CodeGenOpt::None; // I am setting this to None for the moment as I dont know how this changes generation #endif Array* libs; @@ -554,7 +552,7 @@ int main(int argc, char** argv) targetOptions, mRelocModel, mCodeModel, - codeGenOptLevel + codeGenOptLevel() ); #endif diff --git a/driver/toobj.cpp b/driver/toobj.cpp index bdcb8982f6..3cb0097b09 100644 --- a/driver/toobj.cpp +++ b/driver/toobj.cpp @@ -33,22 +33,7 @@ void emit_file(llvm::TargetMachine &Target, llvm::Module& m, llvm::raw_fd_ostrea void writeModule(llvm::Module* m, std::string filename) { // run optimizer - bool reverify = ldc_optimize_module(m); - - // verify the llvm - if (!global.params.noVerify && reverify) { - std::string verifyErr; - Logger::println("Verifying module... again..."); - LOG_SCOPE; - if (llvm::verifyModule(*m,llvm::ReturnStatusAction,&verifyErr)) - { - error("%s", verifyErr.c_str()); - fatal(); - } - else { - Logger::println("Verification passed!"); - } - } + ldc_optimize_module(m); // eventually do our own path stuff, dmd's is a bit strange. typedef llvm::sys::Path LLPath; @@ -141,16 +126,8 @@ void emit_file(llvm::TargetMachine &Target, llvm::Module& m, llvm::raw_fd_ostrea else Passes.add(new TargetData(&m)); - // Last argument is enum CodeGenOpt::Level OptLevel - // debug info doesn't work properly with OptLevel != None! - CodeGenOpt::Level LastArg = CodeGenOpt::Default; - if (global.params.symdebug || !optimize()) - LastArg = CodeGenOpt::None; - else if (optLevel() >= 3) - LastArg = CodeGenOpt::Aggressive; - llvm::formatted_raw_ostream fout(out); - if (Target.addPassesToEmitFile(Passes, fout, fileType, LastArg)) + if (Target.addPassesToEmitFile(Passes, fout, fileType, codeGenOptLevel())) assert(0 && "no support for asm output"); Passes.doInitialization(); diff --git a/gen/module.cpp b/gen/module.cpp index 6ee6dd885d..e96d83caf2 100644 --- a/gen/module.cpp +++ b/gen/module.cpp @@ -29,6 +29,7 @@ #include "gen/structs.h" #include "gen/todebug.h" #include "gen/tollvm.h" +#include "gen/optimizer.h" #include "ir/irvar.h" #include "ir/irmodule.h" @@ -289,19 +290,7 @@ llvm::Module* Module::genLLVMModule(llvm::LLVMContext& context, Ir* sir) genmoduleinfo(); // verify the llvm - if (!global.params.noVerify) { - std::string verifyErr; - Logger::println("Verifying module..."); - LOG_SCOPE; - if (llvm::verifyModule(*ir.module,llvm::ReturnStatusAction,&verifyErr)) - { - error("%s", verifyErr.c_str()); - fatal(); - } - else { - Logger::println("Verification passed!"); - } - } + verifyModule(*ir.module); gIR = NULL; diff --git a/gen/optimizer.cpp b/gen/optimizer.cpp index 43015d0224..59dd4e9fd5 100644 --- a/gen/optimizer.cpp +++ b/gen/optimizer.cpp @@ -1,5 +1,6 @@ #include "gen/optimizer.h" #include "gen/cl_helpers.h" +#include "gen/logger.h" #include "gen/passes/Passes.h" @@ -39,6 +40,11 @@ static cl::opt optimizeLevel( clEnumValEnd), cl::init(0)); +static cl::opt +noVerify("disable-verify", + cl::desc("Do not verify result module"), + cl::Hidden); + static cl::opt verifyEach("verify-each", cl::desc("Run verifier after each optimization pass"), @@ -95,6 +101,22 @@ bool optimize() { return optimizeLevel || doInline() || !passList.empty(); } +llvm::CodeGenOpt::Level codeGenOptLevel() { +#if LDC_LLVM_VER < 302 + const int opt = optLevel(); + // Use same appoach as clang (see lib/CodeGen/BackendUtil.cpp) + llvm::CodeGenOpt::Level codeGenOptLevel = llvm::CodeGenOpt::Default; + // Debug info doesn't work properly with CodeGenOpt <> None + if (global.params.symdebug || !opt) codeGenOptLevel = llvm::CodeGenOpt::None; + else if (opt >= 3) codeGenOptLevel = llvm::CodeGenOpt::Aggressive; +#else + // There's a bug in llvm:LiveInterval::createDeadDef() + // which prevents use of other values. + // Happens only with 3.2 trunk. + return llvm::CodeGenOpt::None; +#endif +} + static void addPass(PassManager& pm, Pass* pass) { pm.add(pass); @@ -130,7 +152,7 @@ static void addPassesForOptLevel(PassManager& pm) { addPass(pm, createInstructionCombiningPass()); addPass(pm, createCFGSimplificationPass()); addPass(pm, createPruneEHPass()); - + addPass(pm, createFunctionAttrsPass()); addPass(pm, createTailCallEliminationPass()); @@ -260,5 +282,25 @@ bool ldc_optimize_module(llvm::Module* m) addPassesForOptLevel(pm); pm.run(*m); + + verifyModule(m); + return true; } + +// Verifies the module. +void verifyModule(llvm::Module* m) { + if (!noVerify) { + std::string verifyErr; + Logger::println("Verifying module..."); + LOG_SCOPE; + if (llvm::verifyModule(*m, llvm::ReturnStatusAction, &verifyErr)) + { + error("%s", verifyErr.c_str()); + fatal(); + } + else { + Logger::println("Verification passed!"); + } + } +} diff --git a/gen/optimizer.h b/gen/optimizer.h index 409e30ac53..7fe7c73ca6 100644 --- a/gen/optimizer.h +++ b/gen/optimizer.h @@ -1,6 +1,13 @@ #ifndef LDC_GEN_OPTIMIZER_H #define LDC_GEN_OPTIMIZER_H +// For llvm::CodeGenOpt::Level +#if LDC_LLVM_VER == 300 +#include "llvm/Target/TargetMachine.h" +#else +#include "llvm/Support/CodeGen.h" +#endif + namespace llvm { class Module; } bool ldc_optimize_module(llvm::Module* m); @@ -14,5 +21,9 @@ int optLevel(); bool optimize(); +llvm::CodeGenOpt::Level codeGenOptLevel(); + +void verifyModule(llvm::Module* m); + #endif