[pcre-dev] [PATCH] JIT support with Intel compiler, older So…

Top Page
Delete this message
Author: Daniel Richard G
Date:  
To: pcre-dev
Subject: [pcre-dev] [PATCH] JIT support with Intel compiler, older Solaris
I've encountered some further issues in building PCRE with JIT support in
some less-than-usual environments.

One is using the Intel compiler (icc) on 64-bit Linux. Normally, it
#defines __GNUC__ and compiles the same code as GCC, but in my case, the
compatibility was causing me trouble and I had to disable it using
-no-gcc. Unfortunately, sljitNativeX86_common.c then complained that
"SLJIT_DETECT_SSE2 is not implemented for this C compiler".

Intel's Linux compiler always defines __INTEL_COMPILER---but care is
required in the use of this symbol, because Intel's Windows compiler (icl)
also defines it. So I made the following changes to
sljitNativeX86_common.c:

* Added defined(__INTEL_COMPILER) to the appropriate conditionals

* Moved the 64-bit _MSC_VER case up so that this is used in preference on
Windows (note that icl does define _MSC_VER on Windows, set to the
appropriate SDK version)

* Also moved the 32-bit _MSC_VER case up, for parallelism (icl can
actually compile both the Intel-syntax and AT&T-syntax asm blocks, but
the former ought to be favored on Windows)

* The Intel compiler treats __asm__ and asm/__asm differently; the former
is presumed to be an AT&T-syntax asm block, the latter Intel. For
reference, see

     http://software.intel.com/sites/products/documentation/doclib/stdxe/2013/composerxe/compiler/cpp-win/GUID-5100C4FC-BC2F-4E36-943A-120CFFFB4285.htm


* Also, __cpuid() is not available before Visual Studio 2005, so I added a
_MSC_VER check for that:

     http://msdn.microsoft.com/en-us/library/hskdteyh(v=vs.80).aspx



A similar problem came up when I tried to build PCRE on a 32-bit Linux
system with "icc -no-gcc"; SLJIT_CALL was being defined to __stdcall,
which the compiler didn't recognize. I changed the logic around a bit not
only so that the symbol would be defined to empty, but also to simplify
the control flow that would result in the symbol being defined to empty.
(I would have made it use __attribute__((fastcall)) like GCC, except that
this led to segfault city in the test suite. I'll follow up this issue
separately.)


Seeing as SLJIT recently gained SPARC support, I also tried building PCRE
on a Solaris UltraSPARC system to see if JIT support was at all working in
64-bit builds. This system has an older version of the vendor compiler,
which has a few quirks:

* No tolerance for variable declarations after statements (fixed)

* No support for the "inline" keyword (fixed, although there may be
versions of the compiler newer than mine that still don't support this)

* __asm__ not recognized, but __asm works

* No apparent support for "asm volatile"


I'm not sure how the latter two points should be addressed. If I append
"-D__asm__=__asm -Dvolatile=" to the compiler command line, I get this:

$ cc -DHAVE_CONFIG_H -I. -I... -D__EXTENSIONS__ -D_REENTRANT -Dsparc -mt -D_REENTRANT -Xa -mt -v -xarch=v9 -xcrossfile -xO5 -c .../pcre_jit_compile.c -KPIC -DPIC -o libpcre_la-pcre_jit_compile.o -D__asm__=__asm -Dvolatile=
".../sljit/sljitNativeSPARC_common.c", line 44: warning: asm() statement disables optimization within function
".../sljit/sljitNativeSPARC_common.c", line 44: syntax error before or at: :
".../sljit/sljitNativeSPARC_common.c", line 55: syntax error before or at: :
".../sljit/sljitNativeSPARC_common.c", line 350: cannot recover from previous errors
cc: acomp failed for .../pcre_jit_compile.c


Lastly, my patch fixes a few spelling errors in sljitLir.h. Just happened
upon them :-)


--Daniel


--
Daniel Richard G. || danielg@??? || Software Developer
Teragram Linguistic Technologies (a division of SAS)
http://www.teragram.com/Index: sljit/sljitLir.h
===================================================================
--- sljit/sljitLir.h    (revision 1221)
+++ sljit/sljitLir.h    (working copy)
@@ -881,7 +881,7 @@
 SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value);
 
 /* After the code generation the address for label, jump and const instructions
-   are computed. Since these structures are freed sljit_free_compiler, the
+   are computed. Since these structures are freed by sljit_free_compiler, the
    addresses must be preserved by the user program elsewere. */
 static SLJIT_INLINE sljit_uw sljit_get_label_addr(struct sljit_label *label) { return label->addr; }
 static SLJIT_INLINE sljit_uw sljit_get_jump_addr(struct sljit_jump *jump) { return jump->addr; }
@@ -898,12 +898,12 @@
 #define SLJIT_MAJOR_VERSION    0
 #define SLJIT_MINOR_VERSION    90
 
