mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-01-12 02:43:14 +01:00
Merge pull request #91 from eldar/master
Split the compiler into a driver and a shared library.
This commit is contained in:
@@ -191,7 +191,7 @@ foreach(TARGET ${HOST_ARCH} ${EXTRA_LLVM_MODULES})
|
||||
endforeach(TARGET)
|
||||
|
||||
set_source_files_properties(
|
||||
${PROJECT_SOURCE_DIR}/gen/main.cpp PROPERTIES
|
||||
${PROJECT_SOURCE_DIR}/driver/main.cpp PROPERTIES
|
||||
COMPILE_DEFINITIONS LDC_TARGETS=${LLVM_MODULES_DEFINE}
|
||||
)
|
||||
|
||||
@@ -204,6 +204,7 @@ set_source_files_properties(
|
||||
file(GLOB_RECURSE FE_SRC ${DMDFE_PATH}/*.c ${DMDFE_PATH}/*.h)
|
||||
file(GLOB_RECURSE GEN_SRC gen/*.cpp gen/*.h)
|
||||
file(GLOB IR_SRC ir/*.cpp ir/*.h)
|
||||
file(GLOB_RECURSE DRV_SRC driver/*.cpp driver/*.h)
|
||||
# exclude idgen and impcnvgen and generated sources, just in case
|
||||
list(REMOVE_ITEM FE_SRC
|
||||
${PROJECT_SOURCE_DIR}/${DMDFE_PATH}/idgen.c
|
||||
@@ -266,9 +267,40 @@ endif(USE_METADATA)
|
||||
#
|
||||
# Set up the main ldc/ldc2 target.
|
||||
#
|
||||
if(BUILD_SHARED)
|
||||
set(LDC_LIB_TYPE SHARED)
|
||||
else(BUILD_SHARED)
|
||||
set(LDC_LIB_TYPE STATIC)
|
||||
endif(BUILD_SHARED)
|
||||
|
||||
set(LDC_LIB LDCShared)
|
||||
add_library(${LDC_LIB} ${LDC_LIB_TYPE} ${LDC_SOURCE_FILES})
|
||||
# Build ldc
|
||||
set_target_properties(
|
||||
${LDC_LIB} PROPERTIES
|
||||
RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin
|
||||
LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib
|
||||
ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib
|
||||
ARCHIVE_OUTPUT_NAME ldc
|
||||
LIBRARY_OUTPUT_NAME ldc
|
||||
RUNTIME_OUTPUT_NAME ldc
|
||||
COMPILE_FLAGS "${LLVM_CXXFLAGS} ${LIBCONFIG_CXXFLAGS} -Wno-deprecated -Wno-write-strings -fexceptions"
|
||||
)
|
||||
|
||||
# LDFLAGS should actually be in target property LINK_FLAGS, but this works, and gets around linking problems
|
||||
target_link_libraries(${LDC_LIB} "${LLVM_LDFLAGS} ${LLVM_LIBRARIES}")
|
||||
if(WIN32)
|
||||
target_link_libraries(${LDC_LIB} imagehlp psapi)
|
||||
elseif(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
target_link_libraries(${LDC_LIB} dl)
|
||||
endif(WIN32)
|
||||
|
||||
if(USE_BOEHM_GC)
|
||||
target_link_libraries(${LDC_LIB} ${PROJECT_SOURCE_DIR}/libgc.a)
|
||||
endif(USE_BOEHM_GC)
|
||||
|
||||
# Path where ldc executable will be put
|
||||
add_executable(${LDC_EXE} ${LDC_SOURCE_FILES})
|
||||
add_executable(${LDC_EXE} ${DRV_SRC})
|
||||
# Name of ldc executable
|
||||
set(LDC_EXE_NAME ${PROGRAM_PREFIX}${LDC_EXE}${PROGRAM_SUFFIX})
|
||||
# Build ldc
|
||||
@@ -278,18 +310,8 @@ set_target_properties(
|
||||
RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin
|
||||
COMPILE_FLAGS "${LLVM_CXXFLAGS} ${LIBCONFIG_CXXFLAGS} -Wno-deprecated -Wno-write-strings -fexceptions"
|
||||
)
|
||||
target_link_libraries(${LDC_EXE} ${LDC_LIB} ${LIBCONFIG_LDFLAGS} config++)
|
||||
|
||||
# LDFLAGS should actually be in target property LINK_FLAGS, but this works, and gets around linking problems
|
||||
target_link_libraries(${LDC_EXE} "${LLVM_LDFLAGS} ${LLVM_LIBRARIES}" ${LIBCONFIG_LDFLAGS} config++)
|
||||
if(WIN32)
|
||||
target_link_libraries(${LDC_EXE} imagehlp psapi)
|
||||
elseif(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
target_link_libraries(${LDC_EXE} dl)
|
||||
endif(WIN32)
|
||||
|
||||
if(USE_BOEHM_GC)
|
||||
target_link_libraries(${LDC_EXE} ${PROJECT_SOURCE_DIR}/libgc.a)
|
||||
endif(USE_BOEHM_GC)
|
||||
|
||||
get_target_property(LDC_LOC ${LDC_EXE} LOCATION)
|
||||
|
||||
@@ -300,6 +322,7 @@ get_target_property(LDC_LOC ${LDC_EXE} LOCATION)
|
||||
add_subdirectory(runtime)
|
||||
|
||||
install(TARGETS ${LDC_EXE} DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)
|
||||
install(TARGETS ${LDC_LIB} DESTINATION ${CMAKE_INSTALL_PREFIX}/lib)
|
||||
install(PROGRAMS ${PROJECT_SOURCE_DIR}/bin/${LDMD_EXE} DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)
|
||||
install(FILES ${PROJECT_BINARY_DIR}/bin/${LDC_EXE}_install.conf DESTINATION ${CONF_INST_DIR} RENAME ${LDC_EXE}.conf)
|
||||
install(FILES ${PROJECT_BINARY_DIR}/bin/${LDC_EXE}_install.rebuild.conf DESTINATION ${CONF_INST_DIR} RENAME ${LDC_EXE}.rebuild.conf)
|
||||
|
||||
@@ -306,6 +306,11 @@ struct Param
|
||||
const char* llvmArch;
|
||||
const char *targetTriple;
|
||||
const char *dataLayout;
|
||||
|
||||
// Codegen cl options
|
||||
bool singleObj;
|
||||
bool disableRedZone;
|
||||
bool noVerify;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@@ -272,6 +272,11 @@ struct Param
|
||||
const char* llvmArch;
|
||||
const char *targetTriple;
|
||||
const char *dataLayout;
|
||||
|
||||
// Codegen cl options
|
||||
bool singleObj;
|
||||
bool disableRedZone;
|
||||
bool noVerify;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "gen/cl_options.h"
|
||||
#include "driver/cl_options.h"
|
||||
#include "gen/cl_helpers.h"
|
||||
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
@@ -132,8 +132,9 @@ cl::opt<cl::boolOrDefault> output_o("output-o",
|
||||
cl::desc("Write native object"));
|
||||
|
||||
// Disabling Red Zone
|
||||
cl::opt<bool> disableRedZone("disable-red-zone",
|
||||
cl::opt<bool, true> disableRedZone("disable-red-zone",
|
||||
cl::desc("Do not emit code that uses the red zone."),
|
||||
cl::location(global.params.disableRedZone),
|
||||
cl::init(false));
|
||||
|
||||
// DDoc options
|
||||
@@ -360,7 +361,7 @@ static cl::opt<bool, true, FlagParser> postconditions("postconditions",
|
||||
cl::init(true));
|
||||
|
||||
|
||||
static MultiSetter ContractsSetter(false,
|
||||
static MultiSetter ContractsSetter(false,
|
||||
&global.params.useIn, &global.params.useOut, NULL);
|
||||
static cl::opt<MultiSetter, true, FlagParser> contracts("contracts",
|
||||
cl::desc("(*) Enable function pre- and post-conditions"),
|
||||
@@ -374,10 +375,13 @@ static cl::opt<MultiSetter, true, cl::parser<bool> > release("release",
|
||||
cl::location(ReleaseSetter),
|
||||
cl::ValueDisallowed);
|
||||
|
||||
cl::opt<bool, true> noVerify("noverify",
|
||||
llvm::cl::desc("Do not run the validation pass before writing bitcode"),
|
||||
cl::location(global.params.noVerify));
|
||||
|
||||
cl::opt<bool> singleObj("singleobj",
|
||||
cl::opt<bool, true> singleObj("singleobj",
|
||||
cl::desc("Create only a single output object file"),
|
||||
cl::ZeroOrMore);
|
||||
cl::location(global.params.singleObj));
|
||||
|
||||
cl::opt<bool> linkonceTemplates("linkonce-templates",
|
||||
cl::desc("Use linkonce_odr linkage for template symbols instead of weak_odr"),
|
||||
@@ -33,7 +33,7 @@ namespace opts {
|
||||
extern cl::opt<bool> output_ll;
|
||||
extern cl::opt<bool> output_s;
|
||||
extern cl::opt<cl::boolOrDefault> output_o;
|
||||
extern cl::opt<bool> disableRedZone;
|
||||
extern cl::opt<bool, true> disableRedZone;
|
||||
extern cl::opt<std::string> ddocDir;
|
||||
extern cl::opt<std::string> ddocFile;
|
||||
extern cl::opt<std::string> jsonFile;
|
||||
@@ -50,7 +50,7 @@ namespace opts {
|
||||
extern cl::opt<std::string> mTargetTriple;
|
||||
extern cl::opt<llvm::Reloc::Model> mRelocModel;
|
||||
extern cl::opt<llvm::CodeModel::Model> mCodeModel;
|
||||
extern cl::opt<bool> singleObj;
|
||||
extern cl::opt<bool, true> singleObj;
|
||||
extern cl::opt<bool> linkonceTemplates;
|
||||
|
||||
// Arguments to -d-debug
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
#include "libconfig.h++"
|
||||
|
||||
#include "gen/configfile.h"
|
||||
#include "driver/configfile.h"
|
||||
|
||||
#include "mars.h"
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
#include "gen/linker.h"
|
||||
#include "gen/llvm.h"
|
||||
#include "llvm/Linker.h"
|
||||
#include "llvm/Support/FileSystem.h"
|
||||
@@ -13,10 +12,12 @@
|
||||
|
||||
#define NO_COUT_LOGGER
|
||||
#include "gen/logger.h"
|
||||
#include "gen/cl_options.h"
|
||||
#include "gen/optimizer.h"
|
||||
#include "gen/programs.h"
|
||||
|
||||
#include "driver/linker.h"
|
||||
#include "driver/cl_options.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Is this useful?
|
||||
@@ -30,18 +30,18 @@
|
||||
|
||||
#include "gen/logger.h"
|
||||
#include "gen/linkage.h"
|
||||
#include "gen/linker.h"
|
||||
#include "gen/irstate.h"
|
||||
#include "gen/optimizer.h"
|
||||
#include "gen/toobj.h"
|
||||
#include "gen/metadata.h"
|
||||
#include "gen/passes/Passes.h"
|
||||
|
||||
#include "gen/cl_options.h"
|
||||
#include "driver/linker.h"
|
||||
#include "driver/cl_options.h"
|
||||
#include "gen/cl_helpers.h"
|
||||
using namespace opts;
|
||||
|
||||
#include "gen/configfile.h"
|
||||
#include "driver/configfile.h"
|
||||
#include "driver/toobj.h"
|
||||
|
||||
#if POSIX
|
||||
#include <errno.h>
|
||||
169
driver/toobj.cpp
Normal file
169
driver/toobj.cpp
Normal file
@@ -0,0 +1,169 @@
|
||||
|
||||
// Copyright (c) 1999-2004 by Digital Mars
|
||||
// All Rights Reserved
|
||||
// written by Walter Bright
|
||||
// www.digitalmars.com
|
||||
// License for redistribution is by either the Artistic License
|
||||
// in artistic.txt, or the GNU General Public License in gnu.txt.
|
||||
// See the included readme.txt for details.
|
||||
|
||||
#include <cstddef>
|
||||
#include <fstream>
|
||||
|
||||
#include "llvm/Analysis/Verifier.h"
|
||||
#include "llvm/Bitcode/ReaderWriter.h"
|
||||
#include "llvm/Module.h"
|
||||
#include "llvm/PassManager.h"
|
||||
#include "llvm/Support/Program.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/FormattedStream.h"
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
|
||||
#include "gen/irstate.h"
|
||||
#include "gen/logger.h"
|
||||
#include "gen/optimizer.h"
|
||||
|
||||
|
||||
// fwd decl
|
||||
void emit_file(llvm::TargetMachine &Target, llvm::Module& m, llvm::raw_fd_ostream& Out,
|
||||
llvm::TargetMachine::CodeGenFileType fileType);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
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!");
|
||||
}
|
||||
}
|
||||
|
||||
// eventually do our own path stuff, dmd's is a bit strange.
|
||||
typedef llvm::sys::Path LLPath;
|
||||
|
||||
// write LLVM bitcode
|
||||
if (global.params.output_bc) {
|
||||
LLPath bcpath = LLPath(filename);
|
||||
bcpath.eraseSuffix();
|
||||
bcpath.appendSuffix(std::string(global.bc_ext));
|
||||
Logger::println("Writing LLVM bitcode to: %s\n", bcpath.c_str());
|
||||
std::string errinfo;
|
||||
llvm::raw_fd_ostream bos(bcpath.c_str(), errinfo, llvm::raw_fd_ostream::F_Binary);
|
||||
if (bos.has_error())
|
||||
{
|
||||
error("cannot write LLVM bitcode file '%s': %s", bcpath.c_str(), errinfo.c_str());
|
||||
fatal();
|
||||
}
|
||||
llvm::WriteBitcodeToFile(m, bos);
|
||||
}
|
||||
|
||||
// write LLVM IR
|
||||
if (global.params.output_ll) {
|
||||
LLPath llpath = LLPath(filename);
|
||||
llpath.eraseSuffix();
|
||||
llpath.appendSuffix(std::string(global.ll_ext));
|
||||
Logger::println("Writing LLVM asm to: %s\n", llpath.c_str());
|
||||
std::string errinfo;
|
||||
llvm::raw_fd_ostream aos(llpath.c_str(), errinfo);
|
||||
if (aos.has_error())
|
||||
{
|
||||
error("cannot write LLVM asm file '%s': %s", llpath.c_str(), errinfo.c_str());
|
||||
fatal();
|
||||
}
|
||||
m->print(aos, NULL);
|
||||
}
|
||||
|
||||
// write native assembly
|
||||
if (global.params.output_s) {
|
||||
LLPath spath = LLPath(filename);
|
||||
spath.eraseSuffix();
|
||||
spath.appendSuffix(std::string(global.s_ext));
|
||||
Logger::println("Writing native asm to: %s\n", spath.c_str());
|
||||
std::string err;
|
||||
{
|
||||
llvm::raw_fd_ostream out(spath.c_str(), err);
|
||||
if (err.empty())
|
||||
{
|
||||
emit_file(*gTargetMachine, *m, out, llvm::TargetMachine::CGFT_AssemblyFile);
|
||||
}
|
||||
else
|
||||
{
|
||||
error("cannot write native asm: %s", err.c_str());
|
||||
fatal();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (global.params.output_o) {
|
||||
LLPath objpath = LLPath(filename);
|
||||
Logger::println("Writing object file to: %s\n", objpath.c_str());
|
||||
std::string err;
|
||||
{
|
||||
llvm::raw_fd_ostream out(objpath.c_str(), err, llvm::raw_fd_ostream::F_Binary);
|
||||
if (err.empty())
|
||||
{
|
||||
emit_file(*gTargetMachine, *m, out, llvm::TargetMachine::CGFT_ObjectFile);
|
||||
}
|
||||
else
|
||||
{
|
||||
error("cannot write object file: %s", err.c_str());
|
||||
fatal();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ================================================================== */
|
||||
|
||||
// based on llc code, University of Illinois Open Source License
|
||||
void emit_file(llvm::TargetMachine &Target, llvm::Module& m, llvm::raw_fd_ostream& out,
|
||||
llvm::TargetMachine::CodeGenFileType fileType)
|
||||
{
|
||||
using namespace llvm;
|
||||
|
||||
// Build up all of the passes that we want to do to the module.
|
||||
FunctionPassManager Passes(&m);
|
||||
|
||||
if (const TargetData *TD = Target.getTargetData())
|
||||
Passes.add(new TargetData(*TD));
|
||||
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))
|
||||
assert(0 && "no support for asm output");
|
||||
|
||||
Passes.doInitialization();
|
||||
|
||||
// Run our queue of passes all at once now, efficiently.
|
||||
for (llvm::Module::iterator I = m.begin(), E = m.end(); I != E; ++I)
|
||||
if (!I->isDeclaration())
|
||||
Passes.run(*I);
|
||||
|
||||
Passes.doFinalization();
|
||||
|
||||
// release module from module provider so we can delete it ourselves
|
||||
//std::string Err;
|
||||
//llvm::Module* rmod = Provider.releaseModule(&Err);
|
||||
//assert(rmod);
|
||||
}
|
||||
@@ -17,8 +17,6 @@
|
||||
#include "ir/irmodule.h"
|
||||
#include "ir/irtypestruct.h"
|
||||
|
||||
#include "gen/cl_options.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static LLValue *DtoSlice(DValue *dval)
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
#include "gen/dvalue.h"
|
||||
#include "gen/abi.h"
|
||||
#include "gen/nested.h"
|
||||
#include "gen/cl_options.h"
|
||||
#include "gen/pragma.h"
|
||||
|
||||
using namespace llvm::Attribute;
|
||||
@@ -510,7 +509,7 @@ void DtoDeclareFunction(FuncDeclaration* fdecl)
|
||||
// parameter attributes
|
||||
if (!fdecl->isIntrinsic()) {
|
||||
set_param_attrs(f, func, fdecl);
|
||||
if (opts::disableRedZone) {
|
||||
if (global.params.disableRedZone) {
|
||||
func->addFnAttr(NoRedZone);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
#include "linkage.h"
|
||||
#include "gen/cl_options.h"
|
||||
|
||||
LLGlobalValue::LinkageTypes templateLinkage;
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
#include "gen/functions.h"
|
||||
#include "gen/typeinf.h"
|
||||
#include "gen/todebug.h"
|
||||
#include "gen/cl_options.h"
|
||||
#include "gen/nested.h"
|
||||
#include "ir/irmodule.h"
|
||||
|
||||
@@ -1649,7 +1648,7 @@ bool mustDefineSymbol(Dsymbol* s)
|
||||
TemplateInstance* tinst = DtoIsTemplateInstance(s);
|
||||
if (tinst)
|
||||
{
|
||||
if (!opts::singleObj)
|
||||
if (!global.params.singleObj)
|
||||
return true;
|
||||
|
||||
if (!tinst->emittedInModule)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user