diff options
author | Reid Spencer <rspencer@reidspencer.com> | 2006-11-17 03:32:33 +0000 |
---|---|---|
committer | Reid Spencer <rspencer@reidspencer.com> | 2006-11-17 03:32:33 +0000 |
commit | 8b2e1419cf24a33df5a87c99e367528b44dc28cf (patch) | |
tree | dfa50da1818a1e9c1d0588c060051c65583821a3 /runtime | |
parent | b2b9c20b6121a54a41ee1c583a4bff4389622da2 (diff) |
Undo removal of the runtime libraries. While this may have been a bit
premature, these libraries will be going away for the 2.0 release. Other
arrangements for profiling, gc, etc. should be made in the next few months.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@31807 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'runtime')
48 files changed, 3188 insertions, 0 deletions
diff --git a/runtime/GC/GCInterface.h b/runtime/GC/GCInterface.h new file mode 100644 index 0000000000..4eb48183bc --- /dev/null +++ b/runtime/GC/GCInterface.h @@ -0,0 +1,48 @@ +/*===-- GCInterface.h - Public interface exposed by garbage collectors ----===*\ +|* +|* The LLVM Compiler Infrastructure +|* +|* This file was developed by the LLVM research group and is distributed under +|* the University of Illinois Open Source License. See LICENSE.TXT for details. +|* +|*===----------------------------------------------------------------------===*| +|* +|* This file defines the common public interface that must be exposed by all +|* LLVM garbage collectors. +|* +\*===----------------------------------------------------------------------===*/ + +#ifndef GCINTERFACE_H +#define GCINTERFACE_H + +/* llvm_cg_walk_gcroots - This function is exposed by the LLVM code generator, + * and allows us to traverse the roots on the stack. + */ +void llvm_cg_walk_gcroots(void (*FP)(void **Root, void *Meta)); + + +/* llvm_gc_initialize - This function is called to initalize the garbage + * collector. + */ +void llvm_gc_initialize(unsigned InitialHeapSize); + +/* llvm_gc_allocate - This function allocates Size bytes from the heap and + * returns a pointer to it. + */ +void *llvm_gc_allocate(unsigned Size); + +/* llvm_gc_collect - This function forces a garbage collection cycle. + */ +void llvm_gc_collect(); + +/* llvm_gc_read - This function should be implemented to include any read + * barrier code that is needed by the garbage collector. + */ +void *llvm_gc_read(void *ObjPtr, void **FieldPtr); + +/* llvm_gc_write - This function should be implemented to include any write + * barrier code that is needed by the garbage collector. + */ +void llvm_gc_write(void *V, void *ObjPtr, void **FieldPtr); + +#endif diff --git a/runtime/GC/Makefile b/runtime/GC/Makefile new file mode 100644 index 0000000000..b57dc85907 --- /dev/null +++ b/runtime/GC/Makefile @@ -0,0 +1,19 @@ +##===- runtime/GC/Makefile ---------------------------------*- Makefile -*-===## +# +# The LLVM Compiler Infrastructure +# +# This file was developed by the LLVM research group and is distributed under +# the University of Illinois Open Source License. See LICENSE.TXT for details. +# +##===----------------------------------------------------------------------===## + +LEVEL = ../.. +PARALLEL_DIRS := SemiSpace +EXTRA_DIST := gc_exported_symbols.lst +include $(LEVEL)/Makefile.common + +# Install target for libraries: Copy into $LLVMGCCDIR/bytecode-libs +# +install:: + +clean:: diff --git a/runtime/GC/SemiSpace/Makefile b/runtime/GC/SemiSpace/Makefile new file mode 100644 index 0000000000..6f8e54ce27 --- /dev/null +++ b/runtime/GC/SemiSpace/Makefile @@ -0,0 +1,19 @@ +##===- runtime/GC/SemiSpace/Makefile -----------------------*- Makefile -*-===## +# +# The LLVM Compiler Infrastructure +# +# This file was developed by the LLVM research group and is distributed under +# the University of Illinois Open Source License. See LICENSE.TXT for details. +# +##===----------------------------------------------------------------------===## + +LEVEL = ../../.. +BYTECODE_LIBRARY = 1 +LIBRARYNAME = gcsemispace +BYTECODE_DESTINATION = $(CFERuntimeLibDir) +EXPORTED_SYMBOL_FILE = $(PROJ_SRC_DIR)/../gc_exported_symbols.lst + +include $(LEVEL)/Makefile.common + +CompileCommonOpts := $(filter-out -pedantic,$(CompileCommonOpts)) +CompileCommonOpts := $(filter-out -Wno-long-long,$(CompileCommonOpts)) diff --git a/runtime/GC/SemiSpace/semispace.c b/runtime/GC/SemiSpace/semispace.c new file mode 100644 index 0000000000..cb5864b0bd --- /dev/null +++ b/runtime/GC/SemiSpace/semispace.c @@ -0,0 +1,122 @@ +/*===-- semispace.c - Simple semi-space copying garbage collector ---------===*\ +|* +|* The LLVM Compiler Infrastructure +|* +|* This file was developed by the LLVM research group and is distributed under +|* the University of Illinois Open Source License. See LICENSE.TXT for details. +|* +|*===----------------------------------------------------------------------===*| +|* +|* This garbage collector is an extremely simple copying collector. It splits +|* the managed region of memory into two pieces: the current space to allocate +|* from, and the copying space. When the portion being allocated from fills up, +|* a garbage collection cycle happens, which copies all live blocks to the other +|* half of the managed space. +|* +\*===----------------------------------------------------------------------===*/ + +#include "../GCInterface.h" +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +/* AllocPtr - This points to the next byte that is available for allocation. + */ +static char *AllocPtr; + +/* AllocEnd - This points to the first byte not available for allocation. When + * AllocPtr passes this, we have run out of space. + */ +static char *AllocEnd; + +/* CurSpace/OtherSpace - These pointers point to the two regions of memory that + * we switch between. The unallocated portion of the CurSpace is known to be + * zero'd out, but the OtherSpace contains junk. + */ +static void *CurSpace, *OtherSpace; + +/* SpaceSize - The size of each space. */ +static unsigned SpaceSize; + +/* llvm_gc_initialize - Allocate the two spaces that we plan to switch between. + */ +void llvm_gc_initialize(unsigned InitialHeapSize) { + SpaceSize = InitialHeapSize/2; + CurSpace = AllocPtr = calloc(1, SpaceSize); + OtherSpace = malloc(SpaceSize); + AllocEnd = AllocPtr + SpaceSize; +} + +/* We always want to inline the fast path, but never want to inline the slow + * path. + */ +void *llvm_gc_allocate(unsigned Size) __attribute__((always_inline)); +static void* llvm_gc_alloc_slow(unsigned Size) __attribute__((noinline)); + +void *llvm_gc_allocate(unsigned Size) { + char *OldAP = AllocPtr; + char *NewEnd = OldAP+Size; + if (NewEnd > AllocEnd) + return llvm_gc_alloc_slow(Size); + AllocPtr = NewEnd; + return OldAP; +} + +static void* llvm_gc_alloc_slow(unsigned Size) { + llvm_gc_collect(); + if (AllocPtr+Size > AllocEnd) { + fprintf(stderr, "Garbage collector ran out of memory " + "allocating object of size: %d\n", Size); + exit(1); + } + + return llvm_gc_allocate(Size); +} + + +static void process_pointer(void **Root, void *Meta) { + printf("process_root[0x%p] = 0x%p\n", (void*) Root, (void*) *Root); +} + +void llvm_gc_collect() { + // Clear out the space we will be copying into. + // FIXME: This should do the copy, then clear out whatever space is left. + memset(OtherSpace, 0, SpaceSize); + + printf("Garbage collecting!!\n"); + llvm_cg_walk_gcroots(process_pointer); + abort(); +} + +/* We use no read/write barriers */ +void *llvm_gc_read(void *ObjPtr, void **FieldPtr) { return *FieldPtr; } +void llvm_gc_write(void *V, void *ObjPtr, void **FieldPtr) { *FieldPtr = V; } + + +/*===----------------------------------------------------------------------===** + * FIXME: This should be in a code-generator specific library, but for now this + * will work for all code generators. + */ +typedef struct GCRoot { + void **RootPtr; + void *Meta; +} GCRoot; + +typedef struct GCRoots { + struct GCRoots *Next; + unsigned NumRoots; + GCRoot RootRecords[]; +} GCRoots; +GCRoots *llvm_gc_root_chain; + +void llvm_cg_walk_gcroots(void (*FP)(void **Root, void *Meta)) { + GCRoots *R = llvm_gc_root_chain; + for (; R; R = R->Next) { + unsigned i, e; + for (i = 0, e = R->NumRoots; i != e; ++i) + FP(R->RootRecords[i].RootPtr, R->RootRecords[i].Meta); + } +} +/* END FIXME! */ + + diff --git a/runtime/GC/gc_exported_symbols.lst b/runtime/GC/gc_exported_symbols.lst new file mode 100644 index 0000000000..0ed60f57ee --- /dev/null +++ b/runtime/GC/gc_exported_symbols.lst @@ -0,0 +1,7 @@ +llvm_gc_initialize +llvm_gc_allocate +llvm_gc_collect +llvm_gc_write +llvm_gc_read + +llvm_gc_root_chain
\ No newline at end of file diff --git a/runtime/GCCLibraries/Makefile b/runtime/GCCLibraries/Makefile new file mode 100644 index 0000000000..b976f1248e --- /dev/null +++ b/runtime/GCCLibraries/Makefile @@ -0,0 +1,12 @@ +##===- runtime/GCCLibraries/Makefile -----------------------*- Makefile -*-===## +# +# The LLVM Compiler Infrastructure +# +# This file was developed by the LLVM research group and is distributed under +# the University of Illinois Open Source License. See LICENSE.TXT for details. +# +##===----------------------------------------------------------------------===## + +LEVEL := ../.. +PARALLEL_DIRS := crtend libc libgcc libm +include $(LEVEL)/Makefile.common diff --git a/runtime/GCCLibraries/README.txt b/runtime/GCCLibraries/README.txt new file mode 100644 index 0000000000..24890d2ef1 --- /dev/null +++ b/runtime/GCCLibraries/README.txt @@ -0,0 +1,7 @@ +This directory contains libraries which are used when building the GCC +front-end. For the most part, these are just stub libraries, but some +of them contain actual code. + +In particular, the crtend library contains the runtime code to handle +static constructors and destructors for C and C++ programs. + diff --git a/runtime/GCCLibraries/crtend/Exception.cpp b/runtime/GCCLibraries/crtend/Exception.cpp new file mode 100644 index 0000000000..d4ac290122 --- /dev/null +++ b/runtime/GCCLibraries/crtend/Exception.cpp @@ -0,0 +1,54 @@ +//===- Exception.cpp - Generic language-independent exceptions ------------===// +// +// This file defines the the shared data structures used by all language +// specific exception handling runtime libraries. +// +//===----------------------------------------------------------------------===// + +#include "Exception.h" + +// Thread local state for exception handling. FIXME: This should really be made +// thread-local! + +// UncaughtExceptionStack - The stack of exceptions currently being thrown. +static llvm_exception *UncaughtExceptionStack = 0; + +// __llvm_eh_has_uncaught_exception - This is used to implement +// std::uncaught_exception. +// +bool __llvm_eh_has_uncaught_exception() throw() { + return UncaughtExceptionStack != 0; +} + +// __llvm_eh_current_uncaught_exception - This function checks to see if the +// current uncaught exception is of the specified language type. If so, it +// returns a pointer to the exception area data. +// +void *__llvm_eh_current_uncaught_exception_type(unsigned HandlerType) throw() { + if (UncaughtExceptionStack->ExceptionType == HandlerType) + return UncaughtExceptionStack+1; + return 0; +} + +// __llvm_eh_add_uncaught_exception - This adds the specified exception to the +// top of the uncaught exception stack. The exception should not already be on +// the stack! +void __llvm_eh_add_uncaught_exception(llvm_exception *E) throw() { + E->Next = UncaughtExceptionStack; + UncaughtExceptionStack = E; +} + + +// __llvm_eh_get_uncaught_exception - Returns the current uncaught exception. +// There must be an uncaught exception for this to work! +llvm_exception *__llvm_eh_get_uncaught_exception() throw() { + return UncaughtExceptionStack; +} + +// __llvm_eh_pop_from_uncaught_stack - Remove the current uncaught exception +// from the top of the stack. +llvm_exception *__llvm_eh_pop_from_uncaught_stack() throw() { + llvm_exception *E = __llvm_eh_get_uncaught_exception(); + UncaughtExceptionStack = E->Next; + return E; +} diff --git a/runtime/GCCLibraries/crtend/Exception.h b/runtime/GCCLibraries/crtend/Exception.h new file mode 100644 index 0000000000..dc4d3a5f2c --- /dev/null +++ b/runtime/GCCLibraries/crtend/Exception.h @@ -0,0 +1,71 @@ +//===- Exception.h - Generic language-independent exceptions ----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by the LLVM research group and is distributed under +// the University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the the shared data structures used by all language +// specific exception handling runtime libraries. +// +// NOTE NOTE NOTE: A copy of this file lives in llvmgcc/libstdc++-v3/libsupc++/ +// Any modifications to this file must keep it in sync! +// +//===----------------------------------------------------------------------===// + +#ifndef EXCEPTION_H +#define EXCEPTION_H + +struct llvm_exception { + // ExceptionDestructor - This call-back function is used to destroy the + // current exception, without requiring the caller to know what the concrete + // exception type is. + // + void (*ExceptionDestructor)(llvm_exception *); + + // ExceptionType - This field identifies what runtime library this exception + // came from. Currently defined values are: + // 0 - Error + // 1 - longjmp exception (see longjmp-exception.c) + // 2 - C++ exception (see c++-exception.c) + // + unsigned ExceptionType; + + // Next - This points to the next exception in the current stack. + llvm_exception *Next; + + // HandlerCount - This is a count of the number of handlers which have + // currently caught this exception. If the handler is caught and this number + // falls to zero, the exception is destroyed. + // + unsigned HandlerCount; + + // isRethrown - This field is set on an exception if it has been 'throw;'n. + // This is needed because the exception might exit through a number of the + // end_catch statements matching the number of begin_catch statements that + // have been processed. When this happens, the exception should become + // uncaught, not dead. + // + int isRethrown; +}; + +enum { + ErrorException = 0, + SJLJException = 1, + CXXException = 2 +}; + +// Language independent exception handling API... +// +extern "C" { + bool __llvm_eh_has_uncaught_exception() throw(); + void *__llvm_eh_current_uncaught_exception_type(unsigned HandlerType) throw(); + void __llvm_eh_add_uncaught_exception(llvm_exception *E) throw(); + + llvm_exception *__llvm_eh_get_uncaught_exception() throw(); + llvm_exception *__llvm_eh_pop_from_uncaught_stack() throw(); +} + +#endif diff --git a/runtime/GCCLibraries/crtend/Makefile b/runtime/GCCLibraries/crtend/Makefile new file mode 100644 index 0000000000..1fd3167246 --- /dev/null +++ b/runtime/GCCLibraries/crtend/Makefile @@ -0,0 +1,83 @@ +##===- runtime/GCCLibraries/crtend/Makefile ----------------*- Makefile -*-===## +# +# The LLVM Compiler Infrastructure +# +# This file was developed by the LLVM research group and is distributed under +# the University of Illinois Open Source License. See LICENSE.TXT for details. +# +##===----------------------------------------------------------------------===## +# +# This directory contains the C and C++ runtime libraries for the LLVM GCC +# front-ends. See the README.txt file for more details. +# +# Since this archive has strange requirements, we use some custom rules for +# building it. +# +##===----------------------------------------------------------------------===## + +LEVEL = ../../.. +DONT_BUILD_RELINKED = 1 +LIBRARYNAME = crtend +BYTECODE_DESTINATION = $(CFERuntimeLibDir) + +MainSrc := crtend.c +GenericEHSrc := Exception.cpp +SJLJEHSrc := SJLJ-Exception.cpp + +EXTRA_DIST := $(MainSrc) $(GenericEHSrc) $(SJLJEHSrc) \ + comp_main.lst comp_genericeh.lst comp_sjljeh.lst + +include $(LEVEL)/Makefile.common + +MainObj := $(ObjDir)/crtend.bc +GenericEHObj := $(ObjDir)/Exception.bc +SJLJEHObj := $(ObjDir)/SJLJ-Exception.bc + +# __main and ctor/dtor support component +$(ObjDir)/comp_main.bc: $(MainObj) + $(Echo) Linking $(notdir $@) component... + $(Verb) $(GCCLD) -link-as-library \ + -internalize-public-api-file=$(PROJ_SRC_DIR)/comp_main.lst \ + $(MainObj) -o $@ + +# Generic exception handling support runtime. +$(ObjDir)/comp_genericeh.bc: $(GenericEHObj) + $(Echo) Linking $(notdir $@) component... + $(Verb) $(GCCLD) -link-as-library \ + -internalize-public-api-file=$(PROJ_SRC_DIR)/comp_genericeh.lst \ + $(GenericEHObj) -o $@ + +# setjmp/longjmp exception handling support runtime. +$(ObjDir)/comp_sjljeh.bc: $(SJLJEHObj) + $(Echo) Linking $(notdir $@) component... + $(Verb) $(GCCLD) -link-as-library \ + -internalize-public-api-file=$(PROJ_SRC_DIR)/comp_sjljeh.lst \ + $(SJLJEHObj) -o $@ + +SYMBOLHACKEDOBJS := $(ObjDir)/comp_main.bc $(ObjDir)/comp_genericeh.bc \ + $(ObjDir)/comp_sjljeh.bc + +all-local:: $(LibName.BCA) + +ifdef BYTECODE_DESTINATION +BytecodeDestDir := $(BYTECODE_DESTINATION) +else +BytecodeDestDir := $(PROJ_libdir) +endif + +DestBytecodeLib = $(BytecodeDestDir)/lib$(LIBRARYNAME).a +install-bytecode-local:: $(DestBytecodeLib) +install-local:: $(DestBytecodeLib) + +$(LibName.BCA): $(SYMBOLHACKEDOBJS) $(LibDir)/.dir $(LLVMToolDir)/llvm-ar + $(Echo) Building $(BuildMode) Bytecode Archive $(notdir $@) + $(Verb) $(RM) -f $@ + $(Verb) $(LArchive) $@ $(SYMBOLHACKEDOBJS) + +$(DestBytecodeLib): $(BytecodeDestDir) $(LibName.BCA) + $(Echo) Installing $(BuildMode) Bytecode Archive $(DestBytecodeLib) + $(Verb) $(DataInstall) $(LibName.BCA) $(DestBytecodeLib) + +uninstall-local:: + $(Echo) Uninstalling $(BuildMode) Bytecode Archive $(DestBytecodeLib) + -$(Verb) $(RM) -f $(DestBytecodeLib) diff --git a/runtime/GCCLibraries/crtend/README.txt b/runtime/GCCLibraries/crtend/README.txt new file mode 100644 index 0000000000..a763cb26dd --- /dev/null +++ b/runtime/GCCLibraries/crtend/README.txt @@ -0,0 +1,15 @@ +This directory contains the C and C++ runtime libraries for the LLVM GCC +front-ends. It is composed of four distinct pieces: + +1. __main: now dead, but provided for compatibility. + +2. Generic EH support routines. This is used by C/C++ programs that use + setjmp/longjmp, and by C++ programs that make use of exceptions. + +3. setjmp/longjmp EH support. This is used by C/C++ programs that call SJLJ. + +4. C++ exception handling runtime support. + +These four components are compiled together into an archive file, so that +applications using a subset of the four do not pull in unnecessary code and +dependencies. diff --git a/runtime/GCCLibraries/crtend/SJLJ-Exception.cpp b/runtime/GCCLibraries/crtend/SJLJ-Exception.cpp new file mode 100644 index 0000000000..6a3e4724ae --- /dev/null +++ b/runtime/GCCLibraries/crtend/SJLJ-Exception.cpp @@ -0,0 +1,146 @@ +//===- SJLJ-Exception.cpp - SetJmp/LongJmp Exception Handling -------------===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by the LLVM research group and is distributed under +// the University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements the API used by the Setjmp/Longjmp exception handling +// runtime library. +// +//===----------------------------------------------------------------------===// + +#include "SJLJ-Exception.h" +#include <cstdlib> +#include <cassert> + +// Assert should only be used for debugging the runtime library. Enabling it in +// CVS will break some platforms! +#undef assert +#define assert(X) + +// get_sjlj_exception - Adjust the llvm_exception pointer to be an appropriate +// llvm_sjlj_exception pointer. +inline llvm_sjlj_exception *get_sjlj_exception(llvm_exception *E) { + assert(E->ExceptionType == SJLJException); + return (llvm_sjlj_exception*)(E+1) - 1; +} + +// SetJmpMapEntry - One entry in a linked list of setjmps for the current +// function. +struct SetJmpMapEntry { + void *JmpBuf; + unsigned SetJmpID; + SetJmpMapEntry *Next; +}; + +// SJLJDestructor - This function is used to free the exception when +// language-indent code needs to destroy the exception without knowing exactly +// what type it is. +static void SJLJDestructor(llvm_exception *E) { + free(get_sjlj_exception(E)); +} + + +// __llvm_sjljeh_throw_longjmp - This function creates the longjmp exception and +// returns. It takes care of mapping the longjmp value from 0 -> 1 as +// appropriate. The caller should immediately call llvm.unwind after this +// function call. +void __llvm_sjljeh_throw_longjmp(void *JmpBuffer, int Val) throw() { + llvm_sjlj_exception *E = + (llvm_sjlj_exception *)malloc(sizeof(llvm_sjlj_exception)); + E->BaseException.ExceptionDestructor = SJLJDestructor; + E->BaseException.ExceptionType = SJLJException; + E->BaseException.HandlerCount = 0; + E->BaseException.isRethrown = 0; + E->JmpBuffer = JmpBuffer; + E->LongJmpValue = Val ? Val : 1; + + __llvm_eh_add_uncaught_exception(&E->BaseException); +} + +// __llvm_sjljeh_init_setjmpmap - This funciton initializes the pointer provided +// to an empty setjmp map, and should be called on entry to a function which +// calls setjmp. +void __llvm_sjljeh_init_setjmpmap(void **SetJmpMap) throw() { + *SetJmpMap = 0; +} + +// __llvm_sjljeh_destroy_setjmpmap - This function frees all memory associated +// with the specified setjmpmap structure. It should be called on all exits +// (returns or unwinds) from the function which calls ...init_setjmpmap. +void __llvm_sjljeh_destroy_setjmpmap(void **SetJmpMap) throw() { + SetJmpMapEntry *Next; + for (SetJmpMapEntry *SJE = *(SetJmpMapEntry**)SetJmpMap; SJE; SJE = Next) { + Next = SJE->Next; + free(SJE); + } +} + +// __llvm_sjljeh_add_setjmp_to_map - This function adds or updates an entry to +// the map, to indicate which setjmp should be returned to if a longjmp happens. +void __llvm_sjljeh_add_setjmp_to_map(void **SetJmpMap, void *JmpBuf, + unsigned SetJmpID) throw() { + SetJmpMapEntry **SJE = (SetJmpMapEntry**)SetJmpMap; + + // Scan for a pre-existing entry... + for (; *SJE; SJE = &(*SJE)->Next) + if ((*SJE)->JmpBuf == JmpBuf) { + (*SJE)->SetJmpID = SetJmpID; + return; + } + + // No prexisting entry found, append to the end of the list... + SetJmpMapEntry *New = (SetJmpMapEntry *)malloc(sizeof(SetJmpMapEntry)); + *SJE = New; + New->JmpBuf = JmpBuf; + New->SetJmpID = SetJmpID; + New->Next = 0; +} + +// __llvm_sjljeh_is_longjmp_exception - This function returns true if the +// current uncaught exception is a longjmp exception. This is the first step of +// catching a sjlj exception. +bool __llvm_sjljeh_is_longjmp_exception() throw() { + return __llvm_eh_current_uncaught_exception_type(SJLJException) != 0; +} + +// __llvm_sjljeh_get_longjmp_value - This function returns the value that the +// setjmp call should "return". This requires that the current uncaught +// exception be a sjlj exception, though it does not require the exception to be +// caught by this function. +int __llvm_sjljeh_get_longjmp_value() throw() { + llvm_sjlj_exception *E = + get_sjlj_exception(__llvm_eh_get_uncaught_exception()); + return E->LongJmpValue; +} + +// __llvm_sjljeh_try_catching_longjmp_exception - This function checks to see if +// the current uncaught longjmp exception matches any of the setjmps collected +// in the setjmpmap structure. If so, it catches and destroys the exception, +// returning the index of the setjmp which caught the exception. If not, it +// leaves the exception uncaught and returns a value of ~0. +unsigned __llvm_sjljeh_try_catching_longjmp_exception(void **SetJmpMap) throw(){ + llvm_sjlj_exception *E = + get_sjlj_exception(__llvm_eh_get_uncaught_exception()); + + // Scan for a matching entry in the SetJmpMap... + SetJmpMapEntry *SJE = *(SetJmpMapEntry**)SetJmpMap; + for (; SJE; SJE = SJE->Next) + if (SJE->JmpBuf == E->JmpBuffer) { + // "Catch" and destroy the exception... + __llvm_eh_pop_from_uncaught_stack(); + + // We know it's a longjmp exception, so we can just free it instead of + // calling the destructor. + free(E); + + // Return the setjmp ID which we should branch to... + return SJE->SetJmpID; + } + + // No setjmp in this function catches the exception! + return ~0; +} diff --git a/runtime/GCCLibraries/crtend/SJLJ-Exception.h b/runtime/GCCLibraries/crtend/SJLJ-Exception.h new file mode 100644 index 0000000000..ac27cbed7f --- /dev/null +++ b/runtime/GCCLibraries/crtend/SJLJ-Exception.h @@ -0,0 +1,80 @@ +//===- SJLJ-Exception.h - SetJmp/LongJmp Exception Handling -----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by the LLVM research group and is distributed under +// the University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the data structures and API used by the Setjmp/Longjmp +// exception handling runtime library. +// +//===----------------------------------------------------------------------===// + +#ifndef SJLJ_EXCEPTION_H +#define SJLJ_EXCEPTION_H + +#include "Exception.h" + +struct llvm_sjlj_exception { + // JmpBuffer - This is the buffer which was longjmp'd with. + // + void *JmpBuffer; + + // LongJmpValue - The value passed into longjmp, which the corresponding + // setjmp should return. Note that this value will never be equal to 0. + // + int LongJmpValue; + + // BaseException - The language independent portion of the exception state. + // This is at the end of the record so that we can add additional members to + // this structure without breaking binary compatibility. + // + llvm_exception BaseException; +}; + +extern "C" { + // __llvm_sjljeh_throw_longjmp - This function creates the longjmp exception + // and returns. It takes care of mapping the longjmp value from 0 -> 1 as + // appropriate. The caller should immediately call llvm.unwind after this + // function call. + void __llvm_sjljeh_throw_longjmp(void *JmpBuffer, int Val) throw(); + + // __llvm_sjljeh_init_setjmpmap - This funciton initializes the pointer + // provided to an empty setjmp map, and should be called on entry to a + // function which calls setjmp. + void __llvm_sjljeh_init_setjmpmap(void **SetJmpMap) throw(); + + // __llvm_sjljeh_destroy_setjmpmap - This function frees all memory associated + // with the specified setjmpmap structure. It should be called on all exits + // (returns or unwinds) from the function which calls ...init_setjmpmap. + void __llvm_sjljeh_destroy_setjmpmap(void **SetJmpMap) throw(); + + // __llvm_sjljeh_add_setjmp_to_map - This function adds or updates an entry to + // the map, to indicate which setjmp should be returned to if a longjmp + // happens. + void __llvm_sjljeh_add_setjmp_to_map(void **SetJmpMap, void *JmpBuf, + unsigned SetJmpID) throw(); + + // __llvm_sjljeh_is_longjmp_exception - This function returns true if the + // current uncaught exception is a longjmp exception. This is the first step + // of catching a sjlj exception. + bool __llvm_sjljeh_is_longjmp_exception() throw(); + + // __llvm_sjljeh_get_longjmp_value - This function returns the value that the + // setjmp call should "return". This requires that the current uncaught + // exception be a sjlj exception, though it does not require the exception to + // be caught by this function. + int __llvm_sjljeh_get_longjmp_value() throw(); + + // __llvm_sjljeh_try_catching_longjmp_exception - This function checks to see + // if the current uncaught longjmp exception matches any of the setjmps + // collected in the setjmpmap structure. If so, it catches and destroys the + // exception, returning the index of the setjmp which caught the exception. + // If not, it leaves the exception uncaught and returns a value of ~0. + unsigned __llvm_sjljeh_try_catching_longjmp_exception(void **SetJmpMap) + throw(); +} + +#endif diff --git a/runtime/GCCLibraries/crtend/comp_genericeh.lst b/runtime/GCCLibraries/crtend/comp_genericeh.lst new file mode 100644 index 0000000000..9270648b03 --- /dev/null +++ b/runtime/GCCLibraries/crtend/comp_genericeh.lst @@ -0,0 +1,9 @@ +__main +llvm.global_ctors +llvm.global_dtors + +__llvm_eh_has_uncaught_exception +__llvm_eh_current_uncaught_exception_type +__llvm_eh_add_uncaught_exception +__llvm_eh_get_uncaught_exception +__llvm_eh_pop_from_uncaught_stack diff --git a/runtime/GCCLibraries/crtend/comp_main.lst b/runtime/GCCLibraries/crtend/comp_main.lst new file mode 100644 index 0000000000..ea953b7f92 --- /dev/null +++ b/runtime/GCCLibraries/crtend/comp_main.lst @@ -0,0 +1,3 @@ +__main +llvm.global_ctors +llvm.global_dtors diff --git a/runtime/GCCLibraries/crtend/comp_sjljeh.lst b/runtime/GCCLibraries/crtend/comp_sjljeh.lst new file mode 100644 index 0000000000..afcaaf0d05 --- /dev/null +++ b/runtime/GCCLibraries/crtend/comp_sjljeh.lst @@ -0,0 +1,7 @@ +__llvm_sjljeh_throw_longjmp +__llvm_sjljeh_init_setjmpmap +__llvm_sjljeh_destroy_setjmpmap +__llvm_sjljeh_add_setjmp_to_map +__llvm_sjljeh_is_longjmp_exception +__llvm_sjljeh_get_longjmp_value +__llvm_sjljeh_try_catching_longjmp_exception diff --git a/runtime/GCCLibraries/crtend/crtend.c b/runtime/GCCLibraries/crtend/crtend.c new file mode 100644 index 0000000000..561b6fd241 --- /dev/null +++ b/runtime/GCCLibraries/crtend/crtend.c @@ -0,0 +1,16 @@ +/*===- crtend.c - Initialization code for programs ------------------------===*\ + * + * The LLVM Compiler Infrastructure + * + * This file was developed by the LLVM research group and is distributed under + * the University of Illinois Open Source License. See LICENSE.TXT for details. + * + *===----------------------------------------------------------------------===* + * + * This file defines the __main function, which we preserve for backwards + * compatibility. + * +\*===----------------------------------------------------------------------===*/ + +void __main(void) { +} diff --git a/runtime/GCCLibraries/libc/COPYING.LIB b/runtime/GCCLibraries/libc/COPYING.LIB new file mode 100644 index 0000000000..cf9b6b9972 --- /dev/null +++ b/runtime/GCCLibraries/libc/COPYING.LIB @@ -0,0 +1,510 @@ + + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations +below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. +^L + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it +becomes a de-facto standard. To achieve this, non-free programs must +be allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. +^L + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control +compilation and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. +^L + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. +^L + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at least + three years, to give the same user the materials specified in + Subsection 6a, above, for a charge no more than the cost of + performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. +^L + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. +^L + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply, and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License +may add an explicit geographical distribution limitation excluding those +countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. +^L + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS +^L + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms +of the ordinary General Public License). + + To apply these terms, attach the following notices to the library. +It is safest to attach them to the start of each source file to most +effectively convey the exclusion of warranty; and each file should +have at least the "copyright" line and a pointer to where the full +notice is found. + + + <one line to give the library's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or +your school, if any, to sign a "copyright disclaimer" for the library, +if necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James + Random Hacker. + + <signature of Ty Coon>, 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/runtime/GCCLibraries/libc/LICENSE.TXT b/runtime/GCCLibraries/libc/LICENSE.TXT new file mode 100644 index 0000000000..7bcfd36d9f --- /dev/null +++ b/runtime/GCCLibraries/libc/LICENSE.TXT @@ -0,0 +1,17 @@ +libc +------------------------------------------------------------------------------ +The stripped down C library found in llvm/runtime/GCCLibraries/libc is licensed +to you under the GNU Lesser General Public License (LGPL). The license, along +with copyright information, is in COPYING.LIB. + +Portions of glibc also contain copyrights and licenses from third parties. +Those are listed in LICENSES. + +FSF copyright and warranty disclaimer: +Copyright (C) 1991, 1992, 1996, 1997, 1999 Free Software Foundation, Inc. +Copyright (C) 1995,96,97,2002 Free Software Foundation, Inc. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. diff --git a/runtime/GCCLibraries/libc/LICENSES b/runtime/GCCLibraries/libc/LICENSES new file mode 100644 index 0000000000..b3b8899e5a --- /dev/null +++ b/runtime/GCCLibraries/libc/LICENSES @@ -0,0 +1,219 @@ +This file contains the copying permission notices for various files in the +GNU C Library distribution that have copyright owners other than the Free +Software Foundation. These notices all require that a copy of the notice +be included in the accompanying documentation and be distributed with +binary distributions of the code, so be sure to include this file along +with any binary distributions derived from the GNU C Library. + + +All code incorporated from 4.4 BSD is distributed under the following +license: + +Copyright (C) 1991 Regents of the University of California. +All rights reserved. + +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. [This condition was removed.] +4. Neither the name of the University nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 THE REGENTS OR 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. + +The DNS resolver code, taken from BIND 4.9.5, is copyrighted both by +UC Berkeley and by Digital Equipment Corporation. The DEC portions +are under the following license: + +Portions Copyright (C) 1993 by Digital Equipment Corporation. + +Permission to use, copy, modify, and distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies, and +that the name of Digital Equipment Corporation not be used in +advertising or publicity pertaining to distribution of the document or +software without specific, written prior permission. + +THE SOFTWARE IS PROVIDED ``AS IS'' AND DIGITAL EQUIPMENT CORP. +DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL +DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING +FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION +WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +The Sun RPC support (from rpcsrc-4.0) is covered by the following +license: + +Copyright (C) 1984, Sun Microsystems, Inc. + +Sun RPC is a product of Sun Microsystems, Inc. and is provided for +unrestricted use provided that this legend is included on all tape media +and as a part of the software program in whole or part. Users may copy +or modify Sun RPC without charge, but are not authorized to license or +distribute it to anyone else except as part of a product or program +developed by the user. + +SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE +WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR +PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + +Sun RPC is provided with no support and without any obligation on the +part of Sun Microsystems, Inc. to assist in its use, correction, +modification or enhancement. + +SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE +INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC +OR ANY PART THEREOF. + +In no event will Sun Microsystems, Inc. be liable for any lost revenue +or profits or other special, indirect and consequential damages, even if +Sun has been advised of the possibility of such damages. + + +The following CMU license covers some of the support code for Mach, +derived from Mach 3.0: + +Mach Operating System +Copyright (C) 1991,1990,1989 Carnegie Mellon University +All Rights Reserved. + +Permission to use, copy, modify and distribute this software and its +documentation is hereby granted, provided that both the copyright +notice and this permission notice appear in all copies of the +software, derivative works or modified versions, and any portions +thereof, and that both notices appear in supporting documentation. + +CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS ``AS IS'' +CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR +ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + +Carnegie Mellon requests users of this software to return to + + Software Distribution Coordinator + School of Computer Science + Carnegie Mellon University + Pittsburgh PA 15213-3890 + +or Software.Distribution@CS.CMU.EDU any improvements or +extensions that they make and grant Carnegie Mellon the rights to +redistribute these changes. + +The file if_ppp.h is under the following CMU license: + + 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 of the University nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY AND + CONTRIBUTORS ``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 THE UNIVERSITY OR 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. + +The following license covers the files from Intel's "Highly Optimized +Mathematical Functions for Itanium" collection: + +Intel License Agreement + +Copyright (c) 2000, Intel Corporation + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +* Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + +* 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. + +* The name of Intel Corporation may not be used to endorse or promote +products derived from this software without specific prior written +permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"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 INTEL OR +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. + +The files inet/getnameinfo.c and sysdeps/posix/getaddrinfo.c are copyright +(C) by Craig Metz and are distributed under the following license: + +/* The Inner Net License, Version 2.00 + + The author(s) grant permission for redistribution and use in source and +binary forms, with or without modification, of the software and documentation +provided that the following conditions are met: + +0. If you receive a version of the software that is specifically labelled + as not being for redistribution (check the version message and/or README), + you are not permitted to redistribute that version of the software in any + way or form. +1. All terms of the all other applicable copyrights and licenses must be + followed. +2. Redistributions of source code must retain the authors' copyright + notice(s), this list of conditions, and the following disclaimer. +3. Redistributions in binary form must reproduce the authors' copyright + notice(s), this list of conditions, and the following disclaimer in the + documentation and/or other materials provided with the distribution. +4. [The copyright holder has authorized the removal of this clause.] +5. Neither the name(s) of the author(s) nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY ITS AUTHORS AND CONTRIBUTORS ``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 THE AUTHORS OR 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. + + If these license terms cause you a real problem, contact the author. */ diff --git a/runtime/GCCLibraries/libc/Makefile b/runtime/GCCLibraries/libc/Makefile new file mode 100644 index 0000000000..4dc2f88a92 --- /dev/null +++ b/runtime/GCCLibraries/libc/Makefile @@ -0,0 +1,19 @@ +##===- runtime/GCCLibraries/libc/Makefile ------------------*- Makefile -*-===## +# +# The LLVM Compiler Infrastructure +# +# This file was developed by the LLVM research group and is distributed under +# the University of Illinois Open Source License. See LICENSE.TXT for details. +# +##===----------------------------------------------------------------------===## + +LEVEL = ../../.. +BYTECODE_LIBRARY = 1 +DONT_BUILD_RELINKED = 1 +LIBRARYNAME = c +BYTECODE_DESTINATION = $(CFERuntimeLibDir) + +include $(LEVEL)/Makefile.common + +CompileCommonOpts := $(filter-out -pedantic,$(CompileCommonOpts)) +CompileCommonOpts := $(filter-out -Wno-long-long,$(CompileCommonOpts)) diff --git a/runtime/GCCLibraries/libc/README.txt b/runtime/GCCLibraries/libc/README.txt new file mode 100644 index 0000000000..c29ebc6e42 --- /dev/null +++ b/runtime/GCCLibraries/libc/README.txt @@ -0,0 +1,4 @@ +This directory contains source files to build the LLVM version of libc. + +Currently it is hacked together on a by-demand basis, but someday a proper +port of libc would be very nice. diff --git a/runtime/GCCLibraries/libc/atox.c b/runtime/GCCLibraries/libc/atox.c new file mode 100644 index 0000000000..726f432626 --- /dev/null +++ b/runtime/GCCLibraries/libc/atox.c @@ -0,0 +1,118 @@ +//===-- atox.c - Ascii string parsers for LLVM libc Library -------*- C -*-===// +// +// A lot of this code is ripped gratuitously from glibc and libiberty. +// +//===----------------------------------------------------------------------===// + + +#define isspace(x) ((x) == ' ' || (x) == '\t' || (x) == '\n') +#define isdigit(x) ((x) >= '0' && (x) <= '9') +#define isupper(x) ((x) >= 'A' && (x) <= 'Z') +#define islower(x) ((x) >= 'a' && (x) <= 'z') +#define isalpha(x) (isupper(x) || islower(x)) + +#ifndef ULONG_MAX +#define ULONG_MAX ((unsigned long)(~0L)) /* 0xFFFFFFFF */ +#endif + +#ifndef LONG_MAX +#define LONG_MAX ((long)(ULONG_MAX >> 1)) /* 0x7FFFFFFF */ +#endif + +#ifndef LONG_MIN +#define LONG_MIN ((long)(~LONG_MAX)) /* 0x80000000 */ +#endif + +#if 0 +/* + * Convert a string to a long integer. + * + * Ignores `locale' stuff. Assumes that the upper and lower case + * alphabets and digits are each contiguous. + */ +long strtol(const char *nptr, char **endptr, int base) { + register const char *s = nptr; + register unsigned long acc; + register int c; + register unsigned long cutoff; + register int neg = 0, any, cutlim; + + /* + * Skip white space and pick up leading +/- sign if any. + * If base is 0, allow 0x for hex and 0 for octal, else + * assume decimal; if base is already 16, allow 0x. + */ + do { + c = *s++; + } while (isspace(c)); + if (c == '-') { + neg = 1; + c = *s++; + } else if (c == '+') + c = *s++; + if ((base == 0 || base == 16) && + c == '0' && (*s == 'x' || *s == 'X')) { + c = s[1]; + s += 2; + base = 16; + } + if (base == 0) + base = c == '0' ? 8 : 10; + + /* + * Compute the cutoff value between legal numbers and illegal + * numbers. That is the largest legal value, divided by the + * base. An input number that is greater than this value, if + * followed by a legal input character, is too big. One that + * is equal to this value may be valid or not; the limit + * between valid and invalid numbers is then based on the last + * digit. For instance, if the range for longs is + * [-2147483648..2147483647] and the input base is 10, + * cutoff will be set to 214748364 and cutlim to either + * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated + * a value > 214748364, or equal but the next digit is > 7 (or 8), + * the number is too big, and we will return a range error. + * + * Set any if any `digits' consumed; make it negative to indicate + * overflow. + */ + cutoff = neg ? -(unsigned long)LONG_MIN : LONG_MAX; + cutlim = cutoff % (unsigned long)base; + cutoff /= (unsigned long)base; + for (acc = 0, any = 0;; c = *s++) { + if (isdigit(c)) + c -= '0'; + else if (isalpha(c)) + c -= isupper(c) ? 'A' - 10 : 'a' - 10; + else + break; + if (c >= base) + break; + if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim) + any = -1; + else { + any = 1; + acc *= base; + acc += c; + } + } + if (any < 0) { + acc = neg ? LONG_MIN : LONG_MAX; + } else if (neg) + acc = -acc; + if (endptr != 0) + *endptr = (char *) (any ? s - 1 : nptr); + return (acc); +} + + +/* Convert a string to an int. */ +int atoi(const char *nptr) { + return (int)strtol(nptr, 0, 10); +} + +/* Convert a string to a long int. */ +long int atol(const char *nptr) { + return strtol(nptr, 0, 10); +} +#endif diff --git a/runtime/GCCLibraries/libc/io.c b/runtime/GCCLibraries/libc/io.c new file mode 100644 index 0000000000..e09283ada5 --- /dev/null +++ b/runtime/GCCLibraries/libc/io.c @@ -0,0 +1,18 @@ +//===-- io.c - IO routines for LLVM libc Library ------------------*- C -*-===// +// +// A lot of this code is ripped gratuitously from glibc and libiberty. +// +//===----------------------------------------------------------------------===// + +int putchar(int); + +// The puts() function writes the string pointed to by s, followed by a +// NEWLINE character, to the standard output stream stdout. On success the +// number of characters written is returned; otherwise they return EOF. +// +int puts(const char *S) { + const char *Str = S; + while (*Str) putchar(*Str++); + putchar('\n'); + return Str+1-S; +} diff --git a/runtime/GCCLibraries/libc/qsort.c b/runtime/GCCLibraries/libc/qsort.c new file mode 100644 index 0000000000..2949b7848b --- /dev/null +++ b/runtime/GCCLibraries/libc/qsort.c @@ -0,0 +1,261 @@ +//===-- qsort.c - The qsort function for the LLVM libc Library ----*- C -*-===// +// +// This code is a modified form of the qsort() function from the GNU C +// library. +// +// Modifications: +// 2003/05/29 - Code disabled for compilation. Line wrapping changed. +// +//===----------------------------------------------------------------------===// + +/* Copyright (C) 1991, 1992, 1996, 1997, 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Written by Douglas C. Schmidt (schmidt@ics.uci.edu). + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +/* If you consider tuning this algorithm, you should consult first: + Engineering a sort function; Jon Bentley and M. Douglas McIlroy; + Software - Practice and Experience; Vol. 23 (11), 1249-1265, 1993. */ + +#if 0 + +#include <limits.h> +#include <stdlib.h> +#include <string.h> + +/* Byte-wise swap two items of size SIZE. */ +#define SWAP(a, b, size) \ + do \ + { \ + register size_t __size = (size); \ + register char *__a = (a), *__b = (b); \ + do \ + { \ + char __tmp = *__a; \ + *__a++ = *__b; \ + *__b++ = __tmp; \ + } while (--__size > 0); \ + } while (0) + +/* Discontinue quicksort algorithm when partition gets below this size. + This particular magic number was chosen to work best on a Sun 4/260. */ +#define MAX_THRESH 4 + +/* Stack node declarations used to store unfulfilled partition obligations. */ +typedef struct + { + char *lo; + char *hi; + } stack_node; + +/* The next 4 #defines implement a very fast in-line stack abstraction. */ +/* The stack needs log (total_elements) entries (we could even subtract + log(MAX_THRESH)). Since total_elements has type size_t, we get as + upper bound for log (total_elements): + bits per byte (CHAR_BIT) * sizeof(size_t). */ +#define STACK_SIZE (CHAR_BIT * sizeof(size_t)) +#define PUSH(low, high) ((void) ((top->lo = (low)), (top->hi = (high)), ++top)) +#define POP(low, high) ((void) (--top, (low = top->lo), (high = top->hi))) +#define STACK_NOT_EMPTY (stack < top) + + +/* Order size using quicksort. This implementation incorporates + four optimizations discussed in Sedgewick: + + 1. Non-recursive, using an explicit stack of pointer that store the + next array partition to sort. To save time, this maximum amount + of space required to store an array of SIZE_MAX is allocated on the + stack. Assuming a 32-bit (64 bit) integer for size_t, this needs + only 32 * sizeof(stack_node) == 256 bytes (for 64 bit: 1024 bytes). + Pretty cheap, actually. + + 2. Chose the pivot element using a median-of-three decision tree. + This reduces the probability of selecting a bad pivot value and + eliminates certain extraneous comparisons. + + 3. Only quicksorts TOTAL_ELEMS / MAX_THRESH partitions, leaving + insertion sort to order the MAX_THRESH items within each partition. + This is a big win, since insertion sort is faster for small, mostly + sorted array segments. + + 4. The larger of the two sub-partitions is always pushed onto the + stack first, with the algorithm then concentrating on the + smaller partition. This *guarantees* no more than log (total_elems) + stack size is needed (actually O(1) in this case)! */ + +typedef int(*__compar_fn_t)(const void *, const void *); +void +qsort (void *const pbase, size_t total_elems, size_t size, + __compar_fn_t cmp) +{ + register char *base_ptr = (char *) pbase; + + const size_t max_thresh = MAX_THRESH * size; + + if (total_elems == 0) + /* Avoid lossage with unsigned arithmetic below. */ + return; + + if (total_elems > MAX_THRESH) + { + char *lo = base_ptr; + char *hi = &lo[size * (total_elems - 1)]; + stack_node stack[STACK_SIZE]; + stack_node *top = stack + 1; + + while (STACK_NOT_EMPTY) + { + char *left_ptr; + char *right_ptr; + + /* Select median value from among LO, MID, and HI. Rearrange + LO and HI so the three values are sorted. This lowers the + probability of picking a pathological pivot value and + skips a comparison for both the LEFT_PTR and RIGHT_PTR in + the while loops. */ + + char *mid = lo + size * ((hi - lo) / size >> 1); + + if ((*cmp) ((void *) mid, (void *) lo) < 0) + SWAP (mid, lo, size); + if ((*cmp) ((void *) hi, (void *) mid) < 0) + SWAP (mid, hi, size); + else + goto jump_over; + if ((*cmp) ((void *) mid, (void *) lo) < 0) + SWAP (mid, lo, size); + jump_over:; + + left_ptr = lo + size; + right_ptr = hi - size; + + /* Here's the famous ``collapse the walls'' section of quicksort. + Gotta like those tight inner loops! They are the main reason + that this algorithm runs much faster than others. */ + do + { + while ((*cmp) ((void *) left_ptr, (void *) mid) < 0) + left_ptr += size; + + while ((*cmp) ((void *) mid, (void *) right_ptr) < 0) + right_ptr -= size; + + if (left_ptr < right_ptr) + { + SWAP (left_ptr, right_ptr, size); + if (mid == left_ptr) + mid = right_ptr; + else if (mid == right_ptr) + mid = left_ptr; + left_ptr += size; + right_ptr -= size; + } + else if (left_ptr == right_ptr) + { + left_ptr += size; + right_ptr -= size; + break; + } + } + while (left_ptr <= right_ptr); + + /* Set up pointers for next iteration. First determine whether + left and right partitions are below the threshold size. If so, + ignore one or both. Otherwise, push the larger partition's + bounds on the stack and continue sorting the smaller one. */ + + if ((size_t) (right_ptr - lo) <= max_thresh) + { + if ((size_t) (hi - left_ptr) <= max_thresh) + /* Ignore both small partitions. */ + POP (lo, hi); + else + /* Ignore small left partition. */ + lo = left_ptr; + } + else if ((size_t) (hi - left_ptr) <= max_thresh) + /* Ignore small right partition. */ + hi = right_ptr; + else if ((right_ptr - lo) > (hi - left_ptr)) + { + /* Push larger left partition indices. */ + PUSH (lo, right_ptr); + lo = left_ptr; + } + else + { + /* Push larger right partition indices. */ + PUSH (left_ptr, hi); + hi = right_ptr; + } + } + } + + /* Once the BASE_PTR array is partially sorted by quicksort the rest + is completely sorted using insertion sort, since this is efficient + for partitions below MAX_THRESH size. BASE_PTR points to the beginning + of the array to sort, and END_PTR points at the very last element in + the array (*not* one beyond it!). */ + +#define min(x, y) ((x) < (y) ? (x) : (y)) + + { + char *const end_ptr = &base_ptr[size * (total_elems - 1)]; + char *tmp_ptr = base_ptr; + char *thresh = min(end_ptr, base_ptr + max_thresh); + register char *run_ptr; + + /* Find smallest element in first threshold and place it at the + array's beginning. This is the smallest array element, + and the operation speeds up insertion sort's inner loop. */ + + for (run_ptr = tmp_ptr + size; run_ptr <= thresh; run_ptr += size) + if ((*cmp) ((void *) run_ptr, (void *) tmp_ptr) < 0) + tmp_ptr = run_ptr; + + if (tmp_ptr != base_ptr) + SWAP (tmp_ptr, base_ptr, size); + + /* Insertion sort, running from left-hand-side up to right-hand-side. */ + + run_ptr = base_ptr + size; + while ((run_ptr += size) <= end_ptr) + { + tmp_ptr = run_ptr - size; + while ((*cmp) ((void *) run_ptr, (void *) tmp_ptr) < 0) + tmp_ptr -= size; + + tmp_ptr += size; + if (tmp_ptr != run_ptr) + { + char *trav; + + trav = run_ptr + size; + while (--trav >= run_ptr) + { + char c = *trav; + char *hi, *lo; + + for (hi = lo = trav; (lo -= size) >= tmp_ptr; hi = lo) + *hi = *lo; + *hi = c; + } + } + } + } +} +#endif diff --git a/runtime/GCCLibraries/libc/remove.c b/runtime/GCCLibraries/libc/remove.c new file mode 100644 index 0000000000..b7d2fa2985 --- /dev/null +++ b/runtime/GCCLibraries/libc/remove.c @@ -0,0 +1,51 @@ +//===-- remove.c - The remove function for the LLVM libc Library --*- C -*-===// +// +// This code is a modified form of the remove() function from the GNU C +// library. +// +// Modifications: +// 2005/11/28 - Added to LLVM tree. Functions renamed to allow compilation. +// Code to control symbol linkage types removed. +// +//===----------------------------------------------------------------------===// + +/* ANSI C `remove' function to delete a file or directory. POSIX.1 version. + Copyright (C) 1995,96,97,2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <errno.h> +#include <stdio.h> +#include <unistd.h> + +int +remove (const char * file) +{ + int save; + + save = errno; + if (rmdir (file) == 0) + return 0; + else if (errno == ENOTDIR && unlink (file) == 0) + { + errno = (save); + return 0; + } + + return -1; +} + diff --git a/runtime/GCCLibraries/libc/string.c b/runtime/GCCLibraries/libc/string.c new file mode 100644 index 0000000000..bd43b34100 --- /dev/null +++ b/runtime/GCCLibraries/libc/string.c @@ -0,0 +1,172 @@ +//===-- string.c - String functions for the LLVM libc Library -----*- C -*-===// +// +// A lot of this code is ripped gratuitously from glibc and libiberty. +// +//===----------------------------------------------------------------------===// + +#include <stdlib.h> +#include <string.h> + +#ifdef strlen +#undef strlen +#endif +size_t strlen(const char *Str) { + size_t Count = 0; + while (*Str) { ++Count; ++Str; } + return Count; +} + +#ifdef strdup +#undef strdup +#endif +char *strdup(const char *str) { + size_t Len = strlen(str); + char *Result = (char*)malloc((Len+1)*sizeof(char)); + memcpy(Result, str, Len+1); + return Result; +} + +#ifdef strndup +#undef strndup +#endif +char *strndup(const char *str, size_t n) { + size_t Len = strlen(str); + if (Len > n) Len = n; + char *Result = (char*)malloc((Len+1)*sizeof(char)); + memcpy(Result, str, Len); + Result[Len] = 0; + return Result; +} + +#ifdef strcpy +#undef strcpy +#endif +char *strcpy(char *s1, const char *s2) { + char *dest = s1; + while ((*s1++ = *s2++)); + return dest; +} + +#ifdef strncpy +#undef strncpy +#endif +char *strncpy(char *s1, const char *s2, size_t n) { + char *dest = s1; + while (n-- && (*s1++ = *s2++)); + return dest; +} + +#ifdef strcat +#undef strcat +#endif +char *strcat(char *s1, const char *s2) { + strcpy(s1+strlen(s1), s2); + return s1; +} + + +#ifdef strcmp +#undef strcmp +#endif +/* Compare S1 and S2, returning less than, equal to or + greater than zero if S1 is lexicographically less than, + equal to or greater than S2. */ +int strcmp (const char *p1, const char *p2) { + register const unsigned char *s1 = (const unsigned char *) p1; + register const unsigned char *s2 = (const unsigned char *) p2; + unsigned char c1, c2; + + do + { + c1 = (unsigned char) *s1++; + c2 = (unsigned char) *s2++; + if (c1 == '\0') + return c1 - c2; + } + while (c1 == c2); + + return c1 - c2; +} + +// http://sources.redhat.com/cgi-bin/cvsweb.cgi/libc/sysdeps/generic/?cvsroot=glibc +#if 0 +typedef unsigned int op_t; +#define OPSIZ 4 + +void *memset (void *dstpp, int c, size_t len) { + long long int dstp = (long long int) dstpp; + + if (len >= 8) + { + size_t xlen; + op_t cccc; + + cccc = (unsigned char) c; + cccc |= cccc << 8; + cccc |= cccc << 16; + if (OPSIZ > 4) + /* Do the shift in two steps to avoid warning if long has 32 bits. */ + cccc |= (cccc << 16) << 16; + + /* There are at least some bytes to set. + No need to test for LEN == 0 in this alignment loop. */ + while (dstp % OPSIZ != 0) + { + ((unsigned char *) dstp)[0] = c; + dstp += 1; + len -= 1; + } + + /* Write 8 `op_t' per iteration until less than 8 `op_t' remain. */ + xlen = len / (OPSIZ * 8); + while (xlen > 0) + { + ((op_t *) dstp)[0] = cccc; + ((op_t *) dstp)[1] = cccc; + ((op_t *) dstp)[2] = cccc; + ((op_t *) dstp)[3] = cccc; + ((op_t *) dstp)[4] = cccc; + ((op_t *) dstp)[5] = cccc; + ((op_t *) dstp)[6] = cccc; + ((op_t *) dstp)[7] = cccc; + dstp += 8 * OPSIZ; + xlen -= 1; + } + len %= OPSIZ * 8; + + /* Write 1 `op_t' per iteration until less than OPSIZ bytes remain. */ + xlen = len / OPSIZ; + while (xlen > 0) + { + ((op_t *) dstp)[0] = cccc; + dstp += OPSIZ; + xlen -= 1; + } + len %= OPSIZ; + } + + /* Write the last few bytes. */ + while (len > 0) + { + ((unsigned char *) dstp)[0] = c; + dstp += 1; + len -= 1; + } + + return dstpp; +} +#endif + +#ifdef memcpy +#undef memcpy +#endif +void *memcpy(void *dstpp, const void *srcpp, size_t len) { + char *dstp = (char*)dstpp; + char *srcp = (char*) srcpp; + unsigned i; + + for (i = 0; i < len; ++i) + dstp[i] = srcp[i]; + + return dstpp; +} diff --git a/runtime/GCCLibraries/libgcc/Makefile b/runtime/GCCLibraries/libgcc/Makefile new file mode 100644 index 0000000000..74b9c91f4b --- /dev/null +++ b/runtime/GCCLibraries/libgcc/Makefile @@ -0,0 +1,16 @@ +##===- runtime/GCCLibraries/libgcc/Makefile ----------------*- Makefile -*-===## +# +# The LLVM Compiler Infrastructure +# +# This file was developed by the LLVM research group and is distributed under +# the University of Illinois Open Source License. See LICENSE.TXT for details. +# +##===----------------------------------------------------------------------===## + +LEVEL = ../../.. +BYTECODE_LIBRARY = 1 +DONT_BUILD_RELINKED = 1 +LIBRARYNAME = gcc +BYTECODE_DESTINATION = $(CFERuntimeLibDir) + +include $(LEVEL)/Makefile.common diff --git a/runtime/GCCLibraries/libgcc/eprintf.c b/runtime/GCCLibraries/libgcc/eprintf.c new file mode 100644 index 0000000000..d4229fad92 --- /dev/null +++ b/runtime/GCCLibraries/libgcc/eprintf.c @@ -0,0 +1,13 @@ +#include <stdio.h> +void abort(void); + +/* This is used by the `assert' macro. */ +void +__eprintf (const char *string, const char *expression, + unsigned int line, const char *filename) +{ + fprintf (stderr, string, expression, line, filename); + fflush (stderr); + abort (); +} + diff --git a/runtime/GCCLibraries/libm/Makefile b/runtime/GCCLibraries/libm/Makefile new file mode 100644 index 0000000000..74ec12ef7f --- /dev/null +++ b/runtime/GCCLibraries/libm/Makefile @@ -0,0 +1,16 @@ +##===- runtime/GCCLibraries/libm/Makefile ------------------*- Makefile -*-===## +# +# The LLVM Compiler Infrastructure +# +# This file was developed by the LLVM research group and is distributed under +# the University of Illinois Open Source License. See LICENSE.TXT for details. +# +##===----------------------------------------------------------------------===## + +LEVEL = ../../.. +BYTECODE_LIBRARY = 1 +DONT_BUILD_RELINKED = 1 +LIBRARYNAME = m +BYTECODE_DESTINATION = $(CFERuntimeLibDir) + +include $(LEVEL)/Makefile.common diff --git a/runtime/GCCLibraries/libm/temp.c b/runtime/GCCLibraries/libm/temp.c new file mode 100644 index 0000000000..163971a14f --- /dev/null +++ b/runtime/GCCLibraries/libm/temp.c @@ -0,0 +1 @@ +typedef int INTEGER; diff --git a/runtime/Makefile b/runtime/Makefile new file mode 100644 index 0000000000..8d6f0ff596 --- /dev/null +++ b/runtime/Makefile @@ -0,0 +1,43 @@ +##===- runtime/Makefile ------------------------------------*- Makefile -*-===## +# +# The LLVM Compiler Infrastructure +# +# This file was developed by the LLVM research group and is distributed under +# the University of Illinois Open Source License. See LICENSE.TXT for details. +# +##===----------------------------------------------------------------------===## + +LEVEL = .. +include $(LEVEL)/Makefile.config + +ifeq ($(LLVMGCC_MAJVERS),4) +PARALLEL_DIRS := +install all:: + $(Echo) "Warning: These runtime libraries only need to be built with" + $(Echo) "Warning: llvm-gcc version 3. They are automatically included" + $(Echo) "Warning: with llvm-gcc version 4 and beyond" +else +ifneq ($(wildcard $(LLVMGCC)),) +PARALLEL_DIRS := GCCLibraries libdummy libprofile libtrace GC +else +PARALLEL_DIRS := +install all :: + @echo '********' Warning: Your LLVMGCCDIR is set incorrectly. Check + @echo '********' Warning: llvm/Makefile.config to make sure it matches + @echo '********' Warning: the directory where the C front-end is + @echo '********' Warning: installed,and re-run configure if it does not. +endif + +# Disable libprofile: a faulty libtool is generated by autoconf which breaks the +# build on Sparc +ifeq ($(ARCH), Sparc) +PARALLEL_DIRS := $(filter-out libprofile, $(PARALLEL_DIRS)) +endif +endif + +include $(LEVEL)/Makefile.common + +# Install target for libraries: Copy into $LLVMGCCDIR/bytecode-libs +# +install:: + diff --git a/runtime/README.txt b/runtime/README.txt new file mode 100644 index 0000000000..2e2e547de3 --- /dev/null +++ b/runtime/README.txt @@ -0,0 +1,4 @@ +This directory contains the various runtime libraries used by components of +the LLVM compiler. For example, the automatic pool allocation transformation +inserts calls to an external pool allocator library. This runtime library is +an example of the type of library that lives in these directories. diff --git a/runtime/libdummy/Makefile b/runtime/libdummy/Makefile new file mode 100644 index 0000000000..6dad7bc609 --- /dev/null +++ b/runtime/libdummy/Makefile @@ -0,0 +1,19 @@ +##===- runtime/libdummy/Makefile ---------------------------*- Makefile -*-===## +# +# The LLVM Compiler Infrastructure +# +# This file was developed by the LLVM research group and is distributed under +# the University of Illinois Open Source License. See LICENSE.TXT for details. +# +##===----------------------------------------------------------------------===## + +LEVEL = ../.. +BYTECODE_LIBRARY = 1 +DONT_BUILD_RELINKED = 1 +LIBRARYNAME = dummy +BYTECODE_DESTINATION = $(CFERuntimeLibDir) + +include $(LEVEL)/Makefile.common + +CompileCommonOpts := $(filter-out -pedantic,$(CompileCommonOpts)) +CompileCommonOpts := $(filter-out -Wno-long-long,$(CompileCommonOpts)) diff --git a/runtime/libdummy/README.txt b/runtime/libdummy/README.txt new file mode 100644 index 0000000000..08e77517f9 --- /dev/null +++ b/runtime/libdummy/README.txt @@ -0,0 +1,2 @@ +This directory contains stub routines which are occasionally useful when +performing alias analysis research. diff --git a/runtime/libdummy/dummylib.c b/runtime/libdummy/dummylib.c new file mode 100644 index 0000000000..aa104f8f8a --- /dev/null +++ b/runtime/libdummy/dummylib.c @@ -0,0 +1,144 @@ +#include <stdio.h> +#include <stdlib.h> +#include <time.h> +#include <stdarg.h> +#include <sys/time.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> + +#if 0 +int stat(const char *file_name, struct stat *buf) { return 0; } +int fstat(int filedes, struct stat *buf) { return 0; } +int lstat(const char *file_name, struct stat *buf) { return 0; } + +// Varargs function definitions +int ioctl(int d, int request, ...) {return 0; } +int printf(const char *X) {return 0; } +int sscanf(const char *X, const char *Y, ...) { return 0; } +int fprintf(FILE *stream, const char *format, ...) { return 0; } + + +int gettimeofday(struct timeval *tv, void *tz) { return 0; } +void *xmalloc(size_t X) { return malloc(X); } + +void srand(unsigned x) {} +double exp(double x) { return 0; } +double log(double x) { return 0; } +double sqrt(double x) { return 0; } +void exit(int x) {} +int puts(const char *x) { return 0; } +void __main() {} +int atoi(const char*x) { return 1; } +char *fgets(char*Ptr, int x, FILE*F) { return Ptr; } +char *gets(char *C) { return C; } +int fclose(FILE*F) { return 0; } +FILE *fopen(const char *n, const char*x) { return malloc(sizeof(FILE)); } +FILE *freopen(const char *path, const char *mode, FILE *stream) { return 0; } +int fflush(FILE *F) { return 0; } +size_t fwrite(const void* str, size_t N, size_t n, FILE *F) { return N; } +void *memset(void *P, int X, size_t N) { return P; } +void *memcpy(void *P, void *S, size_t N) { return P; } +void *memmove(void *P, void *S, size_t N) { return P; } +char *strcpy(char*Str1, const char *Str) { return Str1; } +char *strcat(char*Str1, const char *Str) { return Str1; } +size_t strlen(char *X) { return 0; } +#undef putchar +int putchar(int N) { return N; } +int putc(int c, FILE *stream) { return c; } +int fputc(int c, FILE *stream) { return c; } +int fgetc(FILE *S) { return 0; } +long ftell(FILE *F) { return 0; } +int getc(FILE *S) { return 0; } +size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream) { return 0; } +int fseek(FILE *stream, long offset, int whence) { return 0; } +int feof(FILE *stream) { return 0; } +int fputs(const char *s, char *stream) { return 0; } +int ferror(FILE *F) { return 0; } +FILE *fdopen(int fildes, const char *mode) { return 0;} +FILE *popen(const char *command, const char *type) { return 0; } +int pclose(FILE *stream) { return 0; } + +int ungetc(int c, FILE *stream) { return 0; } +int setvbuf(FILE *stream, char *buf, int mode , size_t size) { return 0; } +void rewind(FILE*F) { } +int fileno(FILE *stream) { return 1; } +char *ttyname(int desc) { return 0; } +long sysconf(int name) { return 0; } +char *tmpnam(char *s) { return s; } + +void *calloc(size_t A, size_t B) { return malloc(A*B); } +void *realloc(void *ptr, size_t N) { return ptr; } +const char *strerror(int N) { return 0; } +int unlink(const char *path) { return 0; } +void perror(const char *err) {} +char *strrchr(const char *S, int C) { return (char*)S; } +int memcmp(const char *A, const char *B, size_t N) { return 0; } +ssize_t read(int fildes, void *buf, size_t nbyte) { return nbyte; } +int close(int FD) { return 0; } +int rename(const char *oldpath, const char *newpath) { return 0; } +ssize_t write(int fd, const void *buf, size_t count) { return 0; } +pid_t getpid(void) { return 0; } +pid_t getppid(void) { return 0; } +void setbuf(FILE *stream, char *buf) {} +int isatty(int desc) { return 0; } +int vsprintf(char *str, const char *format, va_list ap) { return 0; } +char *getcwd(char *buf, size_t size) { return buf; } + +void qsort(void *base, size_t nmemb, size_t size, + int(*compar)(const void *, const void *)) { + compar(base, base); +} + + + +#include <sys/times.h> +clock_t times(struct tms *buf) { return 0; } + + +#include <setjmp.h> +int setjmp(jmp_buf env) { return 0; } +void longjmp(jmp_buf env, int val) {} +int kill(pid_t pid, int sig) { return 0; } +int system(const char *string) { return 0; } +char *getenv(const char *name) { return 0; } +typedef void (*sighandler_t)(int); + +sighandler_t signal(int signum, sighandler_t handler) { return handler; } + + + + +char *strchr(const char *s, int c) { return (char*)s; } +int strcmp(const char *s1, const char *s2) { return 0; } +int strncmp(const char *s1, const char *s2, size_t n) { return 0; } +char *strncpy(char *s1, const char *s2, size_t n) { return s1; } +char *strpbrk(const char *s, const char *accept) { return (char*)s; } +char *strncat(char *dest, const char *src, size_t n) { return dest; } + +double atof(const char *C) { return 0; } + + +long clock() { return 0; } +char *ctime(const time_t *timep) { return 0; } +time_t time(time_t *t) { return *t = 0; } + +double sin(double x) { return x; } +double cos(double x) { return x; } +double tan(double x) { return x; } +double asin(double x) { return x; } +double acos(double x) { return x; } +double atan(double x) { return x; } +double cosh(double x) { return x; } +double sinh(double x) { return x; } +double ceil(double x) { return x; } +double floor(double x) { return x; } + +double atan2(double x, double y) { return x; } +double fmod(double x, double y) { return x; } +double pow(double x, double y) { return x; } + +int tolower(int x) { return x; } +int toupper(int x) { return x; } + +#endif diff --git a/runtime/libprofile/BasicBlockTracing.c b/runtime/libprofile/BasicBlockTracing.c new file mode 100644 index 0000000000..e70dc05284 --- /dev/null +++ b/runtime/libprofile/BasicBlockTracing.c @@ -0,0 +1,67 @@ +/*===-- BasicBlockTracing.c - Support library for basic block tracing -----===*\ +|* +|* The LLVM Compiler Infrastructure +|* +|* This file was developed by the LLVM research group and is distributed under +|* the University of Illinois Open Source License. See LICENSE.TXT for details. +|* +|*===----------------------------------------------------------------------===*| +|* +|* This file implements the call back routines for the basic block tracing +|* instrumentation pass. This should be used with the -trace-basic-blocks +|* LLVM pass. +|* +\*===----------------------------------------------------------------------===*/ + +#include "Profiling.h" +#include <stdlib.h> +#include <stdio.h> + +static unsigned *ArrayStart, *ArrayEnd, *ArrayCursor; + +/* WriteAndFlushBBTraceData - write out the currently accumulated trace data + * and reset the cursor to point to the beginning of the buffer. + */ +static void WriteAndFlushBBTraceData () { + write_profiling_data(BBTraceInfo, ArrayStart, (ArrayCursor - ArrayStart)); + ArrayCursor = ArrayStart; +} + +/* BBTraceAtExitHandler - When the program exits, just write out any remaining + * data and free the trace buffer. + */ +static void BBTraceAtExitHandler() { + WriteAndFlushBBTraceData (); + free (ArrayStart); +} + +/* llvm_trace_basic_block - called upon hitting a new basic block. */ +void llvm_trace_basic_block (unsigned BBNum) { + *ArrayCursor++ = BBNum; + if (ArrayCursor == ArrayEnd) + WriteAndFlushBBTraceData (); +} + +/* llvm_start_basic_block_tracing - This is the main entry point of the basic + * block tracing library. It is responsible for setting up the atexit + * handler and allocating the trace buffer. + */ +int llvm_start_basic_block_tracing(int argc, const char **argv, + unsigned *arrayStart, unsigned numElements) { + int Ret; + const unsigned BufferSize = 128 * 1024; + unsigned ArraySize; + + Ret = save_arguments(argc, argv); + + /* Allocate a buffer to contain BB tracing data */ + ArraySize = BufferSize / sizeof (unsigned); + ArrayStart = malloc (ArraySize * sizeof (unsigned)); + ArrayEnd = ArrayStart + ArraySize; + ArrayCursor = ArrayStart; + + /* Set up the atexit handler. */ + atexit (BBTraceAtExitHandler); + + return Ret; +} diff --git a/runtime/libprofile/BlockProfiling.c b/runtime/libprofile/BlockProfiling.c new file mode 100644 index 0000000000..2b1b011617 --- /dev/null +++ b/runtime/libprofile/BlockProfiling.c @@ -0,0 +1,45 @@ +/*===-- BlockProfiling.c - Support library for block profiling ------------===*\ +|* +|* The LLVM Compiler Infrastructure +|* +|* This file was developed by the LLVM research group and is distributed under +|* the University of Illinois Open Source License. See LICENSE.TXT for details. +|* +|*===----------------------------------------------------------------------===*| +|* +|* This file implements the call back routines for the block profiling +|* instrumentation pass. This should be used with the -insert-block-profiling +|* LLVM pass. +|* +\*===----------------------------------------------------------------------===*/ + +#include "Profiling.h" +#include <stdlib.h> + +static unsigned *ArrayStart; +static unsigned NumElements; + +/* BlockProfAtExitHandler - When the program exits, just write out the profiling + * data. + */ +static void BlockProfAtExitHandler() { + /* Note that if this were doing something more intelligent with the + * instrumentation, we could do some computation here to expand what we + * collected into simple block profiles. (Or we could do it in llvm-prof.) + * Regardless, we directly count each block, so no expansion is necessary. + */ + write_profiling_data(BlockInfo, ArrayStart, NumElements); +} + + +/* llvm_start_block_profiling - This is the main entry point of the block + * profiling library. It is responsible for setting up the atexit handler. + */ +int llvm_start_block_profiling(int argc, const char **argv, + unsigned *arrayStart, unsigned numElements) { + int Ret = save_arguments(argc, argv); + ArrayStart = arrayStart; + NumElements = numElements; + atexit(BlockProfAtExitHandler); + return Ret; +} diff --git a/runtime/libprofile/CommonProfiling.c b/runtime/libprofile/CommonProfiling.c new file mode 100644 index 0000000000..f37b018d9f --- /dev/null +++ b/runtime/libprofile/CommonProfiling.c @@ -0,0 +1,117 @@ +/*===-- CommonProfiling.c - Profiling support library support -------------===*\ +|* +|* The LLVM Compiler Infrastructure +|* +|* This file was developed by the LLVM research group and is distributed under +|* the University of Illinois Open Source License. See LICENSE.TXT for details. +|* +|*===----------------------------------------------------------------------===*| +|* +|* This file implements functions used by the various different types of +|* profiling implementations. +|* +\*===----------------------------------------------------------------------===*/ + +#include "Profiling.h" +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <stdlib.h> + +static char *SavedArgs = 0; +static unsigned SavedArgsLength = 0; + +static const char *OutputFilename = "llvmprof.out"; + +/* save_arguments - Save argc and argv as passed into the program for the file + * we output. + */ +int save_arguments(int argc, const char **argv) { + unsigned Length, i; + if (SavedArgs || !argv) return argc; /* This can be called multiple times */ + + /* Check to see if there are any arguments passed into the program for the + * profiler. If there are, strip them off and remember their settings. + */ + while (argc > 1 && !strncmp(argv[1], "-llvmprof-", 10)) { + /* Ok, we have an llvmprof argument. Remove it from the arg list and decide + * what to do with it. + */ + const char *Arg = argv[1]; + memmove(&argv[1], &argv[2], (argc-1)*sizeof(char*)); + --argc; + + if (!strcmp(Arg, "-llvmprof-output")) { + if (argc == 1) + puts("-llvmprof-output requires a filename argument!"); + else { + OutputFilename = strdup(argv[1]); + memmove(&argv[1], &argv[2], (argc-1)*sizeof(char*)); + --argc; + } + } else { + printf("Unknown option to the profiler runtime: '%s' - ignored.\n", Arg); + } + } + + for (Length = 0, i = 0; i != (unsigned)argc; ++i) + Length += strlen(argv[i])+1; + + SavedArgs = (char*)malloc(Length); + for (Length = 0, i = 0; i != (unsigned)argc; ++i) { + unsigned Len = strlen(argv[i]); + memcpy(SavedArgs+Length, argv[i], Len); + Length += Len; + SavedArgs[Length++] = ' '; + } + + SavedArgsLength = Length; + + return argc; +} + + +/* write_profiling_data - Write a raw block of profiling counters out to the + * llvmprof.out file. Note that we allow programs to be instrumented with + * multiple different kinds of instrumentation. For this reason, this function + * may be called more than once. + */ +void write_profiling_data(enum ProfilingType PT, unsigned *Start, + unsigned NumElements) { + static int OutFile = -1; + int PTy; + + /* If this is the first time this function is called, open the output file for + * appending, creating it if it does not already exist. + */ + if (OutFile == -1) { + OutFile = open(OutputFilename, O_CREAT | O_WRONLY | O_APPEND, 0666); + if (OutFile == -1) { + fprintf(stderr, "LLVM profiling runtime: while opening '%s': ", + OutputFilename); + perror(""); + return; + } + + /* Output the command line arguments to the file. */ + { + int PTy = ArgumentInfo; + int Zeros = 0; + write(OutFile, &PTy, sizeof(int)); + write(OutFile, &SavedArgsLength, sizeof(unsigned)); + write(OutFile, SavedArgs, SavedArgsLength); + /* Pad out to a multiple of four bytes */ + if (SavedArgsLength & 3) + write(OutFile, &Zeros, 4-(SavedArgsLength&3)); + } + } + + /* Write out this record! */ + PTy = PT; + write(OutFile, &PTy, sizeof(int)); + write(OutFile, &NumElements, sizeof(unsigned)); + write(OutFile, Start, NumElements*sizeof(unsigned)); +} diff --git a/runtime/libprofile/EdgeProfiling.c b/runtime/libprofile/EdgeProfiling.c new file mode 100644 index 0000000000..cf717664f3 --- /dev/null +++ b/runtime/libprofile/EdgeProfiling.c @@ -0,0 +1,45 @@ +/*===-- EdgeProfiling.c - Support library for edge profiling --------------===*\ +|* +|* The LLVM Compiler Infrastructure +|* +|* This file was developed by the LLVM research group and is distributed under +|* the University of Illinois Open Source License. See LICENSE.TXT for details. +|* +|*===----------------------------------------------------------------------===*| +|* +|* This file implements the call back routines for the edge profiling +|* instrumentation pass. This should be used with the -insert-edge-profiling +|* LLVM pass. +|* +\*===----------------------------------------------------------------------===*/ + +#include "Profiling.h" +#include <stdlib.h> + +static unsigned *ArrayStart; +static unsigned NumElements; + +/* EdgeProfAtExitHandler - When the program exits, just write out the profiling + * data. + */ +static void EdgeProfAtExitHandler() { + /* Note that if this were doing something more intelligent with the + * instrumentation, we could do some computation here to expand what we + * collected into simple edge profiles. Since we directly count each edge, we + * just write out all of the counters directly. + */ + write_profiling_data(EdgeInfo, ArrayStart, NumElements); +} + + +/* llvm_start_edge_profiling - This is the main entry point of the edge + * profiling library. It is responsible for setting up the atexit handler. + */ +int llvm_start_edge_profiling(int argc, const char **argv, + unsigned *arrayStart, unsigned numElements) { + int Ret = save_arguments(argc, argv); + ArrayStart = arrayStart; + NumElements = numElements; + atexit(EdgeProfAtExitHandler); + return Ret; +} diff --git a/runtime/libprofile/FunctionProfiling.c b/runtime/libprofile/FunctionProfiling.c new file mode 100644 index 0000000000..d030053094 --- /dev/null +++ b/runtime/libprofile/FunctionProfiling.c @@ -0,0 +1,42 @@ +/*===-- FunctionProfiling.c - Support library for function profiling ------===*\ +|* +|* The LLVM Compiler Infrastructure +|* +|* This file was developed by the LLVM research group and is distributed under +|* the University of Illinois Open Source License. See LICENSE.TXT for details. +|* +|*===----------------------------------------------------------------------===*| +|* +|* This file implements the call back routines for the function profiling +|* instrumentation pass. This should be used with the +|* -insert-function-profiling LLVM pass. +|* +\*===----------------------------------------------------------------------===*/ + +#include "Profiling.h" +#include <stdlib.h> + +static unsigned *ArrayStart; +static unsigned NumElements; + +/* FuncProfAtExitHandler - When the program exits, just write out the profiling + * data. + */ +static void FuncProfAtExitHandler() { + /* Just write out the data we collected. + */ + write_profiling_data(FunctionInfo, ArrayStart, NumElements); +} + + +/* llvm_start_func_profiling - This is the main entry point of the function + * profiling library. It is responsible for setting up the atexit handler. + */ +int llvm_start_func_profiling(int argc, const char **argv, + unsigned *arrayStart, unsigned numElements) { + int Ret = save_arguments(argc, argv); + ArrayStart = arrayStart; + NumElements = numElements; + atexit(FuncProfAtExitHandler); + return Ret; +} diff --git a/runtime/libprofile/Makefile b/runtime/libprofile/Makefile new file mode 100644 index 0000000000..e88fcdc34e --- /dev/null +++ b/runtime/libprofile/Makefile @@ -0,0 +1,19 @@ +##===- runtime/libprofile/Makefile -------------------------*- Makefile -*-===## +# +# The LLVM Compiler Infrastructure +# +# This file was developed by the LLVM research group and is distributed under +# the University of Illinois Open Source License. See LICENSE.TXT for details. +# +##===----------------------------------------------------------------------===## + +LEVEL = ../.. +BYTECODE_LIBRARY = 1 +SHARED_LIBRARY = 1 +LOADABLE_MODULE = 1 +LIBRARYNAME = profile_rt +EXTRA_DIST = exported_symbols.lst +EXPORTED_SYMBOL_FILE = $(PROJ_SRC_DIR)/exported_symbols.lst +BYTECODE_DESTINATION = $(CFERuntimeLibDir) + +include $(LEVEL)/Makefile.common diff --git a/runtime/libprofile/Profiling.h b/runtime/libprofile/Profiling.h new file mode 100644 index 0000000000..2c404899c8 --- /dev/null +++ b/runtime/libprofile/Profiling.h @@ -0,0 +1,31 @@ +/*===-- Profiling.h - Profiling support library support routines --*- C -*-===*\ +|* +|* The LLVM Compiler Infrastructure +|* +|* This file was developed by the LLVM research group and is distributed under +|* the University of Illinois Open Source License. See LICENSE.TXT for details. +|* +|*===----------------------------------------------------------------------===*| +|* +|* This file defines functions shared by the various different profiling +|* implementations. +|* +\*===----------------------------------------------------------------------===*/ + +#ifndef PROFILING_H +#define PROFILING_H + +#include "llvm/Analysis/ProfileInfoTypes.h" /* for enum ProfilingType */ + +/* save_arguments - Save argc and argv as passed into the program for the file + * we output. + */ +int save_arguments(int argc, const char **argv); + +/* write_profiling_data - Write out a typed packet of profiling data to the + * current output file. + */ +void write_profiling_data(enum ProfilingType PT, unsigned *Start, + unsigned NumElements); + +#endif diff --git a/runtime/libprofile/exported_symbols.lst b/runtime/libprofile/exported_symbols.lst new file mode 100644 index 0000000000..6f6c3cc840 --- /dev/null +++ b/runtime/libprofile/exported_symbols.lst @@ -0,0 +1,5 @@ + +llvm_start_func_profiling +llvm_start_block_profiling +llvm_start_basic_block_tracing +llvm_trace_basic_block diff --git a/runtime/libtrace/Makefile b/runtime/libtrace/Makefile new file mode 100644 index 0000000000..9a07070374 --- /dev/null +++ b/runtime/libtrace/Makefile @@ -0,0 +1,18 @@ +##===- runtime/libtrace/Makefile ---------------------------*- Makefile -*-===## +# +# The LLVM Compiler Infrastructure +# +# This file was developed by the LLVM research group and is distributed under +# the University of Illinois Open Source License. See LICENSE.TXT for details. +# +##===----------------------------------------------------------------------===## + +LEVEL = ../.. +BYTECODE_LIBRARY = 1 +LIBRARYNAME = trace +BYTECODE_DESTINATION = $(CFERuntimeLibDir) + +include $(LEVEL)/Makefile.common + +CompileCommonOpts := $(filter-out -pedantic,$(CompileCommonOpts)) +CompileCommonOpts := $(filter-out -Wno-long-long,$(CompileCommonOpts)) diff --git a/runtime/libtrace/README.txt b/runtime/libtrace/README.txt new file mode 100644 index 0000000000..80fee9bdbd --- /dev/null +++ b/runtime/libtrace/README.txt @@ -0,0 +1,2 @@ +These routines form the support library for the LLVM -trace and -tracem +instrumentation passes. diff --git a/runtime/libtrace/tracelib.c b/runtime/libtrace/tracelib.c new file mode 100644 index 0000000000..be726f1462 --- /dev/null +++ b/runtime/libtrace/tracelib.c @@ -0,0 +1,392 @@ +/*===-- tracelib.c - Runtime routines for tracing ---------------*- C++ -*-===* + * + * Runtime routines for supporting tracing of execution for code generated by + * LLVM. + * + *===----------------------------------------------------------------------===*/ + +#include "tracelib.h" +#include <assert.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include "llvm/Support/DataTypes.h" + +/*===---------------------------------------------------------------------===== + * HASH FUNCTIONS + *===---------------------------------------------------------------------===*/ + +/* use #defines until we have inlining */ +typedef uintptr_t Index; /* type of keys, size for hash table */ +typedef uint32_t Generic; /* type of values stored in table */ + +/* Index IntegerHashFunc(const Generic value, const Index size) */ +#define IntegerHashFunc(value, size) \ + ( ((((Index) value) << 3) ^ (((Index) value) >> 3)) % size ) + +/* Index IntegerRehashFunc(const Generic oldHashValue, const Index size) */ +#define IntegerRehashFunc(oldHashValue, size) \ + ((Index) ((oldHashValue+16) % size)) /* 16 is relatively prime to a Mersenne prime! */ + +/* Index PointerHashFunc(const void* value, const Index size) */ +#define PointerHashFunc(value, size) \ + IntegerHashFunc((Index) value, size) + +/* Index PointerRehashFunc(const void* value, const Index size) */ +#define PointerRehashFunc(value, size) \ + IntegerRehashFunc((Index) value, size) + +/*===---------------------------------------------------------------------===== + * POINTER-TO-GENERIC HASH TABLE. + * These should be moved to a separate location: HashTable.[ch] + *===---------------------------------------------------------------------===*/ + +typedef enum { FIND, ENTER } ACTION; +typedef char FULLEMPTY; +const FULLEMPTY EMPTY = '\0'; +const FULLEMPTY FULL = '\1'; + +// List of primes closest to powers of 2 in [2^20 -- 2^30], obtained from +// http://www.utm.edu/research/primes/lists/2small/0bit.html. +// Use these as the successive sizes of the hash table. +#define NUMPRIMES 11 +#define FIRSTENTRY 2 +const unsigned PRIMES[NUMPRIMES] = { (1<<20)-3, (1<<21)-9, (1<<22)-3, (1<<23)-15, + (1<<24)-3, (1<<25)-39, (1<<26)-5, (1<<27)-39, + (1<<28)-57, (1<<29)-3, (1<<30)-35 }; +unsigned CurrentSizeEntry = FIRSTENTRY; + +const unsigned MAX_NUM_PROBES = 4; + +typedef struct PtrValueHashEntry_struct { + void* key; + Generic value; +} PtrValueHashEntry; + +typedef struct PtrValueHashTable_struct { + PtrValueHashEntry* table; + FULLEMPTY* fullEmptyFlags; + Index capacity; + Index size; +} PtrValueHashTable; + + +static Generic LookupOrInsertPtr(PtrValueHashTable* ptrTable, void* ptr, + ACTION action, Generic value); + +static void Insert(PtrValueHashTable* ptrTable, void* ptr, Generic value); + +static void Delete(PtrValueHashTable* ptrTable, void* ptr); + +/* Returns 0 if the item is not found. */ +/* void* LookupPtr(PtrValueHashTable* ptrTable, void* ptr) */ +#define LookupPtr(ptrTable, ptr) \ + LookupOrInsertPtr(ptrTable, ptr, FIND, (Generic) 0) + +void +InitializeTable(PtrValueHashTable* ptrTable, Index newSize) +{ + ptrTable->table = (PtrValueHashEntry*) calloc(newSize, + sizeof(PtrValueHashEntry)); + ptrTable->fullEmptyFlags = (FULLEMPTY*) calloc(newSize, sizeof(FULLEMPTY)); + ptrTable->capacity = newSize; + ptrTable->size = 0; +} + +PtrValueHashTable* +CreateTable(Index initialSize) +{ + PtrValueHashTable* ptrTable = + (PtrValueHashTable*) malloc(sizeof(PtrValueHashTable)); + InitializeTable(ptrTable, initialSize); + return ptrTable; +} + +void +ReallocTable(PtrValueHashTable* ptrTable, Index newSize) +{ + if (newSize <= ptrTable->capacity) + return; + +#ifndef NDEBUG + printf("\n***\n*** REALLOCATING SPACE FOR POINTER HASH TABLE.\n"); + printf("*** oldSize = %ld, oldCapacity = %ld\n***\n\n", + (long) ptrTable->size, (long) ptrTable->capacity); +#endif + + unsigned int i; + PtrValueHashEntry* oldTable = ptrTable->table; + FULLEMPTY* oldFlags = ptrTable->fullEmptyFlags; + Index oldSize = ptrTable->size; + Index oldCapacity = ptrTable->capacity; + + /* allocate the new storage and flags and re-insert the old entries */ + InitializeTable(ptrTable, newSize); + for (i=0; i < oldCapacity; ++i) + if (oldFlags[i] == FULL) + Insert(ptrTable, oldTable[i].key, oldTable[i].value); + + assert(ptrTable->size == oldSize && "Incorrect number of entries copied?"); + +#ifndef NDEBUG + for (i=0; i < oldCapacity; ++i) + if (oldFlags[i] == FULL) + assert(LookupPtr(ptrTable, oldTable[i].key) == oldTable[i].value); +#endif + + free(oldTable); + free(oldFlags); +} + +void +DeleteTable(PtrValueHashTable* ptrTable) +{ + free(ptrTable->table); + free(ptrTable->fullEmptyFlags); + memset(ptrTable, '\0', sizeof(PtrValueHashTable)); + free(ptrTable); +} + +void +InsertAtIndex(PtrValueHashTable* ptrTable, void* ptr, Generic value, Index index) +{ + assert(ptrTable->fullEmptyFlags[index] == EMPTY && "Slot is in use!"); + ptrTable->table[index].key = ptr; + ptrTable->table[index].value = value; + ptrTable->fullEmptyFlags[index] = FULL; + ptrTable->size++; +} + +void +DeleteAtIndex(PtrValueHashTable* ptrTable, Index index) +{ + assert(ptrTable->fullEmptyFlags[index] == FULL && "Deleting empty slot!"); + ptrTable->table[index].key = 0; + ptrTable->table[index].value = (Generic) 0; + ptrTable->fullEmptyFlags[index] = EMPTY; + ptrTable->size--; +} + +Index +FindIndex(PtrValueHashTable* ptrTable, void* ptr) +{ + unsigned numProbes = 1; + Index index = PointerHashFunc(ptr, ptrTable->capacity); + if (ptrTable->fullEmptyFlags[index] == FULL) + { + if (ptrTable->table[index].key == ptr) + return index; + + /* First lookup failed on non-empty slot: probe further */ + while (numProbes < MAX_NUM_PROBES) + { + index = PointerRehashFunc(index, ptrTable->capacity); + if (ptrTable->fullEmptyFlags[index] == EMPTY) + break; + else if (ptrTable->table[index].key == ptr) + return index; + ++numProbes; + } + } + + /* Lookup failed: item is not in the table. */ + /* If last slot is empty, use that slot. */ + /* Otherwise, table must have been reallocated, so search again. */ + + if (numProbes == MAX_NUM_PROBES) + { /* table is too full: reallocate and search again */ + if (CurrentSizeEntry >= NUMPRIMES-1) { + fprintf(stderr, "Out of PRIME Numbers!!!"); + abort(); + } + ReallocTable(ptrTable, PRIMES[++CurrentSizeEntry]); + return FindIndex(ptrTable, ptr); + } + else + { + assert(ptrTable->fullEmptyFlags[index] == EMPTY && + "Stopped before finding an empty slot and before MAX probes!"); + return index; + } +} + +/* Look up hash table using 'ptr' as the key. If an entry exists, return + * the value mapped to 'ptr'. If not, and if action==ENTER is specified, + * create a new entry with value 'value', but return 0 in any case. + */ +Generic +LookupOrInsertPtr(PtrValueHashTable* ptrTable, void* ptr, ACTION action, + Generic value) +{ + Index index = FindIndex(ptrTable, ptr); + if (ptrTable->fullEmptyFlags[index] == FULL && + ptrTable->table[index].key == ptr) + return ptrTable->table[index].value; + + /* Lookup failed: item is not in the table */ + /* If action is ENTER, insert item into the table. Return 0 in any case. */ + if (action == ENTER) + InsertAtIndex(ptrTable, ptr, value, index); + + return (Generic) 0; +} + +void +Insert(PtrValueHashTable* ptrTable, void* ptr, Generic value) +{ + Index index = FindIndex(ptrTable, ptr); + assert(ptrTable->fullEmptyFlags[index] == EMPTY && + "ptr is already in the table: delete it first!"); + InsertAtIndex(ptrTable, ptr, value, index); +} + +void +Delete(PtrValueHashTable* ptrTable, void* ptr) +{ + Index index = FindIndex(ptrTable, ptr); + if (ptrTable->fullEmptyFlags[index] == FULL && + ptrTable->table[index].key == ptr) + { + DeleteAtIndex(ptrTable, index); + } +} + +/*===---------------------------------------------------------------------===== + * RUNTIME ROUTINES TO MAP POINTERS TO SEQUENCE NUMBERS + *===---------------------------------------------------------------------===*/ + +PtrValueHashTable* SequenceNumberTable = NULL; +#define INITIAL_SIZE (PRIMES[FIRSTENTRY]) + +#define MAX_NUM_SAVED 1024 + +typedef struct PointerSet_struct { + char* savedPointers[MAX_NUM_SAVED]; /* 1024 alloca'd ptrs shd suffice */ + unsigned int numSaved; + struct PointerSet_struct* nextOnStack; /* implement a cheap stack */ +} PointerSet; + +PointerSet* topOfStack = NULL; + +SequenceNumber +HashPointerToSeqNum(char* ptr) +{ + static SequenceNumber count = 0; + SequenceNumber seqnum; + if (SequenceNumberTable == NULL) { + assert(MAX_NUM_PROBES < INITIAL_SIZE+1 && "Initial size too small"); + SequenceNumberTable = CreateTable(INITIAL_SIZE); + } + seqnum = (SequenceNumber) + LookupOrInsertPtr(SequenceNumberTable, ptr, ENTER, count+1); + + if (seqnum == 0) /* new entry was created with value count+1 */ + seqnum = ++count; /* so increment counter */ + + assert(seqnum <= count && "Invalid sequence number in table!"); + return seqnum; +} + +void +ReleasePointerSeqNum(char* ptr) +{ /* if a sequence number was assigned to this ptr, release it */ + if (SequenceNumberTable != NULL) + Delete(SequenceNumberTable, ptr); +} + +void +PushPointerSet() +{ + PointerSet* newSet = (PointerSet*) malloc(sizeof(PointerSet)); + newSet->numSaved = 0; + newSet->nextOnStack = topOfStack; + topOfStack = newSet; +} + +void +PopPointerSet() +{ + PointerSet* oldSet; + assert(topOfStack != NULL && "popping from empty stack!"); + oldSet = topOfStack; + topOfStack = oldSet->nextOnStack; + assert(oldSet->numSaved == 0); + free(oldSet); +} + +/* free the pointers! */ +static void +ReleaseRecordedPointers(char* savedPointers[MAX_NUM_SAVED], + unsigned int numSaved) +{ + unsigned int i; + for (i=0; i < topOfStack->numSaved; ++i) + ReleasePointerSeqNum(topOfStack->savedPointers[i]); +} + +void +ReleasePointersPopSet() +{ + ReleaseRecordedPointers(topOfStack->savedPointers, topOfStack->numSaved); + topOfStack->numSaved = 0; + PopPointerSet(); +} + +void +RecordPointer(char* ptr) +{ /* record pointers for release later */ + if (topOfStack->numSaved == MAX_NUM_SAVED) { + printf("***\n*** WARNING: OUT OF ROOM FOR SAVED POINTERS." + " ALL POINTERS ARE BEING FREED.\n" + "*** THE SEQUENCE NUMBERS OF SAVED POINTERS WILL CHANGE!\n*** \n"); + ReleaseRecordedPointers(topOfStack->savedPointers, topOfStack->numSaved); + topOfStack->numSaved = 0; + } + topOfStack->savedPointers[topOfStack->numSaved++] = ptr; +} + +/*===---------------------------------------------------------------------===== + * TEST DRIVER FOR INSTRUMENTATION LIBRARY + *===---------------------------------------------------------------------===*/ + +#ifndef TEST_INSTRLIB +#undef TEST_INSTRLIB /* #define this to turn on by default */ +#endif + +#ifdef TEST_INSTRLIB +int +main(int argc, char** argv) +{ + int i, j; + int doRelease = 0; + + INITIAL_SIZE = 5; /* start with small table to test realloc's*/ + + if (argc > 1 && ! strcmp(argv[1], "-r")) + { + PushPointerSet(); + doRelease = 1; + } + + for (i=0; i < argc; ++i) + for (j=0; argv[i][j]; ++j) + { + printf("Sequence number for argc[%d][%d] (%c) = Hash(%p) = %d\n", + i, j, argv[i][j], argv[i]+j, HashPointerToSeqNum(argv[i]+j)); + + if (doRelease) + RecordPointer(argv[i]+j); + } + + if (doRelease) + ReleasePointersPopSet(); + + /* print sequence numbers out again to compare with (-r) and w/o release */ + for (i=argc-1; i >= 0; --i) + for (j=0; argv[i][j]; ++j) + printf("Sequence number for argc[%d][%d] (%c) = %d\n", + i, j, argv[i][j], argv[i]+j, HashPointerToSeqNum(argv[i]+j)); + + return 0; +} +#endif diff --git a/runtime/libtrace/tracelib.h b/runtime/libtrace/tracelib.h new file mode 100644 index 0000000000..a60697a897 --- /dev/null +++ b/runtime/libtrace/tracelib.h @@ -0,0 +1,40 @@ +/*===-- Libraries/tracelib.h - Runtime routines for tracing -----*- C++ -*--=== + * + * Runtime routines for supporting tracing of execution + * for code generated by LLVM. + * + *===---------------------------------------------------------------------===*/ + +#ifndef _TEST_LIBRARIES_LIBINSTR_TRACELIB_ +#define _TEST_LIBRARIES_LIBINSTR_TRACELIB_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <sys/types.h> + +/*===---------------------------------------------------------------------===== + * Support for tracing pointers + *===---------------------------------------------------------------------===*/ + +typedef unsigned int SequenceNumber; + +extern SequenceNumber HashPointerToSeqNum( char* ptr); + +extern void ReleasePointerSeqNum(char* ptr); + +extern void RecordPointer(char* ptr); + +extern void PushPointerSet(); + +extern void ReleasePointersPopSet(); + + +#ifdef __cplusplus +} +#endif + +/*===---------------------------------------------------------------------===*/ + +#endif |