Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #5459 #6220

Merged
merged 6 commits into from
Mar 21, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 18 additions & 5 deletions Make.inc
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ USE_INTEL_JITEVENTS = 0
# libc++ is standard on OS X 10.9, but not for earlier releases
USE_LIBCPP = 0

# Select the cpu architecture to target
# Current available options are "native" and "core2"
JULIA_CPU_TARGET = native

# we include twice to pickup user definitions better
ifeq (exists, $(shell [ -e $(JULIAHOME)/Make.user ] && echo exists ))
include $(JULIAHOME)/Make.user
Expand Down Expand Up @@ -208,6 +212,7 @@ endif
CC = $(CROSS_COMPILE)gcc
CXX = $(CROSS_COMPILE)g++
JCFLAGS = -std=gnu99 -pipe $(fPIC) -fno-strict-aliasing -D_FILE_OFFSET_BITS=64
JCPPFLAGS =
JCXXFLAGS = -pipe $(fPIC) -fno-rtti
DEBUGFLAGS = -O0 -ggdb3 -DDEBUG -fstack-protector-all
SHIPFLAGS = -O3 -falign-functions
Expand All @@ -217,6 +222,7 @@ ifeq ($(USECLANG),1)
CC = $(CROSS_COMPILE)clang
CXX = $(CROSS_COMPILE)clang++
JCFLAGS = -pipe $(fPIC) -fno-strict-aliasing -D_FILE_OFFSET_BITS=64
JCPPFLAGS =
JCXXFLAGS = -pipe $(fPIC) -fno-rtti
DEBUGFLAGS = -O0 -g -DDEBUG -fstack-protector-all
SHIPFLAGS = -O3
Expand All @@ -229,7 +235,7 @@ else
CC += $(STDLIBCPP_FLAG) -mmacosx-version-min=10.6
CXX += $(STDLIBCPP_FLAG) -mmacosx-version-min=10.6
endif
JCFLAGS += -D_LARGEFILE_SOURCE -D_DARWIN_USE_64_BIT_INODE=1
JCPPFLAGS += -D_LARGEFILE_SOURCE -D_DARWIN_USE_64_BIT_INODE=1
endif
endif

Expand All @@ -241,6 +247,14 @@ AS := $(CROSS_COMPILE)as
LD := $(CROSS_COMPILE)ld
RANLIB := $(CROSS_COMPILE)ranlib

ifeq ($(JULIA_CPU_TARGET),native)
JCPPFLAGS += -DJULIA_TARGET_NATIVE
else ifeq ($(JULIA_CPU_TARGET),core2)
JCPPFLAGS += -DJULIA_TARGET_CORE2
else
$(error Unknown cpu target architecture)
endif


