DNS Projects HTTP Projects OSS Projects Testing DNS Building Firefox Extensions Main Page



















Posted: April 23, 2009 by Datazygte, Inc - contribution by rscheckelhoff- at- fourcalorieservers dot-com

LLVM1 and Clang are words describing a potent duo that will soon be on the tips of many tongues.


The LLVM and Clang projects are being carried on at the University of Illinois, Urbana-Champaigne. The LLVM (low level virtual machine) project is an attempt (mostly successful, already) to implement a framework for many compiler flavors, providing both native code generation capability and jit (just in time) intermediate code generation.


I decided to download the svn repository code and start a project to test the new compiler system. The impetus for the project began when I realized that I was being sucked into a gpl-v3 world that I didn't feel comfortable with.

Ostensibly, when LLVM/Clang is finished, it should provide a viable alternative compiler that is not encumbered by gplv3 licensing. (The UIUC license is a BSD-like license).




For the OS, I used (as is my custom) FreeBSD version 7.1-RELEASE. The process was started by downloading the code from the subversion repository:

pkg_add -rK subversion (because it was not on the system)

/usr/local/bin/svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm

pkg_add -rK gmake (because it was not already on the system)

... I then changed to the newly created llvm source directory:

cd llvm

... and configured the build ...

./configure --prefix=/usr/local --enable-optimized

The --enable-optimized setting is highly recommended. I tried the compilation both ways, and found a large difference in compile speed and executable size. The Debug build (without optimization) used 1.2Gb of disk space in the llvm/Debug/bin and llvm/Debug/lib directories. The optimized Release build created only a couple hundred megabytes of executable and library files in the llvm/Release/bin and llvm/Release/lib directories.


... I then executed gmake to compile and link the llvm executables:

gmake

When LLVM completed the compilation and linking processes, I built Clang. First, I grabbed the source:

cd tools


svn co http://llvm.org/svn/llvm-project/cfe/trunk clang

... Then, I moved to the just-created source directory, and executed gmake:

cd clang


gmake



My finishing step was to tack the ../llvm/Release/bin and ../llvm/Release/lib paths onto the environment PATH variable.

What follows is a bit of code (from a Four Calorie DNS server project) that I used as bait to test the LLVM Clang compiler.




Rough Drafting Code


/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
/*
 * main.c
 * Copyright (C) Datazygte, Inc - Contrib by Ron Scheckelhoff 2009 <ron@fourcalorieservers.com>
 *
 * main.cc is free software copyrighted by Datazygte, Inc - Contrib by Ron Scheckelhoff.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name ``Datazygte, Inc - Contrib by Ron Scheckelhoff'' nor the name of any other
 *    contributor may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * main.c IS PROVIDED BY Datazygte, Inc - Contrib by Ron Scheckelhoff ``AS IS'' AND ANY EXPRESS
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL Datazygte, Inc - Contrib by Ron Scheckelhoff OR ANY OTHER CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <iostream.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <unistd.h>


//
// Specification for labels (Max=7 in DNS spec, but here
// is set to 100 for future expandability)
//

#define EOQ 2
#define MAX_LABEL_LENGTH 128
#define MAX_LABELS 100
#define SUCCESS 0
#define FAILURE 999
#define TIMEOUT 998
#define MAX_CHAR 128
#define MIN_CHAR 28
#define MAX_BUFFER_INPUT_QUERY 2048
#define QUERY_HEADER_OFFSET 12


//
struct STC_QUERY_INPUT_C
{
        char bx1_Label_Length;
        char bx128_Label[MAX_LABEL_LENGTH];
        char bx2_Record_Type[2];
        char bx2_Class[2];
};


//
struct STC_QUERY_INPUT_A
{
        char bx2_TransactionID[2];
        char bx2_Flags[2];
        char bx2_Question_Quantity[2];
        char bx2_ResRecord_Quantity[2];
        char bx2_AuthRecord_Quantity[2];
        char bx2_AddRecord_Quantity[2];
};


//
struct STC_QUERY_INPUT_B
{
        STC_QUERY_INPUT_A stcQueryHeader;
        int intTotalLabelCount;
        STC_QUERY_INPUT_C stcLabels[MAX_LABELS];
};


//
// Extract Labels
//
int ExtractLabels(STC_QUERY_INPUT_B* pstcFullQuery,
                                  char cstrBuffer[MAX_BUFFER_INPUT_QUERY], int siz)
{

    char* pstrMarker;

    STC_QUERY_INPUT_C stcLabel;
    STC_QUERY_INPUT_C* pstcLabelForArray;

    int intHereBefore = 0;
    int intLabelIndex = 1;
    int intThisLabelLen = 0;

    memset(&stcLabel,0,sizeof(STC_QUERY_INPUT_C));

    if (siz < MAX_BUFFER_INPUT_QUERY)
    {

        for (int i=QUERY_HEADER_OFFSET; i<siz-EOQ; i++)
        {


            if ((cstrBuffer[i] > MIN_CHAR) && (cstrBuffer[i] < MAX_CHAR))
            {
                    // part of label text - make sure it fits
                    if ((stcLabel.bx1_Label_Length > 0) &&
                        (stcLabel.bx1_Label_Length < MAX_LABEL_LENGTH))
                    {
                            intThisLabelLen++;

                            if (intThisLabelLen <= stcLabel.bx1_Label_Length)
                            {
                                 stcLabel.bx128_Label[intThisLabelLen-1] = cstrBuffer[i];
                            }
                    }
            }
            else
            {
                   // part of label section count

                   if (intHereBefore != 0)
                   {
                          pstcLabelForArray = &pstcFullQuery->stcLabels[intLabelIndex];

                          memset(pstcLabelForArray, 0, sizeof(STC_QUERY_INPUT_C));
                          memcpy(pstcLabelForArray->bx128_Label, stcLabel.bx128_Label, MAX_LABEL_LENGTH);

                          pstcLabelForArray->bx1_Label_Length = stcLabel.bx1_Label_Length;
                          memset(stcLabel.bx128_Label,0,MAX_LABEL_LENGTH);
                          intThisLabelLen = 0;
                          intLabelIndex++;
                   }

                   intHereBefore = 1;
                   stcLabel.bx1_Label_Length = cstrBuffer[i];

                   // end of all labels
                   if (cstrBuffer[i] == 0)
                   {
                          pstcLabelForArray->bx2_Record_Type[1] = cstrBuffer[i+EOQ];
                          return intLabelIndex-1;
                   }
            }
      
	}

   }

   return FAILURE; 

}

         
  


What Have we Written?

Clang Compiler bits and pieces
Continued post: 04/23/2009


The material on http://llvm.org makes a lot of mention about the compiler not being ready in terms of compiling C++. Don't let those warnings stand in your way, as I have found that the compiler nicely falls back to g++ to build any c++ objects in my projects.


The code (shown above) was wrapped up with a few pages more (not shown), and compiled and linked into a program two or three times faster than it did with gcc:


clang -o main main.c


To see a full list of the options, type:

clang -help

..... to be continued ...




1Note that this site is not affiliated with or endorsed by http://llvm.org, LLVM, Clang, or UIUC in any way.












Contact: Ron Scheckelhoff -- Email suggestions to: rscheckelhoff@fourcalorieservers.com ( )




Valid HTML 4.01 Transitional