Wednesday, October 16, 2013

GCC 4.8 on Ubuntu 12.04 x64

Ran into a bug in libstdc++ 4.7 building LLDB with Clang 3.3. So these are the notes on getting GCC 4.8 installed.

Here is a link talking about the libstdc++ bug:
http://stackoverflow.com/questions/15747223/why-does-this-basic-thread-program-fail-with-clang-but-pass-in-g

Good askubuntu link:
http://askubuntu.com/questions/193513/problem-adding-a-ppa-to-install-gcc-4-7

Ubuntu Toolchain PPA:
https://launchpad.net/~ubuntu-toolchain-r/+archive/test

Steps:

sudo add-apt-repository ppa:ubuntu-toolchain-r/test

If that doesn't work, you can create the file manually:

mikesart@mikesart64:~/data/src/blah/build64$ cat /etc/apt/sources.list.d/toolchain.list
# https://launchpad.net/~ubuntu-toolchain-r/+archive/test
deb http://ppa.launchpad.net/ubuntu-toolchain-r/test/ubuntu precise main   
deb-src http://ppa.launchpad.net/ubuntu-toolchain-r/test/ubuntu precise main

sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 1E9377A2BA9EF27F
sudo apt-get update
sudo apt-get install gcc-4.8 g++-4.8

I then added gcc 4.8 to my alternatives list.

sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.8 50
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.8 50
sudo update-alternatives --install /usr/bin/cpp cpp-bin /usr/bin/cpp-4.8 50

Here are some clang / gcc commands to view various options, include paths, etc.

# Show default options and commands, plus include paths
mikesart@mikesart64:~/data/src/llvm.svn/build$ clang -v -fsyntax-only -x c++ /dev/null 2>&1
clang version 3.3 (tags/RELEASE_33/final)
Target: x86_64-unknown-linux-gnu
Thread model: posix
 "/home/mikesart/data/src/clang3.3/bin/clang" -cc1 -triple x86_64-unknown-linux-gnu -fsyntax-only -disable-free -disable-llvm-verifier -main-file-name null -mrelocation-model static -mdisable-fp-elim -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -target-linker-version 2.20.1 -v -resource-dir /home/mikesart/data/src/clang3.3/bin/../lib/clang/3.3 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/x86_64-linux-gnu -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/backward -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/x86_64-linux-gnu/c++/4.8 -internal-isystem /usr/local/include -internal-isystem /home/mikesart/data/src/clang3.3/bin/../lib/clang/3.3/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fdeprecated-macro -fdebug-compilation-dir /home/mikesart/data/src/llvm.svn/build -ferror-limit 19 -fmessage-length 181 -mstackrealign -fobjc-runtime=gcc -fobjc-default-synthesize-properties -fcxx-exceptions -fexceptions -fdiagnostics-show-option -fcolor-diagnostics -backend-option -vectorize-loops -x c++ /dev/null
clang -cc1 version 3.3 based upon LLVM 3.3 default target x86_64-unknown-linux-gnu
ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/x86_64-linux-gnu"
ignoring nonexistent directory "/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8
 /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/backward
 /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/x86_64-linux-gnu/c++/4.8
 /usr/local/include
 /home/mikesart/data/src/clang3.3/bin/../lib/clang/3.3/include
 /usr/include/x86_64-linux-gnu
 /usr/include
End of search list.

# Print the paths used for finding libraries and programs
mikesart@mikesart64:~/data/src/llvm.svn/build$ clang -print-search-dirs | tr : '\n'
programs
 =/home/mikesart/bin
/home/mikesart/data/src/clang3.3/bin
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../x86_64-linux-gnu/bin
libraries
 =/home/mikesart/data/src/clang3.3/bin/../lib/clang/3.3
/usr/lib/gcc/x86_64-linux-gnu/4.8
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu
/lib/x86_64-linux-gnu
/lib/../lib64
/usr/lib/x86_64-linux-gnu
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../..
/lib
/usr/lib

# list all preprocessor definitions
clang -dM -E - < /dev/null
#define _LP64 1
#define __ATOMIC_ACQUIRE 2
#define __ATOMIC_ACQ_REL 4
#define __ATOMIC_CONSUME 1
#define __ATOMIC_RELAXED 0
#define __ATOMIC_RELEASE 3
#define __ATOMIC_SEQ_CST 5

#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__
...

