Fix for Windows build and making NEON target optional

This commit is contained in:
Dmitry Babokin
2013-08-02 19:24:34 -07:00
parent fb34fc5a85
commit dff7735af9
6 changed files with 53 additions and 23 deletions

View File

@@ -39,6 +39,10 @@
LLVM_CONFIG=$(shell which llvm-config) LLVM_CONFIG=$(shell which llvm-config)
CLANG_INCLUDE=$(shell $(LLVM_CONFIG) --includedir) CLANG_INCLUDE=$(shell $(LLVM_CONFIG) --includedir)
# Enable ARM by request
# To enable: make ARM_ENABLED=ON
ARM_ENABLED=OFF
# Add llvm bin to the path so any scripts run will go to the right llvm-config # Add llvm bin to the path so any scripts run will go to the right llvm-config
LLVM_BIN= $(shell $(LLVM_CONFIG) --bindir) LLVM_BIN= $(shell $(LLVM_CONFIG) --bindir)
export PATH:=$(LLVM_BIN):$(PATH) export PATH:=$(LLVM_BIN):$(PATH)
@@ -55,12 +59,15 @@ LLVM_CXXFLAGS=$(shell $(LLVM_CONFIG) --cppflags)
LLVM_VERSION=LLVM_$(shell $(LLVM_CONFIG) --version | sed -e s/\\./_/ -e s/svn//) LLVM_VERSION=LLVM_$(shell $(LLVM_CONFIG) --version | sed -e s/\\./_/ -e s/svn//)
LLVM_VERSION_DEF=-D$(LLVM_VERSION) LLVM_VERSION_DEF=-D$(LLVM_VERSION)
LLVM_COMPONENTS = engine ipo bitreader bitwriter instrumentation linker arm LLVM_COMPONENTS = engine ipo bitreader bitwriter instrumentation linker
# Component "option" was introduced in 3.3 and starting with 3.4 it is required for the link step. # Component "option" was introduced in 3.3 and starting with 3.4 it is required for the link step.
# We check if it's available before adding it (to not break 3.2 and earlier). # We check if it's available before adding it (to not break 3.2 and earlier).
ifeq ($(shell $(LLVM_CONFIG) --components |grep -c option), 1) ifeq ($(shell $(LLVM_CONFIG) --components |grep -c option), 1)
LLVM_COMPONENTS+=option LLVM_COMPONENTS+=option
endif endif
ifeq ($(ARM_ENABLED), ON)
LLVM_COMPONENTS+=arm
endif
LLVM_LIBS=$(shell $(LLVM_CONFIG) --libs $(LLVM_COMPONENTS)) LLVM_LIBS=$(shell $(LLVM_CONFIG) --libs $(LLVM_COMPONENTS))
CLANG=clang CLANG=clang
@@ -104,6 +111,9 @@ OPT=-O2
CXXFLAGS=$(OPT) $(LLVM_CXXFLAGS) -I. -Iobjs/ -I$(CLANG_INCLUDE) \ CXXFLAGS=$(OPT) $(LLVM_CXXFLAGS) -I. -Iobjs/ -I$(CLANG_INCLUDE) \
-Wall $(LLVM_VERSION_DEF) \ -Wall $(LLVM_VERSION_DEF) \
-DBUILD_DATE="\"$(BUILD_DATE)\"" -DBUILD_VERSION="\"$(BUILD_VERSION)\"" -DBUILD_DATE="\"$(BUILD_DATE)\"" -DBUILD_VERSION="\"$(BUILD_VERSION)\""
ifeq ($(ARM_ENABLED), ON)
CXXFLAGS+=-DISPC_ARM_ENABLED
endif
LDFLAGS= LDFLAGS=
ifeq ($(ARCH_OS),Linux) ifeq ($(ARCH_OS),Linux)
@@ -122,8 +132,11 @@ CXX_SRC=ast.cpp builtins.cpp cbackend.cpp ctx.cpp decl.cpp expr.cpp func.cpp \
type.cpp util.cpp type.cpp util.cpp
HEADERS=ast.h builtins.h ctx.h decl.h expr.h func.h ispc.h llvmutil.h module.h \ HEADERS=ast.h builtins.h ctx.h decl.h expr.h func.h ispc.h llvmutil.h module.h \
opt.h stmt.h sym.h type.h util.h opt.h stmt.h sym.h type.h util.h
TARGETS=neon avx1 avx1-x2 avx11 avx11-x2 avx2 avx2-x2 sse2 sse2-x2 sse4 sse4-x2 \ TARGETS=avx1 avx1-x2 avx11 avx11-x2 avx2 avx2-x2 sse2 sse2-x2 sse4 sse4-x2 \
generic-4 generic-8 generic-16 generic-32 generic-64 generic-1 generic-4 generic-8 generic-16 generic-32 generic-64 generic-1
ifeq ($(ARM_ENABLED), ON)
TARGETS+=neon
endif
# These files need to be compiled in two versions - 32 and 64 bits. # These files need to be compiled in two versions - 32 and 64 bits.
BUILTINS_SRC_TARGET=$(addprefix builtins/target-, $(addsuffix .ll, $(TARGETS))) BUILTINS_SRC_TARGET=$(addprefix builtins/target-, $(addsuffix .ll, $(TARGETS)))
# These are files to be compiled in single version. # These are files to be compiled in single version.

View File

@@ -640,7 +640,7 @@ AddBitcodeToModule(const unsigned char *bitcode, int length,
llvm::Triple bcTriple(bcModule->getTargetTriple()); llvm::Triple bcTriple(bcModule->getTargetTriple());
Debug(SourcePos(), "module triple: %s\nbitcode triple: %s\n", Debug(SourcePos(), "module triple: %s\nbitcode triple: %s\n",
mTriple.str().c_str(), bcTriple.str().c_str()); mTriple.str().c_str(), bcTriple.str().c_str());
#ifndef __arm__ #if defined(ISPC_ARM_ENABLED) && !defined(__arm__)
// FIXME: More ugly and dangerous stuff. We really haven't set up // FIXME: More ugly and dangerous stuff. We really haven't set up
// proper build and runtime infrastructure for ispc to do // proper build and runtime infrastructure for ispc to do
// cross-compilation, yet it's at minimum useful to be able to emit // cross-compilation, yet it's at minimum useful to be able to emit
@@ -819,6 +819,7 @@ DefineStdlib(SymbolTable *symbolTable, llvm::LLVMContext *ctx, llvm::Module *mod
// Next, add the target's custom implementations of the various needed // Next, add the target's custom implementations of the various needed
// builtin functions (e.g. __masked_store_32(), etc). // builtin functions (e.g. __masked_store_32(), etc).
switch (g->target->getISA()) { switch (g->target->getISA()) {
#ifdef ISPC_ARM_ENABLED
case Target::NEON: { case Target::NEON: {
if (runtime32) { if (runtime32) {
EXPORT_MODULE(builtins_bitcode_neon_32bit); EXPORT_MODULE(builtins_bitcode_neon_32bit);
@@ -828,6 +829,7 @@ DefineStdlib(SymbolTable *symbolTable, llvm::LLVMContext *ctx, llvm::Module *mod
} }
break; break;
} }
#endif
case Target::SSE2: { case Target::SSE2: {
switch (g->target->getVectorWidth()) { switch (g->target->getVectorWidth()) {
case 4: case 4:

View File

@@ -141,10 +141,12 @@ lGetSystemISA() {
static const char *supportedCPUs[] = { static const char *supportedCPUs[] = {
#ifdef ISPC_ARM_ENABLED
// FIXME: LLVM supports a ton of different ARM CPU variants--not just // FIXME: LLVM supports a ton of different ARM CPU variants--not just
// cortex-a9 and a15. We should be able to handle any of them that also // cortex-a9 and a15. We should be able to handle any of them that also
// have NEON support. // have NEON support.
"cortex-a9", "cortex-a15", "cortex-a9", "cortex-a15",
#endif
"atom", "penryn", "core2", "corei7", "corei7-avx" "atom", "penryn", "core2", "corei7", "corei7-avx"
#if !defined(LLVM_3_1) #if !defined(LLVM_3_1)
, "core-avx-i", "core-avx2" , "core-avx-i", "core-avx2"
@@ -185,9 +187,11 @@ Target::Target(const char *arch, const char *cpu, const char *isa, bool pic) :
// possible ISA based on that. // possible ISA based on that.
if (!strcmp(cpu, "core-avx2")) if (!strcmp(cpu, "core-avx2"))
isa = "avx2"; isa = "avx2";
#ifdef ISPC_ARM_ENABLED
else if (!strcmp(cpu, "cortex-a9") || else if (!strcmp(cpu, "cortex-a9") ||
!strcmp(cpu, "cortex-a15")) !strcmp(cpu, "cortex-a15"))
isa = "neon"; isa = "neon";
#endif
else if (!strcmp(cpu, "core-avx-i")) else if (!strcmp(cpu, "core-avx-i"))
isa = "avx1.1"; isa = "avx1.1";
else if (!strcmp(cpu, "sandybridge") || else if (!strcmp(cpu, "sandybridge") ||
@@ -211,7 +215,7 @@ Target::Target(const char *arch, const char *cpu, const char *isa, bool pic) :
} }
} }
#if !defined(__arm__) #if defined(ISPC_ARM_ENABLED) && !defined(__arm__)
if (cpu == NULL && !strcmp(isa, "neon")) if (cpu == NULL && !strcmp(isa, "neon"))
// If we're compiling NEON on an x86 host and the CPU wasn't // If we're compiling NEON on an x86 host and the CPU wasn't
// supplied, don't go and set the CPU based on the host... // supplied, don't go and set the CPU based on the host...
@@ -246,9 +250,11 @@ Target::Target(const char *arch, const char *cpu, const char *isa, bool pic) :
this->m_cpu = cpu; this->m_cpu = cpu;
if (arch == NULL) { if (arch == NULL) {
#ifdef ISPC_ARM_ENABLED
if (!strcmp(isa, "neon")) if (!strcmp(isa, "neon"))
arch = "arm"; arch = "arm";
else else
#endif
arch = "x86-64"; arch = "x86-64";
} }
@@ -445,6 +451,7 @@ Target::Target(const char *arch, const char *cpu, const char *isa, bool pic) :
this->m_hasGather = true; this->m_hasGather = true;
#endif #endif
} }
#ifdef ISPC_ARM_ENABLED
else if (!strcasecmp(isa, "neon")) { else if (!strcasecmp(isa, "neon")) {
this->m_isa = Target::NEON; this->m_isa = Target::NEON;
this->m_nativeVectorWidth = 4; this->m_nativeVectorWidth = 4;
@@ -454,6 +461,7 @@ Target::Target(const char *arch, const char *cpu, const char *isa, bool pic) :
this->m_maskingIsFree = false; this->m_maskingIsFree = false;
this->m_maskBitCount = 32; this->m_maskBitCount = 32;
} }
#endif
else { else {
fprintf(stderr, "Target ISA \"%s\" is unknown. Choices are: %s\n", fprintf(stderr, "Target ISA \"%s\" is unknown. Choices are: %s\n",
isa, SupportedTargetISAs()); isa, SupportedTargetISAs());
@@ -468,8 +476,10 @@ Target::Target(const char *arch, const char *cpu, const char *isa, bool pic) :
llvm::Reloc::Default; llvm::Reloc::Default;
std::string featuresString = m_attributes; std::string featuresString = m_attributes;
llvm::TargetOptions options; llvm::TargetOptions options;
#ifdef ISPC_ARM_ENABLED
if (m_isa == Target::NEON) if (m_isa == Target::NEON)
options.FloatABIType = llvm::FloatABI::Hard; options.FloatABIType = llvm::FloatABI::Hard;
#endif
#if !defined(LLVM_3_1) #if !defined(LLVM_3_1)
if (g->opt.disableFMA == false) if (g->opt.disableFMA == false)
options.AllowFPOpFusion = llvm::FPOpFusion::Fast; options.AllowFPOpFusion = llvm::FPOpFusion::Fast;
@@ -561,13 +571,21 @@ Target::SupportedTargetCPUs() {
const char * const char *
Target::SupportedTargetArchs() { Target::SupportedTargetArchs() {
return "arm, x86, x86-64"; return
#ifdef ISPC_ARM_ENABLED
"arm, "
#endif
"x86, x86-64";
} }
const char * const char *
Target::SupportedTargetISAs() { Target::SupportedTargetISAs() {
return "neon, sse2, sse2-x2, sse4, sse4-x2, avx, avx-x2" return
#ifdef ISPC_ARM_ENABLED
"neon, "
#endif
"sse2, sse2-x2, sse4, sse4-x2, avx, avx-x2"
", avx1.1, avx1.1-x2, avx2, avx2-x2" ", avx1.1, avx1.1-x2, avx2, avx2-x2"
", generic-1, generic-4, generic-8, generic-16, generic-32"; ", generic-1, generic-4, generic-8, generic-16, generic-32";
} }
@@ -576,10 +594,13 @@ Target::SupportedTargetISAs() {
std::string std::string
Target::GetTripleString() const { Target::GetTripleString() const {
llvm::Triple triple; llvm::Triple triple;
#ifdef ISPC_ARM_ENABLED
if (m_arch == "arm") { if (m_arch == "arm") {
triple.setTriple("armv7-eabi"); triple.setTriple("armv7-eabi");
} }
else { else
#endif
{
// Start with the host triple as the default // Start with the host triple as the default
triple.setTriple(llvm::sys::getDefaultTargetTriple()); triple.setTriple(llvm::sys::getDefaultTargetTriple());
@@ -602,7 +623,9 @@ Target::GetTripleString() const {
const char * const char *
Target::ISAToString(ISA isa) { Target::ISAToString(ISA isa) {
switch (isa) { switch (isa) {
#ifdef ISPC_ARM_ENABLED
case Target::NEON: case Target::NEON:
#endif
return "neon"; return "neon";
case Target::SSE2: case Target::SSE2:
return "sse2"; return "sse2";

6
ispc.h
View File

@@ -179,7 +179,11 @@ public:
flexible/performant of them will apear last in the enumerant. Note flexible/performant of them will apear last in the enumerant. Note
also that __best_available_isa() needs to be updated if ISAs are also that __best_available_isa() needs to be updated if ISAs are
added or the enumerant values are reordered. */ added or the enumerant values are reordered. */
enum ISA { NEON, SSE2, SSE4, AVX, AVX11, AVX2, GENERIC, NUM_ISAS }; enum ISA {
#ifdef ISPC_ARM_ENABLED
NEON,
#endif
SSE2, SSE4, AVX, AVX11, AVX2, GENERIC, NUM_ISAS };
/** Initializes the given Target pointer for a target of the given /** Initializes the given Target pointer for a target of the given
name, if the name is a known target. Returns true if the name, if the name is a known target. Returns true if the

View File

@@ -45,8 +45,6 @@
<ClCompile Include="$(Configuration)\gen-bitcode-generic-32-64bit.cpp" /> <ClCompile Include="$(Configuration)\gen-bitcode-generic-32-64bit.cpp" />
<ClCompile Include="$(Configuration)\gen-bitcode-generic-64-32bit.cpp" /> <ClCompile Include="$(Configuration)\gen-bitcode-generic-64-32bit.cpp" />
<ClCompile Include="$(Configuration)\gen-bitcode-generic-64-64bit.cpp" /> <ClCompile Include="$(Configuration)\gen-bitcode-generic-64-64bit.cpp" />
<ClCompile Include="$(Configuration)\gen-bitcode-neon-32bit.cpp" />
<ClCompile Include="$(Configuration)\gen-bitcode-neon-64bit.cpp" />
<ClCompile Include="$(Configuration)\gen-bitcode-sse2-32bit.cpp" /> <ClCompile Include="$(Configuration)\gen-bitcode-sse2-32bit.cpp" />
<ClCompile Include="$(Configuration)\gen-bitcode-sse2-64bit.cpp" /> <ClCompile Include="$(Configuration)\gen-bitcode-sse2-64bit.cpp" />
<ClCompile Include="$(Configuration)\gen-bitcode-sse2-x2-32bit.cpp" /> <ClCompile Include="$(Configuration)\gen-bitcode-sse2-x2-32bit.cpp" />
@@ -187,19 +185,6 @@
<Message>Building gen-bitcode-sse2-x2-64bit.cpp</Message> <Message>Building gen-bitcode-sse2-x2-64bit.cpp</Message>
</CustomBuild> </CustomBuild>
</ItemGroup> </ItemGroup>
<ItemGroup>
<CustomBuild Include="builtins\target-neon.ll">
<FileType>Document</FileType>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">m4 -Ibuiltins/ -DLLVM_VERSION=%LLVM_VERSION% builtins\target-neon.ll | python bitcode2cpp.py builtins\target-neon.ll &gt; gen-bitcode-neon.cpp</Command>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">gen-bitcode-neon.cpp</Outputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">builtins\util.m4</AdditionalInputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">m4 -Ibuiltins/ -DLLVM_VERSION=%LLVM_VERSION% builtins\target-neon.ll | python bitcode2cpp.py builtins\target-neon.ll &gt; gen-bitcode-neon.cpp</Command>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">gen-bitcode-neon.cpp</Outputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">builtins\util.m4</AdditionalInputs>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Building gen-bitcode-neon.cpp</Message>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Building gen-bitcode-neon.cpp</Message>
</CustomBuild>
</ItemGroup>
<ItemGroup> <ItemGroup>
<CustomBuild Include="builtins\target-avx1.ll"> <CustomBuild Include="builtins\target-avx1.ll">
<FileType>Document</FileType> <FileType>Document</FileType>

View File

@@ -300,6 +300,8 @@ int main(int Argc, char *Argv[]) {
LLVMInitializeX86Disassembler(); LLVMInitializeX86Disassembler();
LLVMInitializeX86TargetMC(); LLVMInitializeX86TargetMC();
#endif // !__ARM__ #endif // !__ARM__
#ifdef ISPC_ARM_ENABLED
// Generating ARM from x86 is more likely to be useful, though. // Generating ARM from x86 is more likely to be useful, though.
LLVMInitializeARMTargetInfo(); LLVMInitializeARMTargetInfo();
LLVMInitializeARMTarget(); LLVMInitializeARMTarget();
@@ -307,6 +309,7 @@ int main(int Argc, char *Argv[]) {
LLVMInitializeARMAsmParser(); LLVMInitializeARMAsmParser();
LLVMInitializeARMDisassembler(); LLVMInitializeARMDisassembler();
LLVMInitializeARMTargetMC(); LLVMInitializeARMTargetMC();
#endif
char *file = NULL; char *file = NULL;
const char *headerFileName = NULL; const char *headerFileName = NULL;