-/* Get the human readable name of the platfrom. Can be useful on platforms
+/* Get the human readable name of the platform. Can be useful on platforms
    like ARM, where ARM and Thumb2 functions can be mixed, and
    it is useful to know the type of the code generator. */
 SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void);
 
-/* Portble helper function to get an offset of a member. */
+/* Portable helper function to get an offset of a member. */
 #define SLJIT_OFFSETOF(base, member) ((sljit_sw)(&((base*)0x10)->member) - 0x10)
 
 #if (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK)
Index: sljit/sljitNativeX86_common.c
===================================================================
--- sljit/sljitNativeX86_common.c    (revision 1221)
+++ sljit/sljitNativeX86_common.c    (working copy)
@@ -277,9 +277,18 @@
 
 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
 
-#if defined(__GNUC__) || defined(__SUNPRO_C)
+#if defined(_MSC_VER) || defined(__BORLANDC__)
+    /* Intel syntax. */
+    __asm {
+        mov eax, 1
+        push ebx
+        cpuid
+        pop ebx
+        mov features, edx
+    }
+#elif defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__SUNPRO_C)
     /* AT&T syntax. */
-    asm (
+    __asm__ (
         "pushl %%ebx\n"
         "movl $0x1, %%eax\n"
         "cpuid\n"
@@ -289,24 +298,20 @@
         :
         : "%eax", "%ecx", "%edx"
     );
-#elif defined(_MSC_VER) || defined(__BORLANDC__)
-    /* Intel syntax. */
-    __asm {
-        mov eax, 1
-        push ebx
-        cpuid
-        pop ebx
-        mov features, edx
-    }
 #else
 #    error "SLJIT_DETECT_SSE2 is not implemented for this C compiler"
 #endif
 
 #else /* SLJIT_CONFIG_X86_32 */
 
-#if defined(__GNUC__) || defined(__SUNPRO_C)
+#if defined(_MSC_VER) && _MSC_VER >= 1400
+    int CPUInfo[4];
+
+    __cpuid(CPUInfo, 1);
+    features = (sljit_ui)CPUInfo[3];
+#elif defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__SUNPRO_C)
     /* AT&T syntax. */
-    asm (
+    __asm__ (
         "pushq %%rbx\n"
         "movl $0x1, %%eax\n"
         "cpuid\n"
@@ -316,11 +321,6 @@
         :
         : "%rax", "%rcx", "%rdx"
     );
-#elif defined(_MSC_VER)
-    int CPUInfo[4];
-
-    __cpuid(CPUInfo, 1);
-    features = (sljit_ui)CPUInfo[3];
 #else
 #    error "SLJIT_DETECT_SSE2 is not implemented for this C compiler"
 #endif
Index: sljit/sljitConfigInternal.h
===================================================================
--- sljit/sljitConfigInternal.h    (revision 1221)
+++ sljit/sljitConfigInternal.h    (working copy)
@@ -174,8 +174,12 @@
 
 #ifndef SLJIT_INLINE
 /* Inline functions. */
+#if defined(__SUNPRO_C) && __SUNPRO_C <= 0x510
+#define SLJIT_INLINE
+#else
 #define SLJIT_INLINE __inline
 #endif
+#endif
 
 #ifndef SLJIT_CONST
 /* Const variables. */
@@ -318,18 +322,16 @@
 #endif /* __BORLANDC__ */
 #define SLJIT_X86_32_FASTCALL 1
 
-#else /* defined(_WIN32) */
-#define SLJIT_CALL __stdcall
-#endif
-
-#else /* Other architectures. */
-
-#define SLJIT_CALL
+#endif /* defined(__GNUC__) */
 
 #endif /* SLJIT_CONFIG_X86_32 */
 
 #endif /* !SLJIT_CALL */
 
+#ifndef SLJIT_CALL
+#define SLJIT_CALL
+#endif
+
 #if !defined(SLJIT_BIG_ENDIAN) && !defined(SLJIT_LITTLE_ENDIAN)
 
 /* These macros are useful for the application. */
Index: sljit/sljitNativeSPARC_common.c
===================================================================
--- sljit/sljitNativeSPARC_common.c    (revision 1221)
+++ sljit/sljitNativeSPARC_common.c    (working copy)
@@ -153,10 +153,11 @@
    Useful for reordering instructions in the delay slot. */
 static sljit_si push_inst(struct sljit_compiler *compiler, sljit_ins ins, sljit_si delay_slot)
 {
+    sljit_ins *ptr;
     SLJIT_ASSERT((delay_slot & DST_INS_MASK) == UNMOVABLE_INS
         || (delay_slot & DST_INS_MASK) == MOVABLE_INS
         || (delay_slot & DST_INS_MASK) == ((ins >> 25) & 0x1f));
-    sljit_ins *ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins));
+    ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins));
     FAIL_IF(!ptr);
     *ptr = ins;
     compiler->size++;