Link for gcc options which control kind of output:
http://gcc.gnu.org/onlinedocs/gcc-4.3.5/gcc/Overall-Options.html

This one really useful: "If the -Q option appears on the command line before the --help= option, then the descriptive text displayed by --help= is changed. Instead of describing the displayed options, an indication is given as to whether the option is enabled, disabled or set to a specific value (assuming that the compiler knows this at the point where the --help= option is used)."

# See what gcc enables with native flag (sse, avx, etc)
# (Clang 3.3 doesn't appear to support the --help=XX stuff)
gcc -march=native -Q --help=target -v

--help=XX supports the following:
  optimizers: display all optimization options supported by the compiler.
  warnings: display all options controlling warning messages produced by the compiler.
  target: display target-specific options.
  params: display values recognized by the --param option.
  common: display options that are common to all languages.
  language: display options supported for language, where language = c++, etc.

You can add undocumented to list all undocumented target-specific switches as well. Ie:

/usr/bin/gcc-4.8 -march=native -Q --help=target,undocumented -v
/usr/bin/gcc-4.8 -march=native -Q --help=c++,undocumented -v

Friday, October 4, 2013

Simple SSE/AVX/MMX sample source code...

For testing a bunch of register stuff in LLDB. Shoved it up here also:

https://gist.github.com/mikesart/6832418#file-gistfile1-txt


// Output from my cmake VERBOSE=1 command for building:
// c++ -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGE_FILES -march=native -g -O0 -std=c++0x -g -o sse.cpp.o -c sse.cpp
// c++ -march=native -g -O0 -std=c++0x -g sse.cpp.o -o sse -rdynamic -ldl -lpthread

// SSE
//
#include <stdio.h>
#include <stdlib.h>

// #include <mmintrin.h> // MMX
// #include <xmmintrin.h> // SSE
// #include <emmintrin.h> // SSE2
// #include <pmmintrin.h> // SSE3
// #include <tmmintrin.h> // SSSE3
// #include <nmmintrin.h> // SSE4.1
// #include <ammintrin.h> // SSE4.2
// #include <wmmintrin.h> // AES/PCMUL
// #include <immintrin.h> // AVX
#include <x86intrin.h>      // Pulls in all of the above based on compiler switches (-march)

// AVX, SSE intrinsics, etc.:
// http://chessprogramming.wikispaces.com/AVX

// Intrinsics for Advanced Vector Extensions:
// http://software.intel.com/sites/products/documentation/hpc/composerxe/en-us/2011Update/cpp/lin/intref_cls/common/intref_bk_advectorext.htm

// Intrinsics for Advanced Vector Extensions 2:
// http://software.intel.com/sites/products/documentation/hpc/composerxe/en-us/2011Update/cpp/lin/intref_cls/common/intref_bk_advectorext2.htm

#ifndef __AVX__
#error AVX not defined
#endif

int main( int argc, char *argv[] )
{
    float a = 16.0f;
    float b = 9.0f;

    __m128 SSE0 = _mm_setzero_ps();
    __m128 SSEa = _mm_set_ps1(a);   // _mm_load1_ps(&a);
    __m128 SSEb = _mm_set_ps1(b);   // _mm_load1_ps(&b);
    __m128 SSEv = _mm_add_ps(SSEa, SSEb);

    __m256 AVX0 = _mm256_setzero_ps();
    __m256 AVXa = _mm256_set1_ps(a);
    __m256 AVXb = _mm256_set1_ps(b);
    __m256 AVXv = _mm256_add_ps(AVXa, AVXb);

    __m64 MMX0 = _mm_setzero_si64();
    __m64 MMXa = _mm_setr_pi32(16, 16);
    __m64 MMXb = _mm_setr_pi32(9, 9);
    __m64 MMXv = _mm_add_pi32(MMXa, MMXb);

    float temp[4] __attribute__((aligned(16)));
    _mm_store_ps(&temp[0], SSEv);
    printf("tempsse is %.2f %.2f %.2f %.2f\n", temp[0], temp[1], temp[2], temp[3]);

    float temp2[8] __attribute((aligned(32)));
    _mm256_store_ps(&temp2[0], AVXv);
    printf("tempavx is %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f\n",
        temp2[0], temp2[1], temp2[2], temp2[3],
        temp2[4], temp2[5], temp2[6], temp2[7]);

    printf("%d\n", _mm_cvtsi64_si32(MMXv));

    return 0;
}