# Calculate relative paths to libdir and private_libdir
build_libdir_rel = $(shell $(JULIAHOME)/contrib/relative_path.sh $(build_bindir) $(build_libdir))
Expand All @@ -250,7 +264,7 @@ build_private_libdir_rel = $(shell $(JULIAHOME)/contrib/relative_path.sh $(build
private_libdir_rel = $(shell $(JULIAHOME)/contrib/relative_path.sh $(bindir) $(private_libdir))

# if not absolute, then relative to the directory of the julia executable
JCFLAGS += "-DJL_SYSTEM_IMAGE_PATH=\"$(build_private_libdir_rel)/sys.ji\""
JCPPFLAGS += "-DJL_SYSTEM_IMAGE_PATH=\"$(build_private_libdir_rel)/sys.ji\""

# On Windows, we want shared library files to end up in $(build_bindir), instead of $(build_libdir)
ifeq ($(OS),WINNT)
Expand Down Expand Up @@ -321,7 +335,7 @@ endif
else
ifeq ($(OS),Darwin)
LIBUNWIND=$(build_libdir)/libosxunwind.a
JCFLAGS+=-DLIBOSXUNWIND
JCPPFLAGS+=-DLIBOSXUNWIND
else
LIBUNWIND=$(build_libdir)/libunwind-generic.a $(build_libdir)/libunwind.a
endif
Expand Down Expand Up @@ -485,8 +499,7 @@ endif
ifeq ($(OS), WINNT)
OSLIBS += -Wl,--export-all-symbols -Wl,--version-script=$(JULIAHOME)/src/julia.expmap \
$(NO_WHOLE_ARCHIVE) -lpsapi -lkernel32 -lws2_32 -liphlpapi -lwinmm -ldbghelp -lssp
JCFLAGS += -D_WIN32_WINNT=0x0600
JCXXFLAGS += -D_WIN32_WINNT=0x0600
JCPPFLAGS += -D_WIN32_WINNT=0x0600
JLDFLAGS = -Wl,--stack,8388608
ifeq ($(ARCH),i686)
JLDFLAGS += -Wl,--large-address-aware
Expand Down
9 changes: 3 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,7 @@ $(build_sysconfdir)/julia/juliarc.jl: contrib/windows/juliarc.jl
endif

# use sys.ji if it exists, otherwise run two stages
$(build_private_libdir)/sys%ji: $(build_private_libdir)/sys%bc

$(build_private_libdir)/sys%o: $(build_private_libdir)/sys%bc
$(call spawn,$(LLVM_LLC)) -filetype=obj -relocation-model=pic -mattr=-bmi2,-avx2 -o $(call cygpath_w,$@) $(call cygpath_w,$<)
$(build_private_libdir)/sys%ji: $(build_private_libdir)/sys%o

.PRECIOUS: $(build_private_libdir)/sys%o

Expand All @@ -77,11 +74,11 @@ $(build_private_libdir)/sys%$(SHLIB_EXT): $(build_private_libdir)/sys%o
$$([ $(OS) = Darwin ] && echo -Wl,-undefined,dynamic_lookup || echo -Wl,--unresolved-symbols,ignore-all ) \
$$([ $(OS) = WINNT ] && echo -ljulia -lssp)

$(build_private_libdir)/sys0.bc:
$(build_private_libdir)/sys0.o:
@$(QUIET_JULIA) cd base && \
$(call spawn,$(JULIA_EXECUTABLE)) --build $(call cygpath_w,$(build_private_libdir)/sys0) sysimg.jl

$(build_private_libdir)/sys.bc: VERSION base/*.jl base/pkg/*.jl base/linalg/*.jl base/sparse/*.jl $(build_datarootdir)/julia/helpdb.jl $(build_datarootdir)/man/man1/julia.1 $(build_private_libdir)/sys0.$(SHLIB_EXT)
$(build_private_libdir)/sys.o: VERSION base/*.jl base/pkg/*.jl base/linalg/*.jl base/sparse/*.jl $(build_datarootdir)/julia/helpdb.jl $(build_datarootdir)/man/man1/julia.1 $(build_private_libdir)/sys0.$(SHLIB_EXT)
@$(QUIET_JULIA) cd base && \
$(call spawn,$(JULIA_EXECUTABLE)) --build $(call cygpath_w,$(build_private_libdir)/sys) \
-J$(call cygpath_w,$(build_private_libdir))/$$([ -e $(build_private_libdir)/sys.ji ] && echo sys.ji || echo sys0.ji) -f sysimg.jl \
Expand Down
1 change: 1 addition & 0 deletions src/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ include $(JULIAHOME)/deps/Versions.make

override CFLAGS += $(JCFLAGS)
override CXXFLAGS += $(JCXXFLAGS)
override CPPFLAGS += $(JCPPFLAGS)

SRCS = \
jltypes gf ast builtins module codegen interpreter \
Expand Down
28 changes: 28 additions & 0 deletions src/cgutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,11 @@ extern "C" int32_t jl_get_llvm_gv(jl_value_t *p)
return 0;
return it->second.index;
}

extern "C" {
extern void jl_cpuid(int32_t CPUInfo[4], int32_t InfoType);
}

static void jl_gen_llvm_gv_array()
{
// emit the variable table into the code image (can only call this once)
Expand All @@ -234,6 +239,29 @@ static void jl_gen_llvm_gv_array()
GlobalVariable::ExternalLinkage,
ConstantInt::get(T_size,globalUnique+1),
"jl_globalUnique");

Constant *feature_string = ConstantDataArray::getString(jl_LLVMContext,jl_cpu_string);
new GlobalVariable(
*jl_Module,
feature_string->getType(),
true,
GlobalVariable::ExternalLinkage,
feature_string,
"jl_sysimg_cpu_target");

// For native also store the cpuid
if(strcmp(jl_cpu_string,"native") == 0) {
uint32_t info[4];

jl_cpuid((int32_t*)info, 1);
new GlobalVariable(
*jl_Module,
T_int64,
true,
GlobalVariable::ExternalLinkage,
ConstantInt::get(T_int64,((uint64_t)info[2])|(((uint64_t)info[3])<<32)),
"jl_sysimg_cpu_cpuid");
}
}

static int32_t jl_assign_functionID(Function *functionObject)
Expand Down
72 changes: 66 additions & 6 deletions src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,14 @@
#include "llvm/ExecutionEngine/JITEventListener.h"
#include "llvm/ExecutionEngine/JITMemoryManager.h"
#include "llvm/PassManager.h"
#include "llvm/Target/TargetLibraryInfo.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Analysis/Passes.h"
#include "llvm/Bitcode/ReaderWriter.h"
#if defined(LLVM_VERSION_MAJOR) && LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 5
#define LLVM35 1
#include "llvm/IR/Verifier.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/IR/DIBuilder.h"
#include "llvm/AsmParser/Parser.h"
#else
Expand Down Expand Up @@ -80,6 +83,7 @@
#include "llvm/Target/TargetOptions.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Transforms/Instrumentation.h"
#if defined(LLVM_VERSION_MAJOR) && LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 1
#include "llvm/Transforms/Vectorize.h"
#endif
Expand Down Expand Up @@ -127,6 +131,7 @@ static LLVMContext &jl_LLVMContext = getGlobalContext();
static IRBuilder<> builder(getGlobalContext());
static bool nested_compile=false;
static ExecutionEngine *jl_ExecutionEngine;
static TargetMachine *jl_TargetMachine;
#ifdef USE_MCJIT
static Module *shadow_module;
static RTDyldMemoryManager *jl_mcjmm;
Expand Down Expand Up @@ -302,6 +307,47 @@ void jl_dump_bitcode(char* fname)
#endif
}

extern "C"
void jl_dump_objfile(char* fname, int jit_model)
{
std::string err;
raw_fd_ostream OS(fname, err);
formatted_raw_ostream FOS(OS);
jl_gen_llvm_gv_array();

// We don't want to use MCJIT's target machine because
// it uses the large code model and we may potentially
// want less optimizations there.
OwningPtr<TargetMachine>
TM(jl_TargetMachine->getTarget().createTargetMachine(
jl_TargetMachine->getTargetTriple(),
jl_TargetMachine->getTargetCPU(),
jl_TargetMachine->getTargetFeatureString(),
jl_TargetMachine->Options,
#ifdef _OS_LINUX_
Reloc::PIC_,
#else
jit_model ? Reloc::PIC_ : Reloc::Default,
#endif
jit_model ? CodeModel::JITDefault : CodeModel::Default,
CodeGenOpt::Aggressive // -O3
));

PassManager PM;
PM.add(new TargetLibraryInfo(Triple(jl_TargetMachine->getTargetTriple())));
PM.add(new DataLayout(*jl_ExecutionEngine->getDataLayout()));
if (TM->addPassesToEmitFile(PM, FOS,
TargetMachine::CGFT_ObjectFile, false)) {
jl_error("Could not generate obj file for this target");
}

#ifdef USE_MCJIT
PM.run(*shadow_module);
#else
PM.run(*jl_Module);
#endif
}

// aggregate of array metadata
typedef struct {
Value *dataptr;
Expand Down Expand Up @@ -366,13 +412,20 @@ static Type *NoopType;

// --- utilities ---

#if defined(JULIA_TARGET_CORE2)
const char *jl_cpu_string = "core2";
#elif defined(JULIA_TARGET_NATIVE)
const char *jl_cpu_string = "native";
#else
#error "Must select julia cpu target"
#endif

extern "C" {
int globalUnique = 0;
}

#include "cgutils.cpp"


static void jl_rethrow_with_add(const char *fmt, ...)
{
if (jl_typeis(jl_exception_in_transit, jl_errorexception_type)) {
Expand Down Expand Up @@ -4082,23 +4135,30 @@ extern "C" void jl_init_codegen(void)
#endif
#ifdef USE_MCJIT
jl_mcjmm = new SectionMemoryManager();
#endif
#else
// Temporarily disable Haswell BMI2 features due to LLVM bug.
const char *mattr[] = {"-bmi2", "-avx2"};
#endif
std::vector<std::string> attrvec (mattr, mattr+2);
jl_ExecutionEngine = EngineBuilder(engine_module)
EngineBuilder eb = EngineBuilder(engine_module)
.setEngineKind(EngineKind::JIT)
#if defined(_OS_WINDOWS_) && defined(_CPU_X86_64_)
.setJITMemoryManager(new JITMemoryManagerWin())
#endif
.setTargetOptions(options)
#if defined(JULIA_TARGET_NATIVE)
.setMCPU("")
#else
.setMCPU(jl_cpu_string)
#endif
#ifdef USE_MCJIT
.setUseMCJIT(true)
.setMAttrs(attrvec)
.setMAttrs(attrvec);
#else
.setMAttrs(attrvec)
.setMAttrs(attrvec);
#endif
.create();
jl_TargetMachine = eb.selectTarget();
jl_ExecutionEngine = eb.create(jl_TargetMachine);
#endif // LLVM VERSION
jl_ExecutionEngine->DisableLazyCompilation();

Expand Down
24 changes: 23 additions & 1 deletion src/dump.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,11 @@ static void write_as_tag(ios_t *s, uint8_t tag)
static void jl_serialize_value_(ios_t *s, jl_value_t *v);
static jl_value_t *jl_deserialize_value(ios_t *s);
static jl_value_t *jl_deserialize_value_internal(ios_t *s);
static jl_value_t ***sysimg_gvars = NULL;
jl_value_t ***sysimg_gvars = NULL;

extern int globalUnique;
extern void jl_cpuid(int32_t CPUInfo[4], int32_t InfoType);
extern const char *jl_cpu_string;

static void jl_load_sysimg_so(char *fname)
{
Expand All @@ -108,6 +110,26 @@ static void jl_load_sysimg_so(char *fname)
if (sysimg_handle != 0) {
sysimg_gvars = (jl_value_t***)jl_dlsym(sysimg_handle, "jl_sysimg_gvars");
globalUnique = *(size_t*)jl_dlsym(sysimg_handle, "jl_globalUnique");
const char *cpu_target = (const char*)jl_dlsym(sysimg_handle, "jl_sysimg_cpu_target");
if (strcmp(cpu_target,jl_cpu_string) != 0)
jl_error("Julia and the system image were compiled for different architectures.\n"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Julia and the System Image" is our new band name.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Our first album cover:

julia child

"Please delete or regenerate sys.{so,dll,dylib}.");
uint32_t info[4];
jl_cpuid((int32_t*)info, 1);
if (strcmp(cpu_target,"native") == 0)
{
uint64_t saved_cpuid = *(uint64_t*)jl_dlsym(sysimg_handle, "jl_sysimg_cpu_cpuid");
if (saved_cpuid != (((uint64_t)info[2])|(((uint64_t)info[3])<<32)))
jl_error("Target architecture mismatch. Please delete or regenerate sys.{so,dll,dylib}.");
} else if(strcmp(cpu_target,"core2") == 0) {
int HasSSSE3 = (info[3] & 1<<9);
if (!HasSSSE3)
jl_error("The current host does not support SSSE3, but the system image was compiled for Core2.\n"
"Please delete or regenerate sys.{so,dll,dylib}.");
} else {
jl_error("System image has unknown target cpu architecture.\n"
"Please delete or regenerate sys.{so,dll,dylib}.");
}
}
else {
sysimg_gvars = 0;
Expand Down
10 changes: 5 additions & 5 deletions src/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -867,13 +867,13 @@ DLLEXPORT int julia_trampoline(int argc, char **argv, int (*pmain)(int ac,char *
if (asprintf(&build_ji, "%s.ji",build_path) > 0) {
jl_save_system_image(build_ji);
free(build_ji);
char *build_bc;
if (asprintf(&build_bc, "%s.bc",build_path) > 0) {
jl_dump_bitcode(build_bc);
free(build_bc);
char *build_o;
if (asprintf(&build_o, "%s.o",build_path) > 0) {
jl_dump_objfile(build_o,0);
free(build_o);
}
else {
ios_printf(ios_stderr,"FATAL: failed to create string for .bc build path");
ios_printf(ios_stderr,"FATAL: failed to create string for .o build path");
}
}
else {
Expand Down
1 change: 1 addition & 0 deletions src/julia_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ void jl_init_tasks(void *stack, size_t ssize);
void jl_init_serializer(void);

void jl_dump_bitcode(char *fname);
void jl_dump_objfile(char *fname, int jit_model);
int32_t jl_get_llvm_gv(jl_value_t *p);

#ifdef _OS_LINUX_
Expand Down
17 changes: 6 additions & 11 deletions src/sys.c
Original file line number Diff line number Diff line change
Expand Up @@ -409,15 +409,9 @@ JL_STREAM *jl_stdin_stream(void) { return (JL_STREAM*)JL_STDIN; }
JL_STREAM *jl_stdout_stream(void) { return (JL_STREAM*)JL_STDOUT; }
JL_STREAM *jl_stderr_stream(void) { return (JL_STREAM*)JL_STDERR; }

// -- set/clear the FZ/DAZ flags on x86 & x86-64 --

#ifdef __SSE__
// CPUID

#ifdef _OS_WINDOWS_
#define cpuid __cpuid
#else

void cpuid(int32_t CPUInfo[4], int32_t InfoType)
DLLEXPORT void jl_cpuid(int32_t CPUInfo[4], int32_t InfoType)
{
__asm__ __volatile__ (
#if defined(__i386__) && defined(__PIC__)
Expand All @@ -436,16 +430,17 @@ void cpuid(int32_t CPUInfo[4], int32_t InfoType)
);
}

#endif
// -- set/clear the FZ/DAZ flags on x86 & x86-64 --
#ifdef __SSE__

DLLEXPORT uint8_t jl_zero_subnormals(uint8_t isZero)
{
uint32_t flags = 0x00000000;
int32_t info[4];

cpuid(info, 0);
jl_cpuid(info, 0);
if (info[0] >= 1) {
cpuid(info, 0x00000001);
jl_cpuid(info, 0x00000001);
if ((info[3] & ((int)1 << 26)) != 0) {
// SSE2 supports both FZ and DAZ
flags = 0x00008040;
Expand Down
Loading