1 //------------------------------------------------------------------------------ 2 // GB_compiler.h: handle compiler variations 3 //------------------------------------------------------------------------------ 4 5 // SuiteSparse:GraphBLAS, Timothy A. Davis, (c) 2017-2021, All Rights Reserved. 6 // SPDX-License-Identifier: Apache-2.0 7 8 //------------------------------------------------------------------------------ 9 10 #ifndef GB_COMPILER_H 11 #define GB_COMPILER_H 12 13 //------------------------------------------------------------------------------ 14 // compiler variations 15 //------------------------------------------------------------------------------ 16 17 // Determine the restrict keyword, and whether or not variable-length arrays 18 // are supported. 19 20 #if ( _MSC_VER && !__INTEL_COMPILER ) 21 22 // Microsoft Visual Studio does not have the restrict keyword, but it does 23 // support __restrict, which is equivalent. Variable-length arrays are 24 // not supported. OpenMP tasks are not available, GraphBLAS no longer 25 // uses OpenMP tasks. 26 27 #define GB_MICROSOFT 1 28 #define GB_HAS_VLA 0 29 #if defined ( __cplusplus ) 30 // C++ does not have the restrict keyword 31 #define restrict 32 #else 33 // C uses __restrict 34 #define restrict __restrict 35 #endif 36 37 #elif defined ( __cplusplus ) 38 39 #define GB_MICROSOFT 0 40 #define GB_HAS_VLA 1 41 // C++ does not have the restrict keyword 42 #define restrict 43 44 #elif GxB_STDC_VERSION >= 199901L 45 46 // ANSI C99 and later have the restrict keyword and variable-length arrays. 47 #define GB_MICROSOFT 0 48 #define GB_HAS_VLA 1 49 50 #else 51 52 // ANSI C95 and earlier have neither 53 #define GB_MICROSOFT 0 54 #define GB_HAS_VLA 0 55 #define restrict 56 57 #endif 58 59 //------------------------------------------------------------------------------ 60 // Microsoft specific include files 61 //------------------------------------------------------------------------------ 62 63 #if GB_MICROSOFT 64 #include <malloc.h> 65 #endif 66 67 //------------------------------------------------------------------------------ 68 // PGI_COMPILER_BUG 69 //------------------------------------------------------------------------------ 70 71 // If GraphBLAS is compiled with -DPGI_COMPILER_BUG, then a workaround is 72 // enabled for a bug in the PGI compiler. The compiler does not correctly 73 // handle automatic arrays of variable size. 74 75 #ifdef PGI_COMPILER_BUG 76 77 // override the ANSI C compiler to turn off variable-length arrays 78 #undef GB_HAS_VLA 79 #define GB_HAS_VLA 0 80 81 #endif 82 83 //------------------------------------------------------------------------------ 84 // OpenMP pragmas and tasks 85 //------------------------------------------------------------------------------ 86 87 // GB_PRAGMA(x) becomes "#pragma x", but the way to do this depends on the 88 // compiler: 89 #if GB_MICROSOFT 90 // MS Visual Studio is not ANSI C11 compliant, and uses __pragma: 91 #define GB_PRAGMA(x) __pragma (x) 92 #else 93 // ANSI C11 compilers use _Pragma: 94 #define GB_PRAGMA(x) _Pragma (#x) 95 #endif 96 97 // construct pragmas for loop vectorization: 98 #if GB_MICROSOFT 99 100 // no #pragma omp simd is available in MS Visual Studio 101 #define GB_PRAGMA_SIMD 102 #define GB_PRAGMA_SIMD_REDUCTION(op,s) 103 104 #else 105 106 // create two kinds of SIMD pragmas: 107 // GB_PRAGMA_SIMD becomes "#pragma omp simd" 108 // GB_PRAGMA_SIMD_REDUCTION (+,cij) becomes 109 // "#pragma omp simd reduction(+:cij)" 110 #define GB_PRAGMA_SIMD GB_PRAGMA (omp simd) 111 #define GB_PRAGMA_SIMD_REDUCTION(op,s) GB_PRAGMA (omp simd reduction(op:s)) 112 113 #endif 114 115 #define GB_PRAGMA_IVDEP GB_PRAGMA(ivdep) 116 117 //------------------------------------------------------------------------------ 118 // variable-length arrays 119 //------------------------------------------------------------------------------ 120 121 // If variable-length arrays are not supported, user-defined types are limited 122 // in size to 128 bytes or less. Many of the type-generic routines allocate 123 // workspace for a single scalar of variable size, using a statement: 124 // 125 // GB_void aij [xsize] ; 126 // 127 // To support non-variable-length arrays in ANSI C95 or earlier, this is used: 128 // 129 // GB_void aij [GB_VLA(xsize)] ; 130 // 131 // GB_VLA(xsize) is either defined as xsize (for ANSI C99 or later), or a fixed 132 // size of 128, in which case user-defined types 133 // are limited to a max of 128 bytes. 134 135 #if ( GB_HAS_VLA ) 136 137 // variable-length arrays are allowed 138 #define GB_VLA(s) s 139 140 #else 141 142 // variable-length arrays are not allowed 143 #define GB_VLA_MAXSIZE 128 144 #define GB_VLA(s) GB_VLA_MAXSIZE 145 146 #endif 147 #endif 148 149