Vendor import of llvm release_30 branch r142614:

http://llvm.org/svn/llvm-project/llvm/branches/release_30@142614
This commit is contained in:
Dimitry Andric 2011-10-20 21:10:27 +00:00
parent 411bd29eea
commit 30815c536b
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/vendor/llvm/dist/; revision=226584
svn path=/vendor/llvm/llvm-r142614/; revision=226585; tag=vendor/llvm/llvm-r142614
2755 changed files with 213827 additions and 82031 deletions

1
.gitignore vendored
View File

@ -22,6 +22,7 @@
# Explicit files to ignore (only matches one).
#==============================================================================#
.gitusers
autom4te.cache
cscope.files
cscope.out
autoconf/aclocal.m4

View File

@ -82,7 +82,7 @@ set(LLVM_ALL_TARGETS
)
# List of targets with JIT support:
set(LLVM_TARGETS_WITH_JIT X86 PowerPC ARM)
set(LLVM_TARGETS_WITH_JIT X86 PowerPC ARM Mips)
if( MSVC )
set(LLVM_TARGETS_TO_BUILD X86
@ -181,12 +181,16 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON)
include_directories( ${LLVM_BINARY_DIR}/include ${LLVM_MAIN_INCLUDE_DIR})
if( ${CMAKE_SYSTEM_NAME} MATCHES SunOS )
SET(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} "-include llvm/Support/Solaris.h")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -include llvm/Support/Solaris.h")
endif( ${CMAKE_SYSTEM_NAME} MATCHES SunOS )
include(AddLLVM)
include(TableGen)
macro(llvm_tablegen)
tablegen(LLVM ${ARGN})
endmacro()
if( MINGW )
# People report that -O3 is unreliable on MinGW. The traditional
# build also uses -O2 for that reason:
@ -195,19 +199,10 @@ endif()
# Put this before tblgen. Else we have a circular dependence.
add_subdirectory(lib/Support)
set(LLVM_TABLEGEN "tblgen" CACHE
STRING "Native TableGen executable. Saves building one when cross-compiling.")
# Effective tblgen executable to be used:
set(LLVM_TABLEGEN_EXE ${LLVM_TABLEGEN})
add_subdirectory(lib/TableGen)
add_subdirectory(utils/TableGen)
if( CMAKE_CROSSCOMPILING )
# This adds a dependency on target `tblgen', so must go after utils/TableGen
include( CrossCompileLLVM )
endif( CMAKE_CROSSCOMPILING )
add_subdirectory(include/llvm)
add_subdirectory(lib)

View File

@ -32,6 +32,10 @@ E: dberlin@dberlin.org
D: ET-Forest implementation.
D: Sparse bitmap
N: David Blaikie
E: dblaikie@gmail.com
D: General bug fixing/fit & finish, mostly in Clang
N: Neil Booth
E: neil@daikokuya.co.uk
D: APFloat implementation.
@ -241,6 +245,10 @@ E: duraid@octopus.com.au
W: http://kinoko.c.u-tokyo.ac.jp/~duraid/
D: IA64 backend, BigBlock register allocator
N: John McCall
E: rjmccall@apple.com
D: Clang semantic analysis and IR generation
N: Michael McCracken
E: michael.mccracken@gmail.com
D: Line number support for llvmgcc
@ -274,6 +282,8 @@ N: Jakob Stoklund Olesen
E: stoklund@2pi.dk
D: Machine code verifier
D: Blackfin backend
D: Fast register allocator
D: Greedy register allocator
N: Richard Osborne
E: richard@xmos.com

View File

@ -10,7 +10,7 @@
LEVEL := .
# Top-Level LLVM Build Stages:
# 1. Build lib/Support, which is used by utils (tblgen).
# 1. Build lib/Support and lib/TableGen, which are used by utils (tblgen).
# 2. Build utils, which is used by VMCore.
# 3. Build VMCore, which builds the Intrinsics.inc file used by libs.
# 4. Build libs, which are needed by llvm-config.
@ -27,10 +27,10 @@ LEVEL := .
ifneq ($(findstring llvmCore, $(RC_ProjectName)),llvmCore) # Normal build (not "Apple-style").
ifeq ($(BUILD_DIRS_ONLY),1)
DIRS := lib/Support utils
OPTIONAL_DIRS :=
DIRS := lib/Support lib/TableGen utils
OPTIONAL_DIRS := tools/clang/utils/TableGen
else
DIRS := lib/Support utils lib/VMCore lib tools/llvm-shlib \
DIRS := lib/Support lib/TableGen utils lib/VMCore lib tools/llvm-shlib \
tools/llvm-config tools runtime docs unittests
OPTIONAL_DIRS := projects bindings
endif
@ -118,7 +118,8 @@ cross-compile-build-tools:
unset CFLAGS ; \
unset CXXFLAGS ; \
$(PROJ_SRC_DIR)/configure --build=$(BUILD_TRIPLE) \
--host=$(BUILD_TRIPLE) --target=$(BUILD_TRIPLE); \
--host=$(BUILD_TRIPLE) --target=$(BUILD_TRIPLE) \
--disable-polly ; \
cd .. ; \
fi; \
(unset SDKROOT; \
@ -187,8 +188,7 @@ FilesToConfig := \
include/llvm/Config/AsmPrinters.def \
include/llvm/Config/AsmParsers.def \
include/llvm/Config/Disassemblers.def \
include/llvm/Support/DataTypes.h \
tools/llvmc/src/Base.td
include/llvm/Support/DataTypes.h
FilesToConfigPATH := $(addprefix $(LLVM_OBJ_ROOT)/,$(FilesToConfig))
all-local:: $(FilesToConfigPATH)

View File

@ -188,30 +188,6 @@ LIBS := @LIBS@
# Targets that we should build
TARGETS_TO_BUILD=@TARGETS_TO_BUILD@
# Path to location for LLVM C/C++ front-end. You can modify this if you
# want to override the value set by configure.
LLVMGCCDIR := @LLVMGCCDIR@
# Full pathnames of LLVM C/C++ front-end 'cc1' and 'cc1plus' binaries:
LLVMGCC := @LLVMGCC@
LLVMGXX := @LLVMGXX@
LLVMCC1 := @LLVMCC1@
LLVMCC1PLUS := @LLVMCC1PLUS@
LLVMGCC_LANGS := @LLVMGCC_LANGS@
LLVMGCC_DRAGONEGG := @LLVMGCC_DRAGONEGG@
# Information on Clang, if configured.
CLANGPATH := @CLANGPATH@
CLANGXXPATH := @CLANGXXPATH@
ENABLE_BUILT_CLANG := @ENABLE_BUILT_CLANG@
# The LLVM capable compiler to use.
LLVMCC_OPTION := @LLVMCC_OPTION@
# The flag used to emit LLVM IR.
LLVMCC_EMITIR_FLAG = @LLVMCC_EMITIR_FLAG@
LLVMCC_DISABLEOPT_FLAGS := @LLVMCC_DISABLEOPT_FLAGS@
# Path to directory where object files should be stored during a build.
# Set OBJ_ROOT to "." if you do not want to use a separate place for
# object files.
@ -338,17 +314,6 @@ endif
# Location of the plugin header file for gold.
BINUTILS_INCDIR := @BINUTILS_INCDIR@
# When ENABLE_LLVMC_DYNAMIC is enabled, LLVMC will link libCompilerDriver
# dynamically. This is needed to make dynamic plugins work on some targets
# (Windows).
ENABLE_LLVMC_DYNAMIC = 0
#@ENABLE_LLVMC_DYNAMIC@
# When ENABLE_LLVMC_DYNAMIC_PLUGINS is enabled, LLVMC will have dynamic plugin
# support (via the -load option).
ENABLE_LLVMC_DYNAMIC_PLUGINS = 1
#@ENABLE_LLVMC_DYNAMIC_PLUGINS@
# Optional flags supported by the compiler
# -Wno-missing-field-initializers
NO_MISSING_FIELD_INITIALIZERS = @NO_MISSING_FIELD_INITIALIZERS@

View File

@ -190,19 +190,6 @@ uninstall:: uninstall-local
install-local:: all-local
install-bytecode:: install-bytecode-local
###############################################################################
# LLVMC: Provide rules for compiling llvmc-based driver
###############################################################################
ifdef LLVMC_BASED_DRIVER
TOOLNAME = $(LLVMC_BASED_DRIVER)
LLVMLIBS = CompilerDriver.a
LINK_COMPONENTS = support
endif # LLVMC_BASED_DRIVER
###############################################################################
# VARIABLES: Set up various variables based on configuration data
###############################################################################
@ -463,11 +450,11 @@ Echo = @$(EchoCmd)
ifndef LLVMAS
LLVMAS := $(LLVMToolDir)/llvm-as$(EXEEXT)
endif
ifndef TBLGEN
ifndef LLVM_TBLGEN
ifeq ($(LLVM_CROSS_COMPILING),1)
TBLGEN := $(BuildLLVMToolDir)/tblgen$(BUILD_EXEEXT)
LLVM_TBLGEN := $(BuildLLVMToolDir)/llvm-tblgen$(BUILD_EXEEXT)
else
TBLGEN := $(LLVMToolDir)/tblgen$(EXEEXT)
LLVM_TBLGEN := $(LLVMToolDir)/llvm-tblgen$(EXEEXT)
endif
endif
LLVM_CONFIG := $(LLVMToolDir)/llvm-config
@ -636,7 +623,7 @@ CPP.BaseFlags += -include llvm/Support/Solaris.h
endif # !HOST_OS - AuroraUX.
LD.Flags += -L$(LibDir) -L$(LLVMLibDir)
CPP.BaseFlags += -D_GNU_SOURCE -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS
CPP.BaseFlags += -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS
# All -I flags should go here, so that they don't confuse llvm-config.
CPP.Flags += $(sort -I$(PROJ_OBJ_DIR) -I$(PROJ_SRC_DIR) \
$(patsubst %,-I%/include,\
@ -697,10 +684,11 @@ DataInstall = $(INSTALL) -m 0644
# When compiling under Mingw/Cygwin, the tblgen tool expects Windows
# paths. In this case, the SYSPATH function (defined in
# Makefile.config) transforms Unix paths into Windows paths.
TableGen = $(TBLGEN) -I $(call SYSPATH, $(PROJ_SRC_DIR)) \
TableGen.Flags= -I $(call SYSPATH, $(PROJ_SRC_DIR)) \
-I $(call SYSPATH, $(LLVM_SRC_ROOT)/include) \
-I $(call SYSPATH, $(PROJ_SRC_ROOT)/include) \
-I $(call SYSPATH, $(PROJ_SRC_ROOT)/lib/Target)
LLVMTableGen = $(LLVM_TBLGEN) $(TableGen.Flags)
Archive = $(AR) $(AR.Flags)
LArchive = $(LLVMToolDir)/llvm-ar rcsf
@ -1686,10 +1674,6 @@ ifdef TARGET
TABLEGEN_INC_FILES_COMMON = 1
endif
ifdef LLVMC_BASED_DRIVER
TABLEGEN_INC_FILES_COMMON = 1
endif
ifdef TABLEGEN_INC_FILES_COMMON
INCFiles := $(filter %.inc,$(BUILT_SOURCES))
@ -1717,87 +1701,87 @@ TDFiles := $(strip $(wildcard $(PROJ_SRC_DIR)/*.td) \
$(LLVM_SRC_ROOT)/include/llvm/CodeGen/ValueTypes.td) \
$(wildcard $(LLVM_SRC_ROOT)/include/llvm/Intrinsics*.td)
# All of these files depend on tblgen and the .td files.
$(INCTMPFiles) : $(TBLGEN) $(TDFiles)
# All .inc.tmp files depend on the .td files.
$(INCTMPFiles) : $(TDFiles)
$(TARGET:%=$(ObjDir)/%GenRegisterInfo.inc.tmp): \
$(ObjDir)/%GenRegisterInfo.inc.tmp : %.td $(ObjDir)/.dir
$(ObjDir)/%GenRegisterInfo.inc.tmp : %.td $(ObjDir)/.dir $(LLVM_TBLGEN)
$(Echo) "Building $(<F) register info implementation with tblgen"
$(Verb) $(TableGen) -gen-register-info -o $(call SYSPATH, $@) $<
$(Verb) $(LLVMTableGen) -gen-register-info -o $(call SYSPATH, $@) $<
$(TARGET:%=$(ObjDir)/%GenInstrInfo.inc.tmp): \
$(ObjDir)/%GenInstrInfo.inc.tmp : %.td $(ObjDir)/.dir
$(ObjDir)/%GenInstrInfo.inc.tmp : %.td $(ObjDir)/.dir $(LLVM_TBLGEN)
$(Echo) "Building $(<F) instruction information with tblgen"
$(Verb) $(TableGen) -gen-instr-info -o $(call SYSPATH, $@) $<
$(Verb) $(LLVMTableGen) -gen-instr-info -o $(call SYSPATH, $@) $<
$(TARGET:%=$(ObjDir)/%GenAsmWriter.inc.tmp): \
$(ObjDir)/%GenAsmWriter.inc.tmp : %.td $(ObjDir)/.dir
$(ObjDir)/%GenAsmWriter.inc.tmp : %.td $(ObjDir)/.dir $(LLVM_TBLGEN)
$(Echo) "Building $(<F) assembly writer with tblgen"
$(Verb) $(TableGen) -gen-asm-writer -o $(call SYSPATH, $@) $<
$(Verb) $(LLVMTableGen) -gen-asm-writer -o $(call SYSPATH, $@) $<
$(TARGET:%=$(ObjDir)/%GenAsmWriter1.inc.tmp): \
$(ObjDir)/%GenAsmWriter1.inc.tmp : %.td $(ObjDir)/.dir
$(ObjDir)/%GenAsmWriter1.inc.tmp : %.td $(ObjDir)/.dir $(LLVM_TBLGEN)
$(Echo) "Building $(<F) assembly writer #1 with tblgen"
$(Verb) $(TableGen) -gen-asm-writer -asmwriternum=1 -o $(call SYSPATH, $@) $<
$(Verb) $(LLVMTableGen) -gen-asm-writer -asmwriternum=1 -o $(call SYSPATH, $@) $<
$(TARGET:%=$(ObjDir)/%GenAsmMatcher.inc.tmp): \
$(ObjDir)/%GenAsmMatcher.inc.tmp : %.td $(ObjDir)/.dir
$(ObjDir)/%GenAsmMatcher.inc.tmp : %.td $(ObjDir)/.dir $(LLVM_TBLGEN)
$(Echo) "Building $(<F) assembly matcher with tblgen"
$(Verb) $(TableGen) -gen-asm-matcher -o $(call SYSPATH, $@) $<
$(Verb) $(LLVMTableGen) -gen-asm-matcher -o $(call SYSPATH, $@) $<
$(TARGET:%=$(ObjDir)/%GenMCCodeEmitter.inc.tmp): \
$(ObjDir)/%GenMCCodeEmitter.inc.tmp: %.td $(ObjDir)/.dir
$(ObjDir)/%GenMCCodeEmitter.inc.tmp: %.td $(ObjDir)/.dir $(LLVM_TBLGEN)
$(Echo) "Building $(<F) MC code emitter with tblgen"
$(Verb) $(TableGen) -gen-emitter -mc-emitter -o $(call SYSPATH, $@) $<
$(Verb) $(LLVMTableGen) -gen-emitter -mc-emitter -o $(call SYSPATH, $@) $<
$(TARGET:%=$(ObjDir)/%GenMCPseudoLowering.inc.tmp): \
$(ObjDir)/%GenMCPseudoLowering.inc.tmp: %.td $(ObjDir)/.dir
$(ObjDir)/%GenMCPseudoLowering.inc.tmp: %.td $(ObjDir)/.dir $(LLVM_TBLGEN)
$(Echo) "Building $(<F) MC Pseudo instruction expander with tblgen"
$(Verb) $(TableGen) -gen-pseudo-lowering -o $(call SYSPATH, $@) $<
$(Verb) $(LLVMTableGen) -gen-pseudo-lowering -o $(call SYSPATH, $@) $<
$(TARGET:%=$(ObjDir)/%GenCodeEmitter.inc.tmp): \
$(ObjDir)/%GenCodeEmitter.inc.tmp: %.td $(ObjDir)/.dir
$(ObjDir)/%GenCodeEmitter.inc.tmp: %.td $(ObjDir)/.dir $(LLVM_TBLGEN)
$(Echo) "Building $(<F) code emitter with tblgen"
$(Verb) $(TableGen) -gen-emitter -o $(call SYSPATH, $@) $<
$(Verb) $(LLVMTableGen) -gen-emitter -o $(call SYSPATH, $@) $<
$(TARGET:%=$(ObjDir)/%GenDAGISel.inc.tmp): \
$(ObjDir)/%GenDAGISel.inc.tmp : %.td $(ObjDir)/.dir
$(ObjDir)/%GenDAGISel.inc.tmp : %.td $(ObjDir)/.dir $(LLVM_TBLGEN)
$(Echo) "Building $(<F) DAG instruction selector implementation with tblgen"
$(Verb) $(TableGen) -gen-dag-isel -o $(call SYSPATH, $@) $<
$(Verb) $(LLVMTableGen) -gen-dag-isel -o $(call SYSPATH, $@) $<
$(TARGET:%=$(ObjDir)/%GenDisassemblerTables.inc.tmp): \
$(ObjDir)/%GenDisassemblerTables.inc.tmp : %.td $(ObjDir)/.dir
$(ObjDir)/%GenDisassemblerTables.inc.tmp : %.td $(ObjDir)/.dir $(LLVM_TBLGEN)
$(Echo) "Building $(<F) disassembly tables with tblgen"
$(Verb) $(TableGen) -gen-disassembler -o $(call SYSPATH, $@) $<
$(Verb) $(LLVMTableGen) -gen-disassembler -o $(call SYSPATH, $@) $<
$(TARGET:%=$(ObjDir)/%GenEDInfo.inc.tmp): \
$(ObjDir)/%GenEDInfo.inc.tmp : %.td $(ObjDir)/.dir
$(ObjDir)/%GenEDInfo.inc.tmp : %.td $(ObjDir)/.dir $(LLVM_TBLGEN)
$(Echo) "Building $(<F) enhanced disassembly information with tblgen"
$(Verb) $(TableGen) -gen-enhanced-disassembly-info -o $(call SYSPATH, $@) $<
$(Verb) $(LLVMTableGen) -gen-enhanced-disassembly-info -o $(call SYSPATH, $@) $<
$(TARGET:%=$(ObjDir)/%GenFastISel.inc.tmp): \
$(ObjDir)/%GenFastISel.inc.tmp : %.td $(ObjDir)/.dir
$(ObjDir)/%GenFastISel.inc.tmp : %.td $(ObjDir)/.dir $(LLVM_TBLGEN)
$(Echo) "Building $(<F) \"fast\" instruction selector implementation with tblgen"
$(Verb) $(TableGen) -gen-fast-isel -o $(call SYSPATH, $@) $<
$(Verb) $(LLVMTableGen) -gen-fast-isel -o $(call SYSPATH, $@) $<
$(TARGET:%=$(ObjDir)/%GenSubtargetInfo.inc.tmp): \
$(ObjDir)/%GenSubtargetInfo.inc.tmp : %.td $(ObjDir)/.dir
$(ObjDir)/%GenSubtargetInfo.inc.tmp : %.td $(ObjDir)/.dir $(LLVM_TBLGEN)
$(Echo) "Building $(<F) subtarget information with tblgen"
$(Verb) $(TableGen) -gen-subtarget -o $(call SYSPATH, $@) $<
$(Verb) $(LLVMTableGen) -gen-subtarget -o $(call SYSPATH, $@) $<
$(TARGET:%=$(ObjDir)/%GenCallingConv.inc.tmp): \
$(ObjDir)/%GenCallingConv.inc.tmp : %.td $(ObjDir)/.dir
$(ObjDir)/%GenCallingConv.inc.tmp : %.td $(ObjDir)/.dir $(LLVM_TBLGEN)
$(Echo) "Building $(<F) calling convention information with tblgen"
$(Verb) $(TableGen) -gen-callingconv -o $(call SYSPATH, $@) $<
$(Verb) $(LLVMTableGen) -gen-callingconv -o $(call SYSPATH, $@) $<
$(TARGET:%=$(ObjDir)/%GenIntrinsics.inc.tmp): \
$(ObjDir)/%GenIntrinsics.inc.tmp : %.td $(ObjDir)/.dir
$(ObjDir)/%GenIntrinsics.inc.tmp : %.td $(ObjDir)/.dir $(LLVM_TBLGEN)
$(Echo) "Building $(<F) intrinsics information with tblgen"
$(Verb) $(TableGen) -gen-tgt-intrinsic -o $(call SYSPATH, $@) $<
$(Verb) $(LLVMTableGen) -gen-tgt-intrinsic -o $(call SYSPATH, $@) $<
$(ObjDir)/ARMGenDecoderTables.inc.tmp : ARM.td $(ObjDir)/.dir
$(ObjDir)/ARMGenDecoderTables.inc.tmp : ARM.td $(ObjDir)/.dir $(LLVM_TBLGEN)
$(Echo) "Building $(<F) decoder tables with tblgen"
$(Verb) $(TableGen) -gen-arm-decoder -o $(call SYSPATH, $@) $<
$(Verb) $(LLVMTableGen) -gen-arm-decoder -o $(call SYSPATH, $@) $<
clean-local::
@ -1805,27 +1789,6 @@ clean-local::
endif # TARGET
ifdef LLVMC_BASED_DRIVER
TDSrc := $(sort $(strip $(wildcard $(PROJ_SRC_DIR)/*.td)) \
$(strip $(wildcard $(PROJ_OBJ_DIR)/*.td)))
TDCommon := $(strip $(wildcard \
$(LLVM_SRC_ROOT)/include/llvm/CompilerDriver/*.td))
TDFiles := $(TDSrc) $(TDCommon)
$(INCTMPFiles) : $(TBLGEN) $(TDFiles)
$(ObjDir)/%.inc.tmp: %.td $(ObjDir)/.dir
$(Echo) "Building LLVMC compilation graph description with tblgen"
$(Verb) $(TableGen) -gen-llvmc -o $(call SYSPATH, $@) $<
clean-local::
-$(Verb) $(RM) -f $(INCFiles)
endif # LLVMC_BASED_DRIVER
###############################################################################
# OTHER RULES: Other rules needed
###############################################################################

View File

@ -13,4 +13,3 @@ assistance with LLVM.
If you're writing a package for LLVM, see docs/Packaging.html for our
suggestions.

View File

@ -14,9 +14,9 @@ clean() {
### Periods should be escaped with backslash for use by grep.
###
### If you update these, please also update docs/GettingStarted.html
want_autoconf_version='2\.60'
want_autoconf_version='2\.61'
want_autoheader_version=$want_autoconf_version
want_aclocal_version='1\.9\.6'
want_aclocal_version='1\.10'
want_libtool_version='1\.5\.22'
### END NOTE #########################################################

249
autoconf/config.guess vendored
View File

@ -1,10 +1,10 @@
#! /bin/sh
# Attempt to guess a canonical system name.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
# Free Software Foundation, Inc.
# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
# 2011 Free Software Foundation, Inc.
timestamp='2009-09-18'
timestamp='2011-08-20'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@ -56,8 +56,9 @@ version="\
GNU config.guess ($timestamp)
Originally written by Per Bothner.
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free
Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@ -180,7 +181,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
fi
;;
*)
os=netbsd
os=netbsd
;;
esac
# The OS release
@ -223,7 +224,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
;;
*5.*)
UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
;;
esac
# According to Compaq, /usr/sbin/psrinfo has been available on
@ -269,7 +270,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
# A Xn.n version is an unreleased experimental baselevel.
# 1.2 uses "1.2" for uname -r.
echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
exit ;;
# Reset EXIT trap before exiting to avoid spurious non-zero exit code.
exitcode=$?
trap '' 0
exit $exitcode ;;
Alpha\ *:Windows_NT*:*)
# How do we know it's Interix rather than the generic POSIX subsystem?
# Should we change UNAME_MACHINE based on the output of uname instead
@ -295,7 +299,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
echo s390-ibm-zvmoe
exit ;;
*:OS400:*:*)
echo powerpc-ibm-os400
echo powerpc-ibm-os400
exit ;;
arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
echo arm-acorn-riscix${UNAME_RELEASE}
@ -334,8 +338,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit ;;
i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
AUX_ARCH="i386"
echo ${AUX_ARCH}-pc-auroraux`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
echo i386-pc-auroraux${UNAME_RELEASE}
exit ;;
i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
eval $set_cc_for_build
@ -395,23 +398,23 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
# MiNT. But MiNT is downward compatible to TOS, so this should
# be no problem.
atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
echo m68k-atari-mint${UNAME_RELEASE}
echo m68k-atari-mint${UNAME_RELEASE}
exit ;;
atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
echo m68k-atari-mint${UNAME_RELEASE}
exit ;;
exit ;;
*falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
echo m68k-atari-mint${UNAME_RELEASE}
echo m68k-atari-mint${UNAME_RELEASE}
exit ;;
milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
echo m68k-milan-mint${UNAME_RELEASE}
exit ;;
echo m68k-milan-mint${UNAME_RELEASE}
exit ;;
hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
echo m68k-hades-mint${UNAME_RELEASE}
exit ;;
echo m68k-hades-mint${UNAME_RELEASE}
exit ;;
*:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
echo m68k-unknown-mint${UNAME_RELEASE}
exit ;;
echo m68k-unknown-mint${UNAME_RELEASE}
exit ;;
m68k:machten:*:*)
echo m68k-apple-machten${UNAME_RELEASE}
exit ;;
@ -481,8 +484,8 @@ EOF
echo m88k-motorola-sysv3
exit ;;
AViiON:dgux:*:*)
# DG/UX returns AViiON for all architectures
UNAME_PROCESSOR=`/usr/bin/uname -p`
# DG/UX returns AViiON for all architectures
UNAME_PROCESSOR=`/usr/bin/uname -p`
if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
then
if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
@ -495,7 +498,7 @@ EOF
else
echo i586-dg-dgux${UNAME_RELEASE}
fi
exit ;;
exit ;;
M88*:DolphinOS:*:*) # DolphinOS (SVR3)
echo m88k-dolphin-sysv3
exit ;;
@ -552,7 +555,7 @@ EOF
echo rs6000-ibm-aix3.2
fi
exit ;;
*:AIX:*:[456])
*:AIX:*:[4567])
IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
IBM_ARCH=rs6000
@ -595,52 +598,52 @@ EOF
9000/[678][0-9][0-9])
if [ -x /usr/bin/getconf ]; then
sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
case "${sc_cpu_version}" in
523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
532) # CPU_PA_RISC2_0
case "${sc_kernel_bits}" in
32) HP_ARCH="hppa2.0n" ;;
64) HP_ARCH="hppa2.0w" ;;
sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
case "${sc_cpu_version}" in
523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
532) # CPU_PA_RISC2_0
case "${sc_kernel_bits}" in
32) HP_ARCH="hppa2.0n" ;;
64) HP_ARCH="hppa2.0w" ;;
'') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
esac ;;
esac
esac ;;
esac
fi
if [ "${HP_ARCH}" = "" ]; then
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
sed 's/^ //' << EOF >$dummy.c
#define _HPUX_SOURCE
#include <stdlib.h>
#include <unistd.h>
#define _HPUX_SOURCE
#include <stdlib.h>
#include <unistd.h>
int main ()
{
#if defined(_SC_KERNEL_BITS)
long bits = sysconf(_SC_KERNEL_BITS);
#endif
long cpu = sysconf (_SC_CPU_VERSION);
int main ()
{
#if defined(_SC_KERNEL_BITS)
long bits = sysconf(_SC_KERNEL_BITS);
#endif
long cpu = sysconf (_SC_CPU_VERSION);
switch (cpu)
{
case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
case CPU_PA_RISC2_0:
#if defined(_SC_KERNEL_BITS)
switch (bits)
{
case 64: puts ("hppa2.0w"); break;
case 32: puts ("hppa2.0n"); break;
default: puts ("hppa2.0"); break;
} break;
#else /* !defined(_SC_KERNEL_BITS) */
puts ("hppa2.0"); break;
#endif
default: puts ("hppa1.0"); break;
}
exit (0);
}
switch (cpu)
{
case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
case CPU_PA_RISC2_0:
#if defined(_SC_KERNEL_BITS)
switch (bits)
{
case 64: puts ("hppa2.0w"); break;
case 32: puts ("hppa2.0n"); break;
default: puts ("hppa2.0"); break;
} break;
#else /* !defined(_SC_KERNEL_BITS) */
puts ("hppa2.0"); break;
#endif
default: puts ("hppa1.0"); break;
}
exit (0);
}
EOF
(CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
test -z "$HP_ARCH" && HP_ARCH=hppa
@ -731,22 +734,22 @@ EOF
exit ;;
C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
echo c1-convex-bsd
exit ;;
exit ;;
C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
if getsysinfo -f scalar_acc
then echo c32-convex-bsd
else echo c2-convex-bsd
fi
exit ;;
exit ;;
C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
echo c34-convex-bsd
exit ;;
exit ;;
C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
echo c38-convex-bsd
exit ;;
exit ;;
C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
echo c4-convex-bsd
exit ;;
exit ;;
CRAY*Y-MP:*:*:*)
echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
exit ;;
@ -770,14 +773,14 @@ EOF
exit ;;
F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
exit ;;
FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
exit ;;
5000:UNIX_System_V:4.*:*)
FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
exit ;;
i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
@ -789,8 +792,8 @@ EOF
echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
exit ;;
*:FreeBSD:*:*)
UNAME_PROCESSOR=`/usr/bin/uname -p`
case ${UNAME_MACHINE} in
UNAME_PROCESSOR=`/usr/bin/uname -p`
case ${UNAME_PROCESSOR} in
amd64)
echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
*)
@ -804,18 +807,18 @@ EOF
echo ${UNAME_MACHINE}-pc-mingw32
exit ;;
i*:windows32*:*)
# uname -m includes "-pc" on this system.
echo ${UNAME_MACHINE}-mingw32
# uname -m includes "-pc" on this system.
echo ${UNAME_MACHINE}-mingw32
exit ;;
i*:PW*:*)
echo ${UNAME_MACHINE}-pc-pw32
exit ;;
*:Interix*:[3456]*)
case ${UNAME_MACHINE} in
*:Interix*:*)
case ${UNAME_MACHINE} in
x86)
echo i586-pc-interix${UNAME_RELEASE}
exit ;;
EM64T | authenticamd | genuineintel)
authenticamd | genuineintel | EM64T)
echo x86_64-unknown-interix${UNAME_RELEASE}
exit ;;
IA64)
@ -866,7 +869,7 @@ EOF
EV6) UNAME_MACHINE=alphaev6 ;;
EV67) UNAME_MACHINE=alphaev67 ;;
EV68*) UNAME_MACHINE=alphaev68 ;;
esac
esac
objdump --private-headers /bin/sh | grep -q ld.so.1
if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
@ -878,7 +881,13 @@ EOF
then
echo ${UNAME_MACHINE}-unknown-linux-gnu
else
echo ${UNAME_MACHINE}-unknown-linux-gnueabi
if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
| grep -q __ARM_PCS_VFP
then
echo ${UNAME_MACHINE}-unknown-linux-gnueabi
else
echo ${UNAME_MACHINE}-unknown-linux-gnueabihf
fi
fi
exit ;;
avr32*:Linux:*:*)
@ -891,10 +900,18 @@ EOF
echo crisv32-axis-linux-gnu
exit ;;
frv:Linux:*:*)
echo frv-unknown-linux-gnu
echo frv-unknown-linux-gnu
exit ;;
i*86:Linux:*:*)
echo ${UNAME_MACHINE}-pc-linux-gnu
LIBC=gnu
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
#ifdef __dietlibc__
LIBC=dietlibc
#endif
EOF
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
exit ;;
ia64:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
@ -921,11 +938,7 @@ EOF
#endif
#endif
EOF
eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
/^CPU/{
s: ::g
p
}'`"
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
;;
or32:Linux:*:*)
@ -955,7 +968,7 @@ EOF
echo ${UNAME_MACHINE}-ibm-linux
exit ;;
sh64*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
sh*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
@ -963,6 +976,9 @@ EOF
sparc:Linux:*:* | sparc64:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
tile*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
vax:Linux:*:*)
echo ${UNAME_MACHINE}-dec-linux-gnu
exit ;;
@ -970,7 +986,7 @@ EOF
echo x86_64-unknown-linux-gnu
exit ;;
xtensa*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
i*86:DYNIX/ptx:4*:*)
# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
@ -979,11 +995,11 @@ EOF
echo i386-sequent-sysv4
exit ;;
i*86:UNIX_SV:4.2MP:2.*)
# Unixware is an offshoot of SVR4, but it has its own version
# number series starting with 2...
# I am not positive that other SVR4 systems won't match this,
# Unixware is an offshoot of SVR4, but it has its own version
# number series starting with 2...
# I am not positive that other SVR4 systems won't match this,
# I just have to hope. -- rms.
# Use sysv4.2uw... so that sysv4* matches it.
# Use sysv4.2uw... so that sysv4* matches it.
echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
exit ;;
i*86:OS/2:*:*)
@ -1015,7 +1031,7 @@ EOF
fi
exit ;;
i*86:*:5:[678]*)
# UnixWare 7.x, OpenUNIX and OpenServer 6.
# UnixWare 7.x, OpenUNIX and OpenServer 6.
case `/bin/uname -X | grep "^Machine"` in
*486*) UNAME_MACHINE=i486 ;;
*Pentium) UNAME_MACHINE=i586 ;;
@ -1043,13 +1059,13 @@ EOF
exit ;;
pc:*:*:*)
# Left here for compatibility:
# uname -m prints for DJGPP always 'pc', but it prints nothing about
# the processor, so we play safe by assuming i586.
# uname -m prints for DJGPP always 'pc', but it prints nothing about
# the processor, so we play safe by assuming i586.
# Note: whatever this is, it MUST be the same as what config.sub
# prints for the "djgpp" host, or else GDB configury will decide that
# this is a cross-build.
echo i586-pc-msdosdjgpp
exit ;;
exit ;;
Intel:Mach:3*:*)
echo i386-pc-mach3
exit ;;
@ -1084,8 +1100,8 @@ EOF
/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
&& { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
&& { echo i486-ncr-sysv4; exit; } ;;
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
&& { echo i486-ncr-sysv4; exit; } ;;
NCR*:*:4.2:* | MPRAS*:*:4.2:*)
OS_REL='.3'
test -r /etc/.relid \
@ -1128,10 +1144,10 @@ EOF
echo ns32k-sni-sysv
fi
exit ;;
PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
# says <Richard.M.Bartel@ccMail.Census.GOV>
echo i586-unisys-sysv4
exit ;;
PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
# says <Richard.M.Bartel@ccMail.Census.GOV>
echo i586-unisys-sysv4
exit ;;
*:UNIX_System_V:4*:FTX*)
# From Gerald Hewes <hewes@openmarket.com>.
# How about differentiating between stratus architectures? -djm
@ -1157,11 +1173,11 @@ EOF
exit ;;
R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
if [ -d /usr/nec ]; then
echo mips-nec-sysv${UNAME_RELEASE}
echo mips-nec-sysv${UNAME_RELEASE}
else
echo mips-unknown-sysv${UNAME_RELEASE}
echo mips-unknown-sysv${UNAME_RELEASE}
fi
exit ;;
exit ;;
BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
echo powerpc-be-beos
exit ;;
@ -1226,6 +1242,9 @@ EOF
*:QNX:*:4*)
echo i386-pc-qnx
exit ;;
NEO-?:NONSTOP_KERNEL:*:*)
echo neo-tandem-nsk${UNAME_RELEASE}
exit ;;
NSE-?:NONSTOP_KERNEL:*:*)
echo nse-tandem-nsk${UNAME_RELEASE}
exit ;;
@ -1271,13 +1290,13 @@ EOF
echo pdp10-unknown-its
exit ;;
SEI:*:*:SEIUX)
echo mips-sei-seiux${UNAME_RELEASE}
echo mips-sei-seiux${UNAME_RELEASE}
exit ;;
*:DragonFly:*:*)
echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
exit ;;
*:*VMS:*:*)
UNAME_MACHINE=`(uname -p) 2>/dev/null`
UNAME_MACHINE=`(uname -p) 2>/dev/null`
case "${UNAME_MACHINE}" in
A*) echo alpha-dec-vms ; exit ;;
I*) echo ia64-dec-vms ; exit ;;
@ -1317,11 +1336,11 @@ main ()
#include <sys/param.h>
printf ("m68k-sony-newsos%s\n",
#ifdef NEWSOS4
"4"
"4"
#else
""
""
#endif
); exit (0);
); exit (0);
#endif
#endif

186
autoconf/config.sub vendored
View File

@ -1,10 +1,10 @@
#! /bin/sh
# Configuration validation subroutine script.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
# Free Software Foundation, Inc.
# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
# 2011 Free Software Foundation, Inc.
timestamp='2009-08-19'
timestamp='2011-08-23'
# This file is (in principle) common to ALL GNU software.
# The presence of a machine in this file suggests that SOME GNU software
@ -75,8 +75,9 @@ Report bugs and patches to <config-patches@gnu.org>."
version="\
GNU config.sub ($timestamp)
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free
Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@ -123,8 +124,9 @@ esac
# Here we must recognize all the valid KERNEL-OS combinations.
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
case $maybe_os in
nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \
uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \
nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
knetbsd*-gnu* | netbsd*-gnu* | \
kopensolaris*-gnu* | \
storm-chaos* | os2-emx* | rtmk-nova*)
os=-$maybe_os
@ -156,8 +158,8 @@ case $os in
os=
basic_machine=$1
;;
-bluegene*)
os=-cnk
-bluegene*)
os=-cnk
;;
-sim | -cisco | -oki | -wec | -winbond)
os=
@ -173,10 +175,10 @@ case $os in
os=-chorusos
basic_machine=$1
;;
-chorusrdb)
os=-chorusrdb
-chorusrdb)
os=-chorusrdb
basic_machine=$1
;;
;;
-hiux*)
os=-hiuxwe2
;;
@ -249,6 +251,7 @@ case $basic_machine in
| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
| am33_2.0 \
| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
| be32 | be64 \
| bfin \
| c4x | clipper \
| d10v | d30v | dlx | dsp16xx \
@ -256,6 +259,7 @@ case $basic_machine in
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
| i370 | i860 | i960 | ia64 \
| ip2k | iq2000 \
| le32 | le64 \
| lm32 \
| m32c | m32r | m32rle | m68000 | m68k | m88k \
| maxq | mb | microblaze | mcore | mep | metag \
@ -281,26 +285,39 @@ case $basic_machine in
| moxie \
| mt \
| msp430 \
| nds32 | nds32le | nds32be \
| nios | nios2 \
| ns16k | ns32k \
| open8 \
| or32 \
| pdp10 | pdp11 | pj | pjl \
| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
| powerpc | powerpc64 | powerpc64le | powerpcle \
| pyramid \
| rx \
| score \
| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
| sh64 | sh64le \
| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
| spu | strongarm \
| tahoe | thumb | tic4x | tic80 | tron \
| v850 | v850e \
| spu \
| tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
| ubicom32 \
| v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
| we32k \
| x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \
| x86 | xc16x | xstormy16 | xtensa \
| z8k | z80)
basic_machine=$basic_machine-unknown
;;
m6811 | m68hc11 | m6812 | m68hc12)
c54x)
basic_machine=tic54x-unknown
;;
c55x)
basic_machine=tic55x-unknown
;;
c6x)
basic_machine=tic6x-unknown
;;
m6811 | m68hc11 | m6812 | m68hc12 | picochip)
# Motorola 68HC11/12.
basic_machine=$basic_machine-unknown
os=-none
@ -311,6 +328,18 @@ case $basic_machine in
basic_machine=mt-unknown
;;
strongarm | thumb | xscale)
basic_machine=arm-unknown
;;
xscaleeb)
basic_machine=armeb-unknown
;;
xscaleel)
basic_machine=armel-unknown
;;
# We use `pc' rather than `unknown'
# because (1) that's what they normally are, and
# (2) the word "unknown" tends to confuse beginning users.
@ -330,8 +359,9 @@ case $basic_machine in
| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
| arm-* | armbe-* | armle-* | armeb-* | armv*-* \
| avr-* | avr32-* \
| be32-* | be64-* \
| bfin-* | bs2000-* \
| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
| c[123]* | c30-* | [cjt]90-* | c4x-* \
| clipper-* | craynv-* | cydra-* \
| d10v-* | d30v-* | dlx-* \
| elxsi-* \
@ -340,6 +370,7 @@ case $basic_machine in
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
| i*86-* | i860-* | i960-* | ia64-* \
| ip2k-* | iq2000-* \
| le32-* | le64-* \
| lm32-* \
| m32c-* | m32r-* | m32rle-* \
| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
@ -365,24 +396,29 @@ case $basic_machine in
| mmix-* \
| mt-* \
| msp430-* \
| nds32-* | nds32le-* | nds32be-* \
| nios-* | nios2-* \
| none-* | np1-* | ns16k-* | ns32k-* \
| open8-* \
| orion-* \
| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
| pyramid-* \
| romp-* | rs6000-* \
| romp-* | rs6000-* | rx-* \
| sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
| sparclite-* \
| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \
| tahoe-* | thumb-* \
| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* | tile-* \
| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \
| tahoe-* \
| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
| tile*-* \
| tron-* \
| v850-* | v850e-* | vax-* \
| ubicom32-* \
| v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
| vax-* \
| we32k-* \
| x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \
| x86-* | x86_64-* | xc16x-* | xps100-* \
| xstormy16-* | xtensa*-* \
| ymp-* \
| z8k-* | z80-*)
@ -407,7 +443,7 @@ case $basic_machine in
basic_machine=a29k-amd
os=-udi
;;
abacus)
abacus)
basic_machine=abacus-unknown
;;
adobe68k)
@ -477,11 +513,20 @@ case $basic_machine in
basic_machine=powerpc-ibm
os=-cnk
;;
c54x-*)
basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
c55x-*)
basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
c6x-*)
basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
c90)
basic_machine=c90-cray
os=-unicos
;;
cegcc)
cegcc)
basic_machine=arm-unknown
os=-cegcc
;;
@ -513,7 +558,7 @@ case $basic_machine in
basic_machine=craynv-cray
os=-unicosmp
;;
cr16)
cr16 | cr16-*)
basic_machine=cr16-unknown
os=-elf
;;
@ -729,7 +774,7 @@ case $basic_machine in
basic_machine=ns32k-utek
os=-sysv
;;
microblaze)
microblaze)
basic_machine=microblaze-xilinx
;;
mingw32)
@ -772,6 +817,10 @@ case $basic_machine in
basic_machine=i370-ibm
os=-mvs
;;
nacl)
basic_machine=le32-unknown
os=-nacl
;;
ncr3000)
basic_machine=i486-ncr
os=-sysv4
@ -836,6 +885,12 @@ case $basic_machine in
np1)
basic_machine=np1-gould
;;
neo-tandem)
basic_machine=neo-tandem
;;
nse-tandem)
basic_machine=nse-tandem
;;
nsr-tandem)
basic_machine=nsr-tandem
;;
@ -918,9 +973,10 @@ case $basic_machine in
;;
power) basic_machine=power-ibm
;;
ppc) basic_machine=powerpc-unknown
ppc | ppcbe) basic_machine=powerpc-unknown
;;
ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
ppc-* | ppcbe-*)
basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ppcle | powerpclittle | ppc-le | powerpc-little)
basic_machine=powerpcle-unknown
@ -1014,6 +1070,9 @@ case $basic_machine in
basic_machine=i860-stratus
os=-sysv4
;;
strongarm-* | thumb-*)
basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
sun2)
basic_machine=m68000-sun
;;
@ -1070,20 +1129,8 @@ case $basic_machine in
basic_machine=t90-cray
os=-unicos
;;
tic54x | c54x*)
basic_machine=tic54x-unknown
os=-coff
;;
tic55x | c55x*)
basic_machine=tic55x-unknown
os=-coff
;;
tic6x | c6x*)
basic_machine=tic6x-unknown
os=-coff
;;
tile*)
basic_machine=tile-unknown
basic_machine=$basic_machine-unknown
os=-linux-gnu
;;
tx39)
@ -1153,6 +1200,9 @@ case $basic_machine in
xps | xps100)
basic_machine=xps100-honeywell
;;
xscale-* | xscalee[bl]-*)
basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`
;;
ymp)
basic_machine=ymp-cray
os=-unicos
@ -1250,15 +1300,15 @@ esac
if [ x"$os" != x"" ]
then
case $os in
# First match some system type aliases
# that might get confused with valid system types.
# First match some system type aliases
# that might get confused with valid system types.
# -solaris* is a basic system type, with this one exception.
-solaris1 | -solaris1.*)
os=`echo $os | sed -e 's|solaris1|sunos4|'`
;;
-auroraux)
os=-auroraux
;;
-solaris1 | -solaris1.*)
os=`echo $os | sed -e 's|solaris1|sunos4|'`
;;
-solaris)
os=-solaris2
;;
@ -1277,8 +1327,8 @@ case $os in
# -sysv* is not here because it comes later, after sysvr4.
-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
| -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
| -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* | -sym* \
| -kopensolaris* \
| -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
| -sym* | -kopensolaris* \
| -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
| -aos* | -aros* \
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
@ -1291,7 +1341,8 @@ case $os in
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
| -chorusos* | -chorusrdb* | -cegcc* \
| -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
| -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
| -mingw32* | -linux-gnu* | -linux-android* \
| -linux-newlib* | -linux-uclibc* \
| -uxpv* | -beos* | -mpeix* | -udk* \
| -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
| -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
@ -1299,7 +1350,7 @@ case $os in
| -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
| -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
| -skyos* | -haiku* | -rdos* | -toppers* | -drops*)
| -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*)
# Remember, each alternative MUST END IN *, to match a version number.
;;
-qnx*)
@ -1338,7 +1389,7 @@ case $os in
-opened*)
os=-openedition
;;
-os400*)
-os400*)
os=-os400
;;
-wince*)
@ -1387,7 +1438,7 @@ case $os in
-sinix*)
os=-sysv4
;;
-tpf*)
-tpf*)
os=-tpf
;;
-triton*)
@ -1432,6 +1483,8 @@ case $os in
-dicos*)
os=-dicos
;;
-nacl*)
;;
-none)
;;
*)
@ -1454,10 +1507,10 @@ else
# system, and we'll never get to this point.
case $basic_machine in
score-*)
score-*)
os=-elf
;;
spu-*)
spu-*)
os=-elf
;;
*-acorn)
@ -1469,8 +1522,17 @@ case $basic_machine in
arm*-semi)
os=-aout
;;
c4x-* | tic4x-*)
os=-coff
c4x-* | tic4x-*)
os=-coff
;;
tic54x-*)
os=-coff
;;
tic55x-*)
os=-coff
;;
tic6x-*)
os=-coff
;;
# This must come before the *-dec entry.
pdp10-*)
@ -1497,7 +1559,7 @@ case $basic_machine in
m68*-cisco)
os=-aout
;;
mep-*)
mep-*)
os=-elf
;;
mips*-cisco)
@ -1524,7 +1586,7 @@ case $basic_machine in
*-ibm)
os=-aix
;;
*-knuth)
*-knuth)
os=-mmixware
;;
*-wec)

View File

@ -31,16 +31,15 @@ dnl===
dnl===-----------------------------------------------------------------------===
dnl Initialize autoconf and define the package name, version number and
dnl email address for reporting bugs.
AC_INIT([[llvm]],[[3.0svn]],[llvmbugs@cs.uiuc.edu])
AC_INIT([[llvm]],[[3.0]],[llvmbugs@cs.uiuc.edu])
dnl Provide a copyright substitution and ensure the copyright notice is included
dnl in the output of --version option of the generated configure script.
AC_SUBST(LLVM_COPYRIGHT,["Copyright (c) 2003-2011 University of Illinois at Urbana-Champaign."])
AC_COPYRIGHT([Copyright (c) 2003-2011 University of Illinois at Urbana-Champaign.])
dnl Indicate that we require autoconf 2.59 or later. Ths is needed because we
dnl use some autoconf macros only available in 2.59.
AC_PREREQ(2.59)
dnl Indicate that we require autoconf 2.60 or later.
AC_PREREQ(2.60)
dnl Verify that the source directory is valid. This makes sure that we are
dnl configuring LLVM and not some other package (it validates --srcdir argument)
@ -58,6 +57,12 @@ if test ${srcdir} != "." ; then
fi
fi
dnl We need to check for the compiler up here to avoid anything else
dnl starting with a different one.
AC_PROG_CC(clang llvm-gcc gcc)
AC_PROG_CXX(clang++ llvm-g++ g++)
AC_PROG_CPP
dnl Configure all of the projects present in our source tree. While we could
dnl just AC_CONFIG_SUBDIRS on the set of directories in projects that have a
dnl configure script, that usage of the AC_CONFIG_SUBDIRS macro is deprecated.
@ -299,6 +304,8 @@ AC_CACHE_CHECK([type of operating system we're going to target],
llvm_cv_target_os_type="Haiku" ;;
*-*-rtems*)
llvm_cv_target_os_type="RTEMS" ;;
*-*-nacl*)
llvm_cv_target_os_type="NativeClient" ;;
*-unknown-eabi*)
llvm_cv_target_os_type="Freestanding" ;;
*)
@ -413,7 +420,7 @@ dnl===-----------------------------------------------------------------------===
dnl --enable-optimized : check whether they want to do an optimized build:
AC_ARG_ENABLE(optimized, AS_HELP_STRING(
--enable-optimized,[Compile with optimizations enabled (default is NO)]),,enableval=$optimize)
--enable-optimized,[Compile with optimizations enabled (default is YES)]),,enableval=$optimize)
if test ${enableval} = "no" ; then
AC_SUBST(ENABLE_OPTIMIZED,[[]])
else
@ -431,7 +438,7 @@ fi
dnl --enable-assertions : check whether they want to turn on assertions or not:
AC_ARG_ENABLE(assertions,AS_HELP_STRING(
--enable-assertions,[Compile with assertion checks enabled (default is YES)]),, enableval="yes")
--enable-assertions,[Compile with assertion checks enabled (default is NO)]),, enableval="no")
if test ${enableval} = "yes" ; then
AC_SUBST(DISABLE_ASSERTIONS,[[]])
else
@ -484,7 +491,7 @@ else
x86_64) AC_SUBST(TARGET_HAS_JIT,1) ;;
Alpha) AC_SUBST(TARGET_HAS_JIT,0) ;;
ARM) AC_SUBST(TARGET_HAS_JIT,1) ;;
Mips) AC_SUBST(TARGET_HAS_JIT,0) ;;
Mips) AC_SUBST(TARGET_HAS_JIT,1) ;;
XCore) AC_SUBST(TARGET_HAS_JIT,0) ;;
MSP430) AC_SUBST(TARGET_HAS_JIT,0) ;;
SystemZ) AC_SUBST(TARGET_HAS_JIT,0) ;;
@ -573,12 +580,12 @@ esac
dnl Allow libstdc++ is embedded in LLVM.dll.
AC_ARG_ENABLE(embed-stdcxx,
AS_HELP_STRING([--enable-embed-stdcxx],
[Build a shared library with embedded libstdc++ for Win32 DLL (default is YES)]),,
[Build a shared library with embedded libstdc++ for Win32 DLL (default is NO)]),,
enableval=default)
case "$enableval" in
yes) AC_SUBST(ENABLE_EMBED_STDCXX,[1]) ;;
no) AC_SUBST(ENABLE_EMBED_STDCXX,[0]) ;;
default) AC_SUBST(ENABLE_EMBED_STDCXX,[1]) ;;
default) AC_SUBST(ENABLE_EMBED_STDCXX,[0]) ;;
*) AC_MSG_ERROR([Invalid setting for --enable-embed-stdcxx. Use "yes" or "no"]) ;;
esac
@ -658,7 +665,7 @@ for a_target in $TARGETS_TO_BUILD; do
[LLVM architecture name for the native architecture, if available])
LLVM_NATIVE_TARGET="LLVMInitialize${LLVM_NATIVE_ARCH}Target"
LLVM_NATIVE_TARGETINFO="LLVMInitialize${LLVM_NATIVE_ARCH}TargetInfo"
LLVM_NATIVE_MCASMINFO="LLVMInitialize${LLVM_NATIVE_ARCH}MCAsmInfo"
LLVM_NATIVE_TARGETMC="LLVMInitialize${LLVM_NATIVE_ARCH}TargetMC"
LLVM_NATIVE_ASMPRINTER="LLVMInitialize${LLVM_NATIVE_ARCH}AsmPrinter"
if test -f ${srcdir}/lib/Target/${LLVM_NATIVE_ARCH}/AsmParser/Makefile ; then
LLVM_NATIVE_ASMPARSER="LLVMInitialize${LLVM_NATIVE_ARCH}AsmParser"
@ -667,8 +674,8 @@ for a_target in $TARGETS_TO_BUILD; do
[LLVM name for the native Target init function, if available])
AC_DEFINE_UNQUOTED(LLVM_NATIVE_TARGETINFO, $LLVM_NATIVE_TARGETINFO,
[LLVM name for the native TargetInfo init function, if available])
AC_DEFINE_UNQUOTED(LLVM_NATIVE_MCASMINFO, $LLVM_NATIVE_MCASMINFO,
[LLVM name for the native MCAsmInfo init function, if available])
AC_DEFINE_UNQUOTED(LLVM_NATIVE_TARGETMC, $LLVM_NATIVE_TARGETMC,
[LLVM name for the native target MC init function, if available])
AC_DEFINE_UNQUOTED(LLVM_NATIVE_ASMPRINTER, $LLVM_NATIVE_ASMPRINTER,
[LLVM name for the native AsmPrinter init function, if available])
if test -f ${srcdir}/lib/Target/${LLVM_NATIVE_ARCH}/AsmParser/Makefile ; then
@ -716,97 +723,6 @@ esac
AC_DEFINE_UNQUOTED([ENABLE_CBE_PRINTF_A],$ENABLE_CBE_PRINTF_A,
[Define if CBE is enabled for printf %a output])
dnl Allow a specific llvm-gcc/llvm-g++ pair to be used with this LLVM config.
AC_ARG_WITH(llvmgccdir,
AS_HELP_STRING([--with-llvmgccdir],
[Specify location of llvm-gcc install dir (default searches PATH)]),,
withval=default)
case "$withval" in
default) WITH_LLVMGCCDIR=default ;;
/* | [[A-Za-z]]:[[\\/]]*) WITH_LLVMGCCDIR=$withval ;;
*) AC_MSG_ERROR([Invalid path for --with-llvmgccdir. Provide full path]) ;;
esac
dnl Allow a specific llvm-gcc compiler to be used with this LLVM config.
AC_ARG_WITH(llvmgcc,
AS_HELP_STRING([--with-llvmgcc],
[Specify location of llvm-gcc driver (default searches PATH)]),
LLVMGCC=$with_llvmgcc
WITH_LLVMGCCDIR="",)
dnl Allow a specific llvm-g++ compiler to be used with this LLVM config.
AC_ARG_WITH(llvmgxx,
AS_HELP_STRING([--with-llvmgxx],
[Specify location of llvm-g++ driver (default searches PATH)]),
LLVMGXX=$with_llvmgxx
WITH_LLVMGCCDIR="",)
if test -n "$LLVMGCC"; then
LLVMGCCCOMMAND="$LLVMGCC"
fi
if test -n "$LLVMGXX"; then
LLVMGXXCOMMAND="$LLVMGXX"
fi
if test -n "$LLVMGCC" && test -z "$LLVMGXX"; then
AC_MSG_ERROR([Invalid llvm-g++. Use --with-llvmgxx when --with-llvmgcc is used]);
fi
if test -n "$LLVMGXX" && test -z "$LLVMGCC"; then
AC_MSG_ERROR([Invalid llvm-gcc. Use --with-llvmgcc when --with-llvmgxx is used]);
fi
dnl Allow a specific Clang compiler to be used with this LLVM config.
AC_ARG_WITH(clang,
AS_HELP_STRING([--with-clang],
[Specify location of clang compiler (default is --with-built-clang)]),
[],[with_clang=default])
dnl Enable use of the built Clang.
AC_ARG_WITH(built-clang,
AS_HELP_STRING([--with-built-clang],
[Use the compiled Clang as the LLVM compiler (default=check)]),
[],[with_built_clang=check])
dnl Select the Clang compiler option.
dnl
dnl If --with-clang is given, always honor that; otherwise honor
dnl --with-built-clang, or check if we have the clang sources.
AC_MSG_CHECKING([clang compiler])
WITH_CLANGPATH=""
WITH_BUILT_CLANG=0
if test "$with_clang" != "default"; then
WITH_CLANGPATH="$with_clang"
if ! test -x "$WITH_CLANGPATH"; then
AC_MSG_ERROR([invalid --with-clang, path does not specify an executable])
fi
elif test "$with_built_clang" = "yes"; then
WITH_BUILT_CLANG=1
elif test "$with_built_clang" = "no"; then
WITH_BUILT_CLANG=0
else
if test "$with_built_clang" != "check"; then
AC_MSG_ERROR([invalid value for --with-built-clang.])
fi
if test -f ${srcdir}/tools/clang/README.txt; then
WITH_BUILT_CLANG=1
fi
fi
if ! test -z "$WITH_CLANGPATH"; then
AC_MSG_RESULT([$WITH_CLANGPATH])
WITH_CLANGXXPATH=`"$WITH_CLANGPATH" --print-prog-name=clang++`
elif test "$WITH_BUILT_CLANG" = "1"; then
AC_MSG_RESULT([built])
else
AC_MSG_RESULT([none])
fi
AC_SUBST(CLANGPATH,$WITH_CLANGPATH)
AC_SUBST(CLANGXXPATH,$WITH_CLANGXXPATH)
AC_SUBST(ENABLE_BUILT_CLANG,$WITH_BUILT_CLANG)
dnl Override the option to use for optimized builds.
AC_ARG_WITH(optimize-option,
AS_HELP_STRING([--with-optimize-option],
@ -942,8 +858,8 @@ fi
dnl Specify the URL where bug reports should be submitted.
AC_ARG_WITH(bug-report-url,
AS_HELP_STRING([--with-bug-report-url],
[Specify the URL where bug reports should be submitted (default=http://llvm.org)]),,
withval="http://llvm.org")
[Specify the URL where bug reports should be submitted (default=http://llvm.org/bugs/)]),,
withval="http://llvm.org/bugs/")
AC_DEFINE_UNQUOTED(BUG_REPORT_URL,"$withval",
[Bug report URL.])
@ -963,11 +879,6 @@ dnl=== SECTION 4: Check for programs we need and that they are the right version
dnl===
dnl===-----------------------------------------------------------------------===
dnl Check for compilation tools
AC_PROG_CPP
AC_PROG_CC(gcc)
AC_PROG_CXX(g++)
AC_PROG_NM
AC_SUBST(NM)
@ -1139,55 +1050,6 @@ dnl libtool).
AC_LIBTOOL_DLOPEN
AC_LIB_LTDL
if test "$WITH_LLVMGCCDIR" = "default" ; then
LLVMGCC="llvm-gcc${EXEEXT}"
LLVMGXX="llvm-g++${EXEEXT}"
LLVMGCCCOMMAND="$LLVMGCC"
LLVMGXXCOMMAND="$LLVMGXX"
AC_SUBST(LLVMGCCCOMMAND,$LLVMGCCCOMMAND)
AC_SUBST(LLVMGXXCOMMAND,$LLVMGXXCOMMAND)
AC_PATH_PROG(LLVMGCC, $LLVMGCC, [])
AC_PATH_PROG(LLVMGXX, $LLVMGXX, [])
else
if test -z "$LLVMGCC"; then
LLVMGCC="$WITH_LLVMGCCDIR/bin/llvm-gcc${EXEEXT}"
LLVMGCCCOMMAND="$LLVMGCC"
fi
if test -z "$LLVMGXX"; then
LLVMGXX="$WITH_LLVMGCCDIR/bin/llvm-g++${EXEEXT}"
LLVMGXXCOMMAND="$LLVMGXX"
fi
AC_SUBST(LLVMGCC,$LLVMGCC)
AC_SUBST(LLVMGXX,$LLVMGXX)
AC_SUBST(LLVMGCCCOMMAND,$LLVMGCCCOMMAND)
AC_SUBST(LLVMGXXCOMMAND,$LLVMGXXCOMMAND)
fi
dnl Select the LLVM capable compiler to use, we default to using llvm-gcc if
dnl found, otherwise clang if available.
AC_ARG_WITH(llvmcc,
AS_HELP_STRING([--with-llvmcc=<name>],
[Choose the LLVM capable compiler to use (llvm-gcc, clang, or none; default=check)]),
[],[with_llvmcc=check])
AC_MSG_CHECKING([LLVM capable compiler])
if test "$with_llvmcc" != "check"; then
if (test "$with_llvmcc" != "llvm-gcc" &&
test "$with_llvmcc" != "clang" &&
test "$with_llvmcc" != "none"); then
AC_MSG_ERROR([invalid value for --with-llvmcc, expected 'llvm-gcc', 'clang', or 'none'.])
fi
WITH_LLVMCC="$with_llvmcc"
elif test -n "$LLVMGCC"; then
WITH_LLVMCC=llvm-gcc
elif test -n "$WITH_CLANGPATH" || test "$WITH_BUILT_CLANG" -ne "0"; then
WITH_LLVMCC=clang
else
WITH_LLVMCC=none
fi
AC_MSG_RESULT([$WITH_LLVMCC])
AC_SUBST(LLVMCC_OPTION,$WITH_LLVMCC)
AC_MSG_CHECKING([tool compatibility])
dnl Ensure that compilation tools are GCC or a GNU compatible compiler such as
@ -1352,7 +1214,6 @@ dnl Generally we're looking for POSIX headers.
AC_HEADER_DIRENT
AC_HEADER_MMAP_ANONYMOUS
AC_HEADER_STAT
AC_HEADER_STDC
AC_HEADER_SYS_WAIT
AC_HEADER_TIME
@ -1512,9 +1373,9 @@ AC_LINK_IFELSE(
]]),
AC_LANG_POP([C++])
AC_MSG_RESULT(yes)
AC_DEFINE(LLVM_MULTITHREADED, 1, Build multithreading support into LLVM),
AC_DEFINE(LLVM_HAS_ATOMICS, 1, Has gcc/MSVC atomic intrinsics),
AC_MSG_RESULT(no)
AC_DEFINE(LLVM_MULTITHREADED, 0, Build multithreading support into LLVM)
AC_DEFINE(LLVM_HAS_ATOMICS, 0, Has gcc/MSVC atomic intrinsics)
AC_MSG_WARN([LLVM will be built thread-unsafe because atomic builtins are missing]))
dnl===-----------------------------------------------------------------------===
@ -1533,63 +1394,9 @@ if test "$llvm_cv_os_type" = "Linux" -a "$llvm_cv_target_arch" = "x86_64" ; then
fi
fi
dnl Check, whether __dso_handle is present
dnl Check whether __dso_handle is present
AC_CHECK_FUNCS([__dso_handle])
dnl Check wether llvm-gcc is based on dragonegg
AC_CACHE_CHECK([whether llvm-gcc is dragonegg],[llvm_cv_llvmgcc_dragonegg],
[llvm_cv_llvmgcc_dragonegg="no"
if test -n "$LLVMGCC" ; then
cp /dev/null conftest.c
$LLVMGCC -fplugin-arg-dragonegg-emit-ir -S -o - conftest.c > /dev/null 2>&1
if test $? -eq 0 ; then
llvm_cv_llvmgcc_dragonegg="yes"
fi
rm conftest.c
fi])
dnl Set the flags needed to emit LLVM IR and to disable optimizations
dnl in llvmgcc
if test "$llvm_cv_llvmgcc_dragonegg" = "yes" ; then
LLVMCC_EMITIR_FLAG="-fplugin-arg-dragonegg-emit-ir"
LLVMCC_DISABLEOPT_FLAGS="-fplugin-arg-dragonegg-llvm-ir-optimize=0"
else
LLVMCC_EMITIR_FLAG="-emit-llvm"
LLVMCC_DISABLEOPT_FLAGS="-mllvm -disable-llvm-optzns"
fi
AC_SUBST(LLVMCC_EMITIR_FLAG)
dnl See if the llvm-gcc executable can compile to LLVM assembly
AC_CACHE_CHECK([whether llvm-gcc is sane],[llvm_cv_llvmgcc_sanity],
[llvm_cv_llvmgcc_sanity="no"
if test -n "$LLVMGCC" ; then
cp /dev/null conftest.c
$LLVMGCC "$LLVMCC_EMITIR_FLAG" -S -o - conftest.c | \
grep 'target datalayout =' > /dev/null 2>&1
if test $? -eq 0 ; then
llvm_cv_llvmgcc_sanity="yes"
fi
rm conftest.c
fi])
dnl Since we have a sane llvm-gcc, identify it and its sub-tools
dnl Furthermore, add some information about the tools
if test "$llvm_cv_llvmgcc_sanity" = "yes" ; then
AC_MSG_CHECKING([llvm-gcc component support])
llvmcc1path=`$LLVMGCC --print-prog-name=cc1`
AC_SUBST(LLVMCC1,$llvmcc1path)
llvmcc1pluspath=`$LLVMGCC --print-prog-name=cc1plus`
AC_SUBST(LLVMCC1PLUS,$llvmcc1pluspath)
llvmgccdir=`echo "$llvmcc1path" | sed 's,/libexec/.*,,'`
AC_SUBST(LLVMGCCDIR,$llvmgccdir)
llvmgcclangs=[`$LLVMGCC -v --help 2>&1 | grep '^Configured with:' | sed 's/^.*--enable-languages=\([^ ]*\).*/\1/'`]
AC_SUBST(LLVMGCC_LANGS,$llvmgcclangs)
AC_SUBST(LLVMGCC_DRAGONEGG,$llvm_cv_llvmgcc_dragonegg)
AC_SUBST(LLVMCC_DISABLEOPT_FLAGS)
AC_MSG_RESULT([ok])
fi
dnl Propagate the shared library extension that the libltdl checks did to
dnl the Makefiles so we can use it there too
AC_SUBST(SHLIBEXT,$libltdl_cv_shlibext)
@ -1753,12 +1560,12 @@ if test -f ${srcdir}/tools/clang/README.txt; then
AC_CONFIG_FILES([tools/clang/docs/doxygen.cfg])
fi
dnl Configure llvmc's Base plugin
AC_CONFIG_FILES([tools/llvmc/src/Base.td])
dnl Do the first stage of configuration for llvm-config.in.
AC_CONFIG_FILES([tools/llvm-config/llvm-config.in])
dnl OCaml findlib META file
AC_CONFIG_FILES([bindings/ocaml/llvm/META.llvm])
dnl Do special configuration of Makefiles
AC_CONFIG_COMMANDS([setup],,[llvm_src="${srcdir}"])
AC_CONFIG_MAKEFILE(Makefile)

View File

@ -0,0 +1,63 @@
name = "llvm"
version = "@PACKAGE_VERSION@"
description = "Low Level Virtual Machine OCaml bindings"
archive(byte) = "llvm.cma"
archive(native) = "llvm.cmxa"
directory = "."
linkopts = "-ccopt -lstdc++"
package "analysis" (
requires = "llvm"
version = "@PACKAGE_VERSION@"
description = "Intermediate representation analysis for LLVM"
archive(byte) = "llvm_analysis.cma"
archive(native) = "llvm_analysis.cmxa"
)
package "bitreader" (
requires = "llvm"
version = "@PACKAGE_VERSION@"
description = "Bitcode reader for LLVM"
archive(byte) = "llvm_bitreader.cma"
archive(native) = "llvm_bitreader.cmxa"
)
package "bitwriter" (
requires = "llvm,unix"
version = "@PACKAGE_VERSION@"
description = "Bitcode writer for LLVM"
archive(byte) = "llvm_bitwriter.cma"
archive(native) = "llvm_bitwriter.cmxa"
)
package "executionengine" (
requires = "llvm,llvm.target"
version = "@PACKAGE_VERSION@"
description = "JIT and Interpreter for LLVM"
archive(byte) = "llvm_executionengine.cma"
archive(native) = "llvm_executionengine.cmxa"
)
package "ipo" (
requires = "llvm"
version = "@PACKAGE_VERSION@"
description = "IPO Transforms for LLVM"
archive(byte) = "llvm_ipo.cma"
archive(native) = "llvm_ipo.cmxa"
)
package "scalar_opts" (
requires = "llvm"
version = "@PACKAGE_VERSION@"
description = "Scalar Transforms for LLVM"
archive(byte) = "llvm_scalar_opts.cma"
archive(native) = "llvm_scalar_opts.cmxa"
)
package "target" (
requires = "llvm"
version = "@PACKAGE_VERSION@"
description = "Target Information for LLVM"
archive(byte) = "llvm_target.cma"
archive(native) = "llvm_target.cmxa"
)

View File

@ -17,3 +17,24 @@ UsedComponents := core
UsedOcamLibs := llvm
include ../Makefile.ocaml
all-local:: copy-meta
install-local:: install-meta
uninstall-local:: uninstall-meta
DestMETA := $(PROJ_libocamldir)/META.llvm
# Easy way of generating META in the objdir
copy-meta: $(OcamlDir)/META.llvm
$(OcamlDir)/META.llvm: META.llvm
$(Verb) $(CP) -f $< $@
install-meta:: $(ObjDir)/META.llvm
$(Echo) "Install $(BuildMode) $(DestMETA)"
$(Verb) $(MKDIR) $(PROJ_libocamldir)
$(Verb) $(DataInstall) META.llvm "$(DestMETA)"
uninstall-meta::
$(Echo) "Uninstalling $(DestMETA)"
-$(Verb) $(RM) -f "$(DestMETA)"

View File

@ -94,6 +94,9 @@ module Attribute = struct
| Naked
| Inlinehint
| Stackalignment of int
| ReturnsTwice
| UWTable
| NonLazyBind
end
module Icmp = struct
@ -130,6 +133,101 @@ module Fcmp = struct
| True
end
module Opcode = struct
type t =
| Invalid (* not an instruction *)
(* Terminator Instructions *)
| Ret
| Br
| Switch
| IndirectBr
| Invoke
| Invalid2
| Unreachable
(* Standard Binary Operators *)
| Add
| FAdd
| Sub
| FSub
| Mul
| FMul
| UDiv
| SDiv
| FDiv
| URem
| SRem
| FRem
(* Logical Operators *)
| Shl
| LShr
| AShr
| And
| Or
| Xor
(* Memory Operators *)
| Alloca
| Load
| Store
| GetElementPtr
(* Cast Operators *)
| Trunc
| ZExt
| SExt
| FPToUI
| FPToSI
| UIToFP
| SIToFP
| FPTrunc
| FPExt
| PtrToInt
| IntToPtr
| BitCast
(* Other Operators *)
| ICmp
| FCmp
| PHI
| Call
| Select
| UserOp1
| UserOp2
| VAArg
| ExtractElement
| InsertElement
| ShuffleVector
| ExtractValue
| InsertValue
| Fence
| AtomicCmpXchg
| AtomicRMW
| Resume
| LandingPad
| Unwind
end
module ValueKind = struct
type t =
| NullValue
| Argument
| BasicBlock
| InlineAsm
| MDNode
| MDString
| BlockAddress
| ConstantAggregateZero
| ConstantArray
| ConstantExpr
| ConstantFP
| ConstantInt
| ConstantPointerNull
| ConstantStruct
| ConstantVector
| Function
| GlobalAlias
| GlobalVariable
| UndefValue
| Instruction of Opcode.t
end
exception IoError of string
external register_exns : exn -> unit = "llvm_register_core_exns"
@ -163,10 +261,12 @@ external set_data_layout: string -> llmodule -> unit
external dump_module : llmodule -> unit = "llvm_dump_module"
external set_module_inline_asm : llmodule -> string -> unit
= "llvm_set_module_inline_asm"
external module_context : llmodule -> llcontext = "LLVMGetModuleContext"
(*===-- Types -------------------------------------------------------------===*)
external classify_type : lltype -> TypeKind.t = "llvm_classify_type"
external type_context : lltype -> llcontext = "llvm_type_context"
external type_is_sized : lltype -> bool = "llvm_type_is_sized"
(*--... Operations on integer types ........................................--*)
external i1_type : llcontext -> lltype = "llvm_i1_type"
@ -197,9 +297,15 @@ external param_types : lltype -> lltype array = "llvm_param_types"
external struct_type : llcontext -> lltype array -> lltype = "llvm_struct_type"
external packed_struct_type : llcontext -> lltype array -> lltype
= "llvm_packed_struct_type"
external struct_name : lltype -> string option = "llvm_struct_name"
external named_struct_type : llcontext -> string -> lltype =
"llvm_named_struct_type"
external struct_set_body : lltype -> lltype array -> bool -> unit =
"llvm_struct_set_body"
external struct_element_types : lltype -> lltype array
= "llvm_struct_element_types"
external is_packed : lltype -> bool = "llvm_is_packed"
external is_opaque : lltype -> bool = "llvm_is_opaque"
(*--... Operations on pointer, vector, and array types .....................--*)
external array_type : lltype -> int -> lltype = "llvm_array_type"
@ -216,7 +322,9 @@ external vector_size : lltype -> int = "llvm_vector_size"
(*--... Operations on other types ..........................................--*)
external void_type : llcontext -> lltype = "llvm_void_type"
external label_type : llcontext -> lltype = "llvm_label_type"
external type_by_name : llmodule -> string -> lltype option = "llvm_type_by_name"
external classify_value : llvalue -> ValueKind.t = "llvm_classify_value"
(*===-- Values ------------------------------------------------------------===*)
external type_of : llvalue -> lltype = "llvm_type_of"
external value_name : llvalue -> string = "llvm_value_name"
@ -270,6 +378,7 @@ external const_pointer_null : lltype -> llvalue = "LLVMConstPointerNull"
external undef : lltype -> llvalue = "LLVMGetUndef"
external is_null : llvalue -> bool = "llvm_is_null"
external is_undef : llvalue -> bool = "llvm_is_undef"
external constexpr_opcode : llvalue -> Opcode.t = "llvm_constexpr_get_opcode"
(*--... Operations on instructions .........................................--*)
external has_metadata : llvalue -> bool = "llvm_has_metadata"
@ -280,11 +389,15 @@ external clear_metadata : llvalue -> int -> unit = "llvm_clear_metadata"
(*--... Operations on metadata .......,.....................................--*)
external mdstring : llcontext -> string -> llvalue = "llvm_mdstring"
external mdnode : llcontext -> llvalue array -> llvalue = "llvm_mdnode"
external get_mdstring : llvalue -> string option = "llvm_get_mdstring"
external get_named_metadata : llmodule -> string -> llvalue array = "llvm_get_namedmd"
(*--... Operations on scalar constants .....................................--*)
external const_int : lltype -> int -> llvalue = "llvm_const_int"
external const_of_int64 : lltype -> Int64.t -> bool -> llvalue
= "llvm_const_of_int64"
external int64_of_const : llvalue -> Int64.t option
= "llvm_int64_of_const"
external const_int_of_string : lltype -> string -> int -> llvalue
= "llvm_const_int_of_string"
external const_float : lltype -> float -> llvalue = "llvm_const_float"
@ -297,6 +410,8 @@ external const_stringz : llcontext -> string -> llvalue = "llvm_const_stringz"
external const_array : lltype -> llvalue array -> llvalue = "llvm_const_array"
external const_struct : llcontext -> llvalue array -> llvalue
= "llvm_const_struct"
external const_named_struct : lltype -> llvalue array -> llvalue
= "llvm_const_named_struct"
external const_packed_struct : llcontext -> llvalue array -> llvalue
= "llvm_const_packed_struct"
external const_vector : llvalue array -> llvalue = "llvm_const_vector"
@ -530,36 +645,81 @@ let rec fold_right_function_range f i e init =
let fold_right_functions f m init =
fold_right_function_range f (function_end m) (At_start m) init
external llvm_add_function_attr : llvalue -> int -> unit
external llvm_add_function_attr : llvalue -> int32 -> unit
= "llvm_add_function_attr"
external llvm_remove_function_attr : llvalue -> int -> unit
external llvm_remove_function_attr : llvalue -> int32 -> unit
= "llvm_remove_function_attr"
external llvm_function_attr : llvalue -> int32 = "llvm_function_attr"
let pack_attr (attr:Attribute.t) : int =
let pack_attr (attr:Attribute.t) : int32 =
match attr with
Attribute.Zext -> 1 lsl 0
| Attribute.Sext -> 1 lsl 1
| Attribute.Noreturn -> 1 lsl 2
| Attribute.Inreg -> 1 lsl 3
| Attribute.Structret -> 1 lsl 4
| Attribute.Nounwind -> 1 lsl 5
| Attribute.Noalias -> 1 lsl 6
| Attribute.Byval -> 1 lsl 7
| Attribute.Nest -> 1 lsl 8
| Attribute.Readnone -> 1 lsl 9
| Attribute.Readonly -> 1 lsl 10
| Attribute.Noinline -> 1 lsl 11
| Attribute.Alwaysinline -> 1 lsl 12
| Attribute.Optsize -> 1 lsl 13
| Attribute.Ssp -> 1 lsl 14
| Attribute.Sspreq -> 1 lsl 15
| Attribute.Alignment n -> n lsl 16
| Attribute.Nocapture -> 1 lsl 21
| Attribute.Noredzone -> 1 lsl 22
| Attribute.Noimplicitfloat -> 1 lsl 23
| Attribute.Naked -> 1 lsl 24
| Attribute.Inlinehint -> 1 lsl 25
| Attribute.Stackalignment n -> n lsl 26
Attribute.Zext -> Int32.shift_left 1l 0
| Attribute.Sext -> Int32.shift_left 1l 1
| Attribute.Noreturn -> Int32.shift_left 1l 2
| Attribute.Inreg -> Int32.shift_left 1l 3
| Attribute.Structret -> Int32.shift_left 1l 4
| Attribute.Nounwind -> Int32.shift_left 1l 5
| Attribute.Noalias -> Int32.shift_left 1l 6
| Attribute.Byval -> Int32.shift_left 1l 7
| Attribute.Nest -> Int32.shift_left 1l 8
| Attribute.Readnone -> Int32.shift_left 1l 9
| Attribute.Readonly -> Int32.shift_left 1l 10
| Attribute.Noinline -> Int32.shift_left 1l 11
| Attribute.Alwaysinline -> Int32.shift_left 1l 12
| Attribute.Optsize -> Int32.shift_left 1l 13
| Attribute.Ssp -> Int32.shift_left 1l 14
| Attribute.Sspreq -> Int32.shift_left 1l 15
| Attribute.Alignment n -> Int32.shift_left (Int32.of_int n) 16
| Attribute.Nocapture -> Int32.shift_left 1l 21
| Attribute.Noredzone -> Int32.shift_left 1l 22
| Attribute.Noimplicitfloat -> Int32.shift_left 1l 23
| Attribute.Naked -> Int32.shift_left 1l 24
| Attribute.Inlinehint -> Int32.shift_left 1l 25
| Attribute.Stackalignment n -> Int32.shift_left (Int32.of_int n) 26
| Attribute.ReturnsTwice -> Int32.shift_left 1l 29
| Attribute.UWTable -> Int32.shift_left 1l 30
| Attribute.NonLazyBind -> Int32.shift_left 1l 31
let unpack_attr (a : int32) : Attribute.t list =
let l = ref [] in
let check attr =
Int32.logand (pack_attr attr) a in
let checkattr attr =
if (check attr) <> 0l then begin
l := attr :: !l
end
in
checkattr Attribute.Zext;
checkattr Attribute.Sext;
checkattr Attribute.Noreturn;
checkattr Attribute.Inreg;
checkattr Attribute.Structret;
checkattr Attribute.Nounwind;
checkattr Attribute.Noalias;
checkattr Attribute.Byval;
checkattr Attribute.Nest;
checkattr Attribute.Readnone;
checkattr Attribute.Readonly;
checkattr Attribute.Noinline;
checkattr Attribute.Alwaysinline;
checkattr Attribute.Optsize;
checkattr Attribute.Ssp;
checkattr Attribute.Sspreq;
let align = Int32.logand (Int32.shift_right_logical a 16) 31l in
if align <> 0l then
l := Attribute.Alignment (Int32.to_int align) :: !l;
checkattr Attribute.Nocapture;
checkattr Attribute.Noredzone;
checkattr Attribute.Noimplicitfloat;
checkattr Attribute.Naked;
checkattr Attribute.Inlinehint;
let stackalign = Int32.logand (Int32.shift_right_logical a 26) 7l in
if stackalign <> 0l then
l := Attribute.Stackalignment (Int32.to_int stackalign) :: !l;
checkattr Attribute.ReturnsTwice;
checkattr Attribute.UWTable;
checkattr Attribute.NonLazyBind;
!l;;
let add_function_attr llval attr =
llvm_add_function_attr llval (pack_attr attr)
@ -567,9 +727,13 @@ let add_function_attr llval attr =
let remove_function_attr llval attr =
llvm_remove_function_attr llval (pack_attr attr)
let function_attr f = unpack_attr (llvm_function_attr f)
(*--... Operations on params ...............................................--*)
external params : llvalue -> llvalue array = "llvm_params"
external param : llvalue -> int -> llvalue = "llvm_param"
external llvm_param_attr : llvalue -> int32 = "llvm_param_attr"
let param_attr p = unpack_attr (llvm_param_attr p)
external param_parent : llvalue -> llvalue = "LLVMGetParamParent"
external param_begin : llvalue -> (llvalue, llvalue) llpos = "llvm_param_begin"
external param_succ : llvalue -> (llvalue, llvalue) llpos = "llvm_param_succ"
@ -616,9 +780,9 @@ let rec fold_right_param_range f init i e =
let fold_right_params f fn init =
fold_right_param_range f init (param_end fn) (At_start fn)
external llvm_add_param_attr : llvalue -> int -> unit
external llvm_add_param_attr : llvalue -> int32 -> unit
= "llvm_add_param_attr"
external llvm_remove_param_attr : llvalue -> int -> unit
external llvm_remove_param_attr : llvalue -> int32 -> unit
= "llvm_remove_param_attr"
let add_param_attr llval attr =
@ -650,6 +814,8 @@ external block_end : llvalue -> (llvalue, llbasicblock) llrev_pos
= "llvm_block_end"
external block_pred : llbasicblock -> (llvalue, llbasicblock) llrev_pos
= "llvm_block_pred"
external block_terminator : llbasicblock -> llvalue option =
"llvm_block_terminator"
let rec iter_block_range f i e =
if i = e then () else
@ -702,6 +868,11 @@ external instr_end : llbasicblock -> (llbasicblock, llvalue) llrev_pos
external instr_pred : llvalue -> (llbasicblock, llvalue) llrev_pos
= "llvm_instr_pred"
external instr_opcode : llvalue -> Opcode.t = "llvm_instr_get_opcode"
external icmp_predicate : llvalue -> Icmp.t option = "llvm_instr_icmp_predicate"
external icmp_predicate : llvalue -> Icmp.t option = "llvm_instr_icmp_predicate"
let rec iter_instrs_range f i e =
if i = e then () else
match i with
@ -749,9 +920,9 @@ external instruction_call_conv: llvalue -> int
external set_instruction_call_conv: int -> llvalue -> unit
= "llvm_set_instruction_call_conv"
external llvm_add_instruction_param_attr : llvalue -> int -> int -> unit
external llvm_add_instruction_param_attr : llvalue -> int -> int32 -> unit
= "llvm_add_instruction_param_attr"
external llvm_remove_instruction_param_attr : llvalue -> int -> int -> unit
external llvm_remove_instruction_param_attr : llvalue -> int -> int32 -> unit
= "llvm_remove_instruction_param_attr"
let add_instruction_param_attr llval i attr =
@ -769,6 +940,7 @@ external add_incoming : (llvalue * llbasicblock) -> llvalue -> unit
= "llvm_add_incoming"
external incoming : llvalue -> (llvalue * llbasicblock) list = "llvm_incoming"
external delete_instruction : llvalue -> unit = "llvm_delete_instruction"
(*===-- Instruction builders ----------------------------------------------===*)
external builder : llcontext -> llbuilder = "llvm_builder"
@ -811,8 +983,15 @@ external build_cond_br : llvalue -> llbasicblock -> llbasicblock -> llbuilder ->
llvalue = "llvm_build_cond_br"
external build_switch : llvalue -> llbasicblock -> int -> llbuilder -> llvalue
= "llvm_build_switch"
external build_malloc : lltype -> string -> llbuilder -> llvalue =
"llvm_build_malloc"
external build_array_malloc : lltype -> llvalue -> string -> llbuilder ->
llvalue = "llvm_build_array_malloc"
external build_free : llvalue -> llbuilder -> llvalue = "llvm_build_free"
external add_case : llvalue -> llvalue -> llbasicblock -> unit
= "llvm_add_case"
external switch_default_dest : llvalue -> llbasicblock =
"LLVMGetSwitchDefaultDest"
external build_indirect_br : llvalue -> int -> llbuilder -> llvalue
= "llvm_build_indirect_br"
external add_destination : llvalue -> llbasicblock -> unit
@ -820,7 +999,11 @@ external add_destination : llvalue -> llbasicblock -> unit
external build_invoke : llvalue -> llvalue array -> llbasicblock ->
llbasicblock -> string -> llbuilder -> llvalue
= "llvm_build_invoke_bc" "llvm_build_invoke_nat"
external build_unwind : llbuilder -> llvalue = "llvm_build_unwind"
external build_landingpad : lltype -> llvalue -> int -> string -> llbuilder ->
llvalue = "llvm_build_landingpad"
external set_cleanup : llvalue -> bool -> unit = "llvm_set_cleanup"
external add_clause : llvalue -> llvalue -> unit = "llvm_add_clause"
external build_resume : llvalue -> llbuilder -> llvalue = "llvm_build_resume"
external build_unreachable : llbuilder -> llvalue = "llvm_build_unreachable"
(*--... Arithmetic .........................................................--*)
@ -1022,7 +1205,14 @@ let rec string_of_lltype ty =
(* FIXME: stop infinite recursion! :) *)
match classify_type ty with
TypeKind.Integer -> "i" ^ string_of_int (integer_bitwidth ty)
| TypeKind.Pointer -> (string_of_lltype (element_type ty)) ^ "*"
| TypeKind.Pointer ->
(let ety = element_type ty in
match classify_type ety with
| TypeKind.Struct ->
(match struct_name ety with
| None -> (string_of_lltype ety)
| Some s -> s) ^ "*"
| _ -> (string_of_lltype (element_type ty)) ^ "*")
| TypeKind.Struct ->
let s = "{ " ^ (concat2 ", " (
Array.map string_of_lltype (struct_element_types ty)

View File

@ -139,6 +139,9 @@ module Attribute : sig
| Naked
| Inlinehint
| Stackalignment of int
| ReturnsTwice
| UWTable
| NonLazyBind
end
(** The predicate for an integer comparison ([icmp]) instruction.
@ -179,6 +182,103 @@ module Fcmp : sig
| True
end
(** The opcodes for LLVM instructions and constant expressions. *)
module Opcode : sig
type t =
| Invalid (* not an instruction *)
(* Terminator Instructions *)
| Ret
| Br
| Switch
| IndirectBr
| Invoke
| Invalid2
| Unreachable
(* Standard Binary Operators *)
| Add
| FAdd
| Sub
| FSub
| Mul
| FMul
| UDiv
| SDiv
| FDiv
| URem
| SRem
| FRem
(* Logical Operators *)
| Shl
| LShr
| AShr
| And
| Or
| Xor
(* Memory Operators *)
| Alloca
| Load
| Store
| GetElementPtr
(* Cast Operators *)
| Trunc
| ZExt
| SExt
| FPToUI
| FPToSI
| UIToFP
| SIToFP
| FPTrunc
| FPExt
| PtrToInt
| IntToPtr
| BitCast
(* Other Operators *)
| ICmp
| FCmp
| PHI
| Call
| Select
| UserOp1
| UserOp2
| VAArg
| ExtractElement
| InsertElement
| ShuffleVector
| ExtractValue
| InsertValue
| Fence
| AtomicCmpXchg
| AtomicRMW
| Resume
| LandingPad
| Unwind
end
(** The kind of an [llvalue], the result of [classify_value v].
* See the various [LLVMIsA*] functions. *)
module ValueKind : sig
type t =
| NullValue
| Argument
| BasicBlock
| InlineAsm
| MDNode
| MDString
| BlockAddress
| ConstantAggregateZero
| ConstantArray
| ConstantExpr
| ConstantFP
| ConstantInt
| ConstantPointerNull
| ConstantStruct
| ConstantVector
| Function
| GlobalAlias
| GlobalVariable
| UndefValue
| Instruction of Opcode.t
end
(** {6 Iteration} *)
@ -263,7 +363,9 @@ val dump_module : llmodule -> unit
the method [llvm::Module::setModuleInlineAsm]. *)
val set_module_inline_asm : llmodule -> string -> unit
(** [module_context m] returns the context of the specified module.
* See the method [llvm::Module::getContext] *)
val module_context : llmodule -> llcontext
(** {6 Types} *)
@ -271,6 +373,11 @@ val set_module_inline_asm : llmodule -> string -> unit
See the method [llvm::Type::getTypeID]. *)
val classify_type : lltype -> TypeKind.t
(** [type_is_sized ty] returns whether the type has a size or not.
* If it doesn't then it is not safe to call the [TargetData::] methods on it.
* *)
val type_is_sized : lltype -> bool
(** [type_context ty] returns the {!llcontext} corresponding to the type [ty].
See the method [llvm::Type::getContext]. *)
val type_context : lltype -> llcontext
@ -339,7 +446,7 @@ val ppc_fp128_type : llcontext -> lltype
See the method [llvm::FunctionType::get]. *)
val function_type : lltype -> lltype array -> lltype
(** [va_arg_function_type ret_ty param_tys] is just like
(** [var_arg_function_type ret_ty param_tys] is just like
[function_type ret_ty param_tys] except that it returns the function type
which also takes a variable number of arguments.
See the method [llvm::FunctionType::get]. *)
@ -372,6 +479,19 @@ val struct_type : llcontext -> lltype array -> lltype
[llvm::StructType::get]. *)
val packed_struct_type : llcontext -> lltype array -> lltype
(** [struct_name ty] returns the name of the named structure type [ty],
* or None if the structure type is not named *)
val struct_name : lltype -> string option
(** [named_struct_type context name] returns the named structure type [name]
* in the context [context].
* See the method [llvm::StructType::get]. *)
val named_struct_type : llcontext -> string -> lltype
(** [struct_set_body ty elts ispacked] sets the body of the named struct [ty]
* to the [elts] elements.
* See the moethd [llvm::StructType::setBody]. *)
val struct_set_body : lltype -> lltype array -> bool -> unit
(** [struct_element_types sty] returns the constituent types of the struct type
[sty]. See the method [llvm::StructType::getElementType]. *)
@ -382,6 +502,9 @@ val struct_element_types : lltype -> lltype array
[false] otherwise. See the method [llvm::StructType::isPacked]. *)
val is_packed : lltype -> bool
(** [is_opaque sty] returns [true] if the structure type [sty] is opaque.
[false] otherwise. See the method [llvm::StructType::isOpaque]. *)
val is_opaque : lltype -> bool
(** {7 Operations on pointer, vector, and array types} *)
@ -431,12 +554,19 @@ val void_type : llcontext -> lltype
[llvm::Type::LabelTy]. *)
val label_type : llcontext -> lltype
(** [type_by_name m name] returns the specified type from the current module
* if it exists.
* See the method [llvm::Module::getTypeByName] *)
val type_by_name : llmodule -> string -> lltype option
(* {6 Values} *)
(** [type_of v] returns the type of the value [v].
See the method [llvm::Value::getType]. *)
val type_of : llvalue -> lltype
val classify_value : llvalue -> ValueKind.t
(** [value_name v] returns the name of the value [v]. For global values, this is
the symbol name. For instructions and basic blocks, it is the SSA register
name. It is meaningless for constants.
@ -534,7 +664,7 @@ val is_null : llvalue -> bool
otherwise. Similar to [llvm::isa<UndefValue>]. *)
val is_undef : llvalue -> bool
val constexpr_opcode : llvalue -> Opcode.t
(** {7 Operations on instructions} *)
(** [has_metadata i] returns whether or not the instruction [i] has any
@ -567,6 +697,14 @@ val mdstring : llcontext -> string -> llvalue
See the method [llvm::MDNode::get]. *)
val mdnode : llcontext -> llvalue array -> llvalue
(** [get_mdstring v] returns the MDString.
* See the method [llvm::MDString::getString] *)
val get_mdstring : llvalue -> string option
(** [get_named_metadata m name] return all the MDNodes belonging to the named
* metadata (if any).
* See the method [llvm::NamedMDNode::getOperand]. *)
val get_named_metadata : llmodule -> string -> llvalue array
(** {7 Operations on scalar constants} *)
@ -578,6 +716,10 @@ val const_int : lltype -> int -> llvalue
[i]. See the method [llvm::ConstantInt::get]. *)
val const_of_int64 : lltype -> Int64.t -> bool -> llvalue
(** [int64_of_const c] returns the int64 value of the [c] constant integer.
* None is returned if this is not an integer constant, or bitwidth exceeds 64.
* See the method [llvm::ConstantInt::getSExtValue].*)
val int64_of_const : llvalue -> Int64.t option
(** [const_int_of_string ty s r] returns the integer constant of type [ty] and
* value [s], with the radix [r]. See the method [llvm::ConstantInt::get]. *)
@ -618,9 +760,14 @@ val const_array : lltype -> llvalue array -> llvalue
(** [const_struct context elts] returns the structured constant of type
[struct_type (Array.map type_of elts)] and containing the values [elts]
in the context [context]. This value can in turn be used as the initializer
for a global variable. See the method [llvm::ConstantStruct::get]. *)
for a global variable. See the method [llvm::ConstantStruct::getAnon]. *)
val const_struct : llcontext -> llvalue array -> llvalue
(** [const_named_struct namedty elts] returns the structured constant of type
[namedty] (which must be a named structure type) and containing the values [elts].
This value can in turn be used as the initializer
for a global variable. See the method [llvm::ConstantStruct::get]. *)
val const_named_struct : lltype -> llvalue array -> llvalue
(** [const_packed_struct context elts] returns the structured constant of
type {!packed_struct_type} [(Array.map type_of elts)] and containing the
@ -1231,6 +1378,10 @@ val set_gc : string option -> llvalue -> unit
[f]. *)
val add_function_attr : llvalue -> Attribute.t -> unit
(** [function_attr f] returns the function attribute for the function [f].
* See the method [llvm::Function::getAttributes] *)
val function_attr : llvalue -> Attribute.t list
(** [remove_function_attr f a] removes attribute [a] from the return type of
function [f]. *)
val remove_function_attr : llvalue -> Attribute.t -> unit
@ -1245,6 +1396,11 @@ val params : llvalue -> llvalue array
See the method [llvm::Function::getArgumentList]. *)
val param : llvalue -> int -> llvalue
(** [param_attr p] returns the attributes of parameter [p].
* See the methods [llvm::Function::getAttributes] and
* [llvm::Attributes::getParamAttributes] *)
val param_attr : llvalue -> Attribute.t list
(** [param_parent p] returns the parent function that owns the parameter.
See the method [llvm::Argument::getParent]. *)
val param_parent : llvalue -> llvalue
@ -1359,6 +1515,7 @@ val block_end : llvalue -> (llvalue, llbasicblock) llrev_pos
See the method [llvm::Function::iterator::operator--]. *)
val block_pred : llbasicblock -> (llvalue, llbasicblock) llrev_pos
val block_terminator : llbasicblock -> llvalue option
(** [rev_iter_blocks f fn] applies function [f] to each of the basic blocks
of function [fn] in reverse order. Tail recursive. *)
@ -1422,6 +1579,9 @@ val instr_pred : llvalue -> (llbasicblock, llvalue) llrev_pos
[f1,...,fN] are the instructions of basic block [bb]. Tail recursive. *)
val fold_right_instrs: (llvalue -> 'a -> 'a) -> llbasicblock -> 'a -> 'a
val instr_opcode : llvalue -> Opcode.t
val icmp_predicate : llvalue -> Icmp.t option
(** {7 Operations on call sites} *)
@ -1473,7 +1633,9 @@ val add_incoming : (llvalue * llbasicblock) -> llvalue -> unit
See the method [llvm::PHINode::getIncomingValue]. *)
val incoming : llvalue -> (llvalue * llbasicblock) list
(** [delete_instruction i] deletes the instruction [i].
* See the method [llvm::Instruction::eraseFromParent]. *)
val delete_instruction : llvalue -> unit
(** {6 Instruction builders} *)
@ -1587,12 +1749,30 @@ val build_cond_br : llvalue -> llbasicblock -> llbasicblock -> llbuilder ->
See the method [llvm::LLVMBuilder::CreateSwitch]. *)
val build_switch : llvalue -> llbasicblock -> int -> llbuilder -> llvalue
(** [build_malloc ty name b] creates an [malloc]
instruction at the position specified by the instruction builder [b].
See the method [llvm::CallInst::CreateMalloc]. *)
val build_malloc : lltype -> string -> llbuilder -> llvalue
(** [build_array_malloc ty val name b] creates an [array malloc]
instruction at the position specified by the instruction builder [b].
See the method [llvm::CallInst::CreateArrayMalloc]. *)
val build_array_malloc : lltype -> llvalue -> string -> llbuilder -> llvalue
(** [build_free p b] creates a [free]
instruction at the position specified by the instruction builder [b].
See the method [llvm::LLVMBuilder::CreateFree]. *)
val build_free : llvalue -> llbuilder -> llvalue
(** [add_case sw onval bb] causes switch instruction [sw] to branch to [bb]
when its input matches the constant [onval].
See the method [llvm::SwitchInst::addCase]. **)
val add_case : llvalue -> llvalue -> llbasicblock -> unit
(** [switch_default_dest sw] returns the default destination of the [switch]
* instruction.
* See the method [llvm:;SwitchInst::getDefaultDest]. **)
val switch_default_dest : llvalue -> llbasicblock
(** [build_indirect_br addr count b] creates a
[indirectbr %addr]
@ -1615,12 +1795,25 @@ val add_destination : llvalue -> llbasicblock -> unit
val build_invoke : llvalue -> llvalue array -> llbasicblock ->
llbasicblock -> string -> llbuilder -> llvalue
(** [build_unwind b] creates an
[unwind]
(** [build_landingpad ty persfn numclauses name b] creates an
[landingpad]
instruction at the position specified by the instruction builder [b].
See the method [llvm::LLVMBuilder::CreateUnwind]. *)
val build_unwind : llbuilder -> llvalue
See the method [llvm::LLVMBuilder::CreateLandingPad]. *)
val build_landingpad : lltype -> llvalue -> int -> string -> llbuilder ->
llvalue
(** [set_cleanup lp] sets the cleanup flag in the [landingpad]instruction.
See the method [llvm::LandingPadInst::setCleanup]. *)
val set_cleanup : llvalue -> bool -> unit
(** [add_clause lp clause] adds the clause to the [landingpad]instruction.
See the method [llvm::LandingPadInst::addClause]. *)
val add_clause : llvalue -> llvalue -> unit
(* [build_resume exn b] builds a [resume exn] instruction
* at the position specified by the instruction builder [b].
* See the method [llvm::LLVMBuilder::CreateResume] *)
val build_resume : llvalue -> llbuilder -> llvalue
(** [build_unreachable b] creates an
[unreachable]

View File

@ -24,6 +24,7 @@
#include "llvm/Config/config.h"
#include <assert.h>
#include <stdlib.h>
#include <string.h>
/* Can't use the recommended caml_named_value mechanism for backwards
@ -171,6 +172,10 @@ CAMLprim value llvm_classify_type(LLVMTypeRef Ty) {
return Val_int(LLVMGetTypeKind(Ty));
}
CAMLprim value llvm_type_is_sized(LLVMTypeRef Ty) {
return Val_bool(LLVMTypeIsSized(Ty));
}
/* lltype -> llcontext */
CAMLprim LLVMContextRef llvm_type_context(LLVMTypeRef Ty) {
return LLVMGetTypeContext(Ty);
@ -287,6 +292,34 @@ CAMLprim LLVMTypeRef llvm_packed_struct_type(LLVMContextRef C,
Wosize_val(ElementTypes), 1);
}
/* llcontext -> string -> lltype */
CAMLprim LLVMTypeRef llvm_named_struct_type(LLVMContextRef C,
value Name) {
return LLVMStructCreateNamed(C, String_val(Name));
}
CAMLprim value llvm_struct_set_body(LLVMTypeRef Ty,
value ElementTypes,
value Packed) {
LLVMStructSetBody(Ty, (LLVMTypeRef *) ElementTypes,
Wosize_val(ElementTypes), Bool_val(Packed));
return Val_unit;
}
/* lltype -> string option */
CAMLprim value llvm_struct_name(LLVMTypeRef Ty)
{
CAMLparam0();
const char *C = LLVMGetStructName(Ty);
if (C) {
CAMLlocal1(result);
result = caml_alloc_small(1, 0);
Store_field(result, 0, caml_copy_string(C));
CAMLreturn(result);
}
CAMLreturn(Val_int(0));
}
/* lltype -> lltype array */
CAMLprim value llvm_struct_element_types(LLVMTypeRef StructTy) {
value Tys = alloc(LLVMCountStructElementTypes(StructTy), 0);
@ -299,6 +332,11 @@ CAMLprim value llvm_is_packed(LLVMTypeRef StructTy) {
return Val_bool(LLVMIsPackedStruct(StructTy));
}
/* lltype -> bool */
CAMLprim value llvm_is_opaque(LLVMTypeRef StructTy) {
return Val_bool(LLVMIsOpaqueStruct(StructTy));
}
/*--... Operations on array, pointer, and vector types .....................--*/
/* lltype -> int -> lltype */
@ -349,6 +387,18 @@ CAMLprim LLVMTypeRef llvm_label_type(LLVMContextRef Context) {
return LLVMLabelTypeInContext(Context);
}
CAMLprim value llvm_type_by_name(LLVMModuleRef M, value Name)
{
CAMLparam1(Name);
LLVMTypeRef Ty = LLVMGetTypeByName(M, String_val(Name));
if (Ty) {
value Option = alloc(1, 0);
Field(Option, 0) = (value) Ty;
CAMLreturn(Option);
}
CAMLreturn(Val_int(0));
}
/*===-- VALUES ------------------------------------------------------------===*/
/* llvalue -> lltype */
@ -356,6 +406,69 @@ CAMLprim LLVMTypeRef llvm_type_of(LLVMValueRef Val) {
return LLVMTypeOf(Val);
}
/* keep in sync with ValueKind.t */
enum ValueKind {
NullValue=0,
Argument,
BasicBlock,
InlineAsm,
MDNode,
MDString,
BlockAddress,
ConstantAggregateZero,
ConstantArray,
ConstantExpr,
ConstantFP,
ConstantInt,
ConstantPointerNull,
ConstantStruct,
ConstantVector,
Function,
GlobalAlias,
GlobalVariable,
UndefValue,
Instruction
};
/* llvalue -> ValueKind.t */
#define DEFINE_CASE(Val, Kind) \
do {if (LLVMIsA##Kind(Val)) CAMLreturn(Val_int(Kind));} while(0)
CAMLprim value llvm_classify_value(LLVMValueRef Val) {
CAMLparam0();
if (!Val)
CAMLreturn(Val_int(NullValue));
if (LLVMIsAConstant(Val)) {
DEFINE_CASE(Val, BlockAddress);
DEFINE_CASE(Val, ConstantAggregateZero);
DEFINE_CASE(Val, ConstantArray);
DEFINE_CASE(Val, ConstantExpr);
DEFINE_CASE(Val, ConstantFP);
DEFINE_CASE(Val, ConstantInt);
DEFINE_CASE(Val, ConstantPointerNull);
DEFINE_CASE(Val, ConstantStruct);
DEFINE_CASE(Val, ConstantVector);
}
if (LLVMIsAInstruction(Val)) {
CAMLlocal1(result);
result = caml_alloc_small(1, 0);
Store_field(result, 0, Val_int(LLVMGetInstructionOpcode(Val)));
CAMLreturn(result);
}
if (LLVMIsAGlobalValue(Val)) {
DEFINE_CASE(Val, Function);
DEFINE_CASE(Val, GlobalAlias);
DEFINE_CASE(Val, GlobalVariable);
}
DEFINE_CASE(Val, Argument);
DEFINE_CASE(Val, BasicBlock);
DEFINE_CASE(Val, InlineAsm);
DEFINE_CASE(Val, MDNode);
DEFINE_CASE(Val, MDString);
DEFINE_CASE(Val, UndefValue);
failwith("Unknown Value class");
}
/* llvalue -> string */
CAMLprim value llvm_value_name(LLVMValueRef Val) {
return copy_string(LLVMGetValueName(Val));
@ -408,6 +521,12 @@ CAMLprim value llvm_is_undef(LLVMValueRef Val) {
return Val_bool(LLVMIsUndef(Val));
}
/* llvalue -> Opcode.t */
CAMLprim value llvm_constexpr_get_opcode(LLVMValueRef Val) {
return LLVMIsAConstantExpr(Val) ?
Val_int(LLVMGetConstOpcode(Val)) : Val_int(0);
}
/*--... Operations on instructions .........................................--*/
/* llvalue -> bool */
@ -454,6 +573,32 @@ CAMLprim LLVMValueRef llvm_mdnode(LLVMContextRef C, value ElementVals) {
Wosize_val(ElementVals));
}
/* llvalue -> string option */
CAMLprim value llvm_get_mdstring(LLVMValueRef V) {
CAMLparam0();
const char *S;
unsigned Len;
if ((S = LLVMGetMDString(V, &Len))) {
CAMLlocal2(Option, Str);
Str = caml_alloc_string(Len);
memcpy(String_val(Str), S, Len);
Option = alloc(1,0);
Store_field(Option, 0, Str);
CAMLreturn(Option);
}
CAMLreturn(Val_int(0));
}
CAMLprim value llvm_get_namedmd(LLVMModuleRef M, value name)
{
CAMLparam1(name);
CAMLlocal1(Nodes);
Nodes = alloc(LLVMGetNamedMetadataNumOperands(M, String_val(name)), 0);
LLVMGetNamedMetadataOperands(M, String_val(name), (LLVMValueRef *) Nodes);
CAMLreturn(Nodes);
}
/*--... Operations on scalar constants .....................................--*/
/* lltype -> int -> llvalue */
@ -467,6 +612,19 @@ CAMLprim LLVMValueRef llvm_const_of_int64(LLVMTypeRef IntTy, value N,
return LLVMConstInt(IntTy, Int64_val(N), Bool_val(SExt));
}
/* llvalue -> Int64.t */
CAMLprim value llvm_int64_of_const(LLVMValueRef Const)
{
CAMLparam0();
if (LLVMIsAConstantInt(Const) &&
LLVMGetIntTypeWidth(LLVMTypeOf(Const)) <= 64) {
value Option = alloc(1, 0);
Field(Option, 0) = caml_copy_int64(LLVMConstIntGetSExtValue(Const));
CAMLreturn(Option);
}
CAMLreturn(Val_int(0));
}
/* lltype -> string -> int -> llvalue */
CAMLprim LLVMValueRef llvm_const_int_of_string(LLVMTypeRef IntTy, value S,
value Radix) {
@ -514,6 +672,11 @@ CAMLprim LLVMValueRef llvm_const_struct(LLVMContextRef C, value ElementVals) {
Wosize_val(ElementVals), 0);
}
/* lltype -> llvalue array -> llvalue */
CAMLprim LLVMValueRef llvm_const_named_struct(LLVMTypeRef Ty, value ElementVals) {
return LLVMConstNamedStruct(Ty, (LLVMValueRef *) Op_val(ElementVals), Wosize_val(ElementVals));
}
/* llcontext -> llvalue array -> llvalue */
CAMLprim LLVMValueRef llvm_const_packed_struct(LLVMContextRef C,
value ElementVals) {
@ -883,15 +1046,22 @@ CAMLprim value llvm_set_gc(value GC, LLVMValueRef Fn) {
return Val_unit;
}
/* llvalue -> Attribute.t -> unit */
/* llvalue -> int32 -> unit */
CAMLprim value llvm_add_function_attr(LLVMValueRef Arg, value PA) {
LLVMAddFunctionAttr(Arg, Int_val(PA));
LLVMAddFunctionAttr(Arg, Int32_val(PA));
return Val_unit;
}
/* llvalue -> Attribute.t -> unit */
/* llvalue -> int32 */
CAMLprim value llvm_function_attr(LLVMValueRef Fn)
{
CAMLparam0();
CAMLreturn(caml_copy_int32(LLVMGetFunctionAttr(Fn)));
}
/* llvalue -> int32 -> unit */
CAMLprim value llvm_remove_function_attr(LLVMValueRef Arg, value PA) {
LLVMRemoveFunctionAttr(Arg, Int_val(PA));
LLVMRemoveFunctionAttr(Arg, Int32_val(PA));
return Val_unit;
}
/*--... Operations on parameters ...........................................--*/
@ -903,6 +1073,13 @@ CAMLprim LLVMValueRef llvm_param(LLVMValueRef Fn, value Index) {
return LLVMGetParam(Fn, Int_val(Index));
}
/* llvalue -> int */
CAMLprim value llvm_param_attr(LLVMValueRef Param)
{
CAMLparam0();
CAMLreturn(caml_copy_int32(LLVMGetAttribute(Param)));
}
/* llvalue -> llvalue */
CAMLprim value llvm_params(LLVMValueRef Fn) {
value Params = alloc(LLVMCountParams(Fn), 0);
@ -910,15 +1087,15 @@ CAMLprim value llvm_params(LLVMValueRef Fn) {
return Params;
}
/* llvalue -> Attribute.t -> unit */
/* llvalue -> int32 -> unit */
CAMLprim value llvm_add_param_attr(LLVMValueRef Arg, value PA) {
LLVMAddAttribute(Arg, Int_val(PA));
LLVMAddAttribute(Arg, Int32_val(PA));
return Val_unit;
}
/* llvalue -> Attribute.t -> unit */
/* llvalue -> int32 -> unit */
CAMLprim value llvm_remove_param_attr(LLVMValueRef Arg, value PA) {
LLVMRemoveAttribute(Arg, Int_val(PA));
LLVMRemoveAttribute(Arg, Int32_val(PA));
return Val_unit;
}
@ -933,6 +1110,19 @@ CAMLprim value llvm_set_param_alignment(LLVMValueRef Arg, value align) {
DEFINE_ITERATORS(
block, BasicBlock, LLVMValueRef, LLVMBasicBlockRef, LLVMGetBasicBlockParent)
/* llbasicblock -> llvalue option */
CAMLprim value llvm_block_terminator(LLVMBasicBlockRef Block)
{
CAMLparam0();
LLVMValueRef Term = LLVMGetBasicBlockTerminator(Block);
if (Term) {
value Option = alloc(1, 0);
Field(Option, 0) = (value) Term;
CAMLreturn(Option);
}
CAMLreturn(Val_int(0));
}
/* llvalue -> llbasicblock array */
CAMLprim value llvm_basic_blocks(LLVMValueRef Fn) {
value MLArray = alloc(LLVMCountBasicBlocks(Fn), 0);
@ -968,6 +1158,28 @@ CAMLprim value llvm_value_is_block(LLVMValueRef Val) {
DEFINE_ITERATORS(instr, Instruction, LLVMBasicBlockRef, LLVMValueRef,
LLVMGetInstructionParent)
/* llvalue -> Opcode.t */
CAMLprim value llvm_instr_get_opcode(LLVMValueRef Inst) {
LLVMOpcode o;
if (!LLVMIsAInstruction(Inst))
failwith("Not an instruction");
o = LLVMGetInstructionOpcode(Inst);
assert (o <= LLVMUnwind );
return Val_int(o);
}
/* llvalue -> ICmp.t */
CAMLprim value llvm_instr_icmp_predicate(LLVMValueRef Val) {
CAMLparam0();
int x = LLVMGetICmpPredicate(Val);
if (x) {
value Option = alloc(1, 0);
Field(Option, 0) = Val_int(x - LLVMIntEQ);
CAMLreturn(Option);
}
CAMLreturn(Val_int(0));
}
/*--... Operations on call sites ...........................................--*/
@ -982,19 +1194,19 @@ CAMLprim value llvm_set_instruction_call_conv(value CC, LLVMValueRef Inst) {
return Val_unit;
}
/* llvalue -> int -> Attribute.t -> unit */
/* llvalue -> int -> int32 -> unit */
CAMLprim value llvm_add_instruction_param_attr(LLVMValueRef Instr,
value index,
value PA) {
LLVMAddInstrAttribute(Instr, Int_val(index), Int_val(PA));
LLVMAddInstrAttribute(Instr, Int_val(index), Int32_val(PA));
return Val_unit;
}
/* llvalue -> int -> Attribute.t -> unit */
/* llvalue -> int -> int32 -> unit */
CAMLprim value llvm_remove_instruction_param_attr(LLVMValueRef Instr,
value index,
value PA) {
LLVMRemoveInstrAttribute(Instr, Int_val(index), Int_val(PA));
LLVMRemoveInstrAttribute(Instr, Int_val(index), Int32_val(PA));
return Val_unit;
}
@ -1045,6 +1257,11 @@ CAMLprim value llvm_incoming(LLVMValueRef PhiNode) {
CAMLreturn(Tl);
}
/* llvalue -> unit */
CAMLprim value llvm_delete_instruction(LLVMValueRef Instruction) {
LLVMInstructionEraseFromParent(Instruction);
return Val_unit;
}
/*===-- Instruction builders ----------------------------------------------===*/
@ -1172,6 +1389,27 @@ CAMLprim LLVMValueRef llvm_build_switch(LLVMValueRef Of,
return LLVMBuildSwitch(Builder_val(B), Of, Else, Int_val(EstimatedCount));
}
/* lltype -> string -> llbuilder -> llvalue */
CAMLprim LLVMValueRef llvm_build_malloc(LLVMTypeRef Ty, value Name,
value B)
{
return LLVMBuildMalloc(Builder_val(B), Ty, String_val(Name));
}
/* lltype -> llvalue -> string -> llbuilder -> llvalue */
CAMLprim LLVMValueRef llvm_build_array_malloc(LLVMTypeRef Ty,
LLVMValueRef Val,
value Name, value B)
{
return LLVMBuildArrayMalloc(Builder_val(B), Ty, Val, String_val(Name));
}
/* llvalue -> llbuilder -> llvalue */
CAMLprim LLVMValueRef llvm_build_free(LLVMValueRef P, value B)
{
return LLVMBuildFree(Builder_val(B), P);
}
/* llvalue -> llvalue -> llbasicblock -> unit */
CAMLprim value llvm_add_case(LLVMValueRef Switch, LLVMValueRef OnVal,
LLVMBasicBlockRef Dest) {
@ -1212,9 +1450,33 @@ CAMLprim LLVMValueRef llvm_build_invoke_bc(value Args[], int NumArgs) {
Args[4], Args[5]);
}
/* llbuilder -> llvalue */
CAMLprim LLVMValueRef llvm_build_unwind(value B) {
return LLVMBuildUnwind(Builder_val(B));
/* lltype -> llvalue -> int -> string -> llbuilder -> llvalue */
CAMLprim LLVMValueRef llvm_build_landingpad(LLVMTypeRef Ty, LLVMValueRef PersFn,
value NumClauses, value Name,
value B) {
return LLVMBuildLandingPad(Builder_val(B), Ty, PersFn, Int_val(NumClauses),
String_val(Name));
}
/* llvalue -> llvalue -> unit */
CAMLprim value llvm_add_clause(LLVMValueRef LandingPadInst, LLVMValueRef ClauseVal)
{
LLVMAddClause(LandingPadInst, ClauseVal);
return Val_unit;
}
/* llvalue -> bool -> unit */
CAMLprim value llvm_set_cleanup(LLVMValueRef LandingPadInst, value flag)
{
LLVMSetCleanup(LandingPadInst, Bool_val(flag));
return Val_unit;
}
/* llvalue -> llbuilder -> llvalue */
CAMLprim LLVMValueRef llvm_build_resume(LLVMValueRef Exn, value B)
{
return LLVMBuildResume(Builder_val(B), Exn);
}
/* llbuilder -> llvalue */

View File

@ -20,8 +20,6 @@ module TargetData = struct
external add : t -> [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
= "llvm_targetdata_add"
external as_string : t -> string = "llvm_targetdata_as_string"
external invalidate_struct_layout : t -> Llvm.lltype -> unit
= "llvm_targetdata_invalidate_struct_layout"
external dispose : t -> unit = "llvm_targetdata_dispose"
end

View File

@ -35,13 +35,6 @@ module TargetData : sig
See the constructor llvm::TargetData::TargetData. *)
external as_string : t -> string = "llvm_targetdata_as_string"
(** Struct layouts are speculatively cached. If a TargetDataRef is alive when
types are being refined and removed, this method must be called whenever a
struct type is removed to avoid a dangling pointer in this cache.
See the method llvm::TargetData::InvalidateStructLayoutInfo. *)
external invalidate_struct_layout : t -> Llvm.lltype -> unit
= "llvm_targetdata_invalidate_struct_layout"
(** Deallocates a TargetData.
See the destructor llvm::TargetData::~TargetData. *)
external dispose : t -> unit = "llvm_targetdata_dispose"

View File

@ -37,13 +37,6 @@ CAMLprim value llvm_targetdata_as_string(LLVMTargetDataRef TD) {
return Copy;
}
/* TargetData.t -> Llvm.lltype -> unit */
CAMLprim value llvm_targetdata_invalidate_struct_layout(LLVMTargetDataRef TD,
LLVMTypeRef Ty) {
LLVMInvalidateStructLayout(TD, Ty);
return Val_unit;
}
/* TargetData.t -> unit */
CAMLprim value llvm_targetdata_dispose(LLVMTargetDataRef TD) {
LLVMDisposeTargetData(TD);

View File

@ -8,7 +8,7 @@
##===----------------------------------------------------------------------===##
LEVEL := ../../..
DIRS = scalar
DIRS = scalar ipo
ocamldoc:
$(Verb) for i in $(DIRS) ; do \

View File

@ -0,0 +1,20 @@
##===- bindings/ocaml/transforms/scalar/Makefile -----------*- Makefile -*-===##
#
# The LLVM Compiler Infrastructure
#
# This file is distributed under the University of Illinois Open Source
# License. See LICENSE.TXT for details.
#
##===----------------------------------------------------------------------===##
#
# This is the makefile for the Objective Caml Llvm_scalar_opts interface.
#
##===----------------------------------------------------------------------===##
LEVEL := ../../../..
LIBRARYNAME := llvm_ipo
DONT_BUILD_RELINKED := 1
UsedComponents := ipo
UsedOcamlInterfaces := llvm
include ../../Makefile.ocaml

View File

@ -0,0 +1,104 @@
/*===-- ipo_ocaml.c - LLVM Ocaml Glue -------------------*- C++ -*-===*\
|* *|
|* The LLVM Compiler Infrastructure *|
|* *|
|* This file is distributed under the University of Illinois Open Source *|
|* License. See LICENSE.TXT for details. *|
|* *|
|*===----------------------------------------------------------------------===*|
|* *|
|* This file glues LLVM's ocaml interface to its C interface. These functions *|
|* are by and large transparent wrappers to the corresponding C functions. *|
|* *|
|* Note that these functions intentionally take liberties with the CAMLparamX *|
|* macros, since most of the parameters are not GC heap objects. *|
|* *|
\*===----------------------------------------------------------------------===*/
#include "llvm-c/Transforms/IPO.h"
#include "caml/mlvalues.h"
#include "caml/misc.h"
/* [`Module] Llvm.PassManager.t -> unit */
CAMLprim value llvm_add_argument_promotion(LLVMPassManagerRef PM) {
LLVMAddArgumentPromotionPass(PM);
return Val_unit;
}
/* [`Module] Llvm.PassManager.t -> unit */
CAMLprim value llvm_add_constant_merge(LLVMPassManagerRef PM) {
LLVMAddConstantMergePass(PM);
return Val_unit;
}
/* [`Module] Llvm.PassManager.t -> unit */
CAMLprim value llvm_add_dead_arg_elimination(LLVMPassManagerRef PM) {
LLVMAddDeadArgEliminationPass(PM);
return Val_unit;
}
/* [`Module] Llvm.PassManager.t -> unit */
CAMLprim value llvm_add_function_attrs(LLVMPassManagerRef PM) {
LLVMAddFunctionAttrsPass(PM);
return Val_unit;
}
/* [`Module] Llvm.PassManager.t -> unit */
CAMLprim value llvm_add_function_inlining(LLVMPassManagerRef PM) {
LLVMAddFunctionInliningPass(PM);
return Val_unit;
}
/* [`Module] Llvm.PassManager.t -> unit */
CAMLprim value llvm_add_always_inliner_pass(LLVMPassManagerRef PM) {
LLVMAddAlwaysInlinerPass(PM);
return Val_unit;
}
/* [`Module] Llvm.PassManager.t -> unit */
CAMLprim value llvm_add_global_dce(LLVMPassManagerRef PM) {
LLVMAddGlobalDCEPass(PM);
return Val_unit;
}
/* [`Module] Llvm.PassManager.t -> unit */
CAMLprim value llvm_add_global_optimizer(LLVMPassManagerRef PM) {
LLVMAddGlobalOptimizerPass(PM);
return Val_unit;
}
/* [`Module] Llvm.PassManager.t -> unit */
CAMLprim value llvm_add_ipc_propagation(LLVMPassManagerRef PM) {
LLVMAddIPConstantPropagationPass(PM);
return Val_unit;
}
/* [`Module] Llvm.PassManager.t -> unit */
CAMLprim value llvm_add_prune_eh(LLVMPassManagerRef PM) {
LLVMAddPruneEHPass(PM);
return Val_unit;
}
/* [`Module] Llvm.PassManager.t -> unit */
CAMLprim value llvm_add_ipsccp(LLVMPassManagerRef PM) {
LLVMAddIPSCCPPass(PM);
return Val_unit;
}
/* [`Module] Llvm.PassManager.t -> bool -> unit */
CAMLprim value llvm_add_internalize(LLVMPassManagerRef PM, value AllButMain) {
LLVMAddInternalizePass(PM, Bool_val(AllButMain));
return Val_unit;
}
/* [`Module] Llvm.PassManager.t -> unit */
CAMLprim value llvm_add_strip_dead_prototypes(LLVMPassManagerRef PM) {
LLVMAddStripDeadPrototypesPass(PM);
return Val_unit;
}
/* [`Module] Llvm.PassManager.t -> unit */
CAMLprim value llvm_add_strip_symbols(LLVMPassManagerRef PM) {
LLVMAddStripSymbolsPass(PM);
return Val_unit;
}

View File

@ -0,0 +1,65 @@
(*===-- llvm_ipo.mli - LLVM Ocaml Interface ------------*- OCaml -*-===*
*
* The LLVM Compiler Infrastructure
*
* This file is distributed under the University of Illinois Open Source
* License. See LICENSE.TXT for details.
*
*===----------------------------------------------------------------------===*)
(** IPO Transforms.
This interface provides an ocaml API for LLVM interprocedural optimizations, the
classes in the [LLVMIPO] library. *)
(** See llvm::createAddArgumentPromotionPass *)
external add_argument_promotion : [ | `Module ] Llvm.PassManager.t -> unit =
"llvm_add_argument_promotion"
(** See llvm::createConstantMergePass function. *)
external add_constant_merge : [ | `Module ] Llvm.PassManager.t -> unit =
"llvm_add_constant_merge"
(** See llvm::createDeadArgEliminationPass function. *)
external add_dead_arg_elimination :
[ | `Module ] Llvm.PassManager.t -> unit = "llvm_add_dead_arg_elimination"
(** See llvm::createFunctionAttrsPass function. *)
external add_function_attrs : [ | `Module ] Llvm.PassManager.t -> unit =
"llvm_add_function_attrs"
(** See llvm::createFunctionInliningPass function. *)
external add_function_inlining : [ | `Module ] Llvm.PassManager.t -> unit =
"llvm_add_function_inlining"
(** See llvm::createGlobalDCEPass function. *)
external add_global_dce : [ | `Module ] Llvm.PassManager.t -> unit =
"llvm_add_global_dce"
(** See llvm::createGlobalOptimizerPass function. *)
external add_global_optimizer : [ | `Module ] Llvm.PassManager.t -> unit =
"llvm_add_global_optimizer"
(** See llvm::createIPConstantPropagationPass function. *)
external add_ipc_propagation : [ | `Module ] Llvm.PassManager.t -> unit =
"llvm_add_ipc_propagation"
(** See llvm::createPruneEHPass function. *)
external add_prune_eh : [ | `Module ] Llvm.PassManager.t -> unit =
"llvm_add_prune_eh"
(** See llvm::createIPSCCPPass function. *)
external add_ipsccp : [ | `Module ] Llvm.PassManager.t -> unit =
"llvm_add_ipsccp"
(** See llvm::createInternalizePass function. *)
external add_internalize : [ | `Module ] Llvm.PassManager.t -> bool -> unit =
"llvm_add_internalize"
(** See llvm::createStripDeadPrototypesPass function. *)
external add_strip_dead_prototypes :
[ | `Module ] Llvm.PassManager.t -> unit = "llvm_add_strip_dead_prototypes"
(** See llvm::createStripSymbolsPass function. *)
external add_strip_symbols : [ | `Module ] Llvm.PassManager.t -> unit =
"llvm_add_strip_symbols"

View File

@ -0,0 +1,65 @@
(*===-- llvm_ipo.mli - LLVM Ocaml Interface ------------*- OCaml -*-===*
*
* The LLVM Compiler Infrastructure
*
* This file is distributed under the University of Illinois Open Source
* License. See LICENSE.TXT for details.
*
*===----------------------------------------------------------------------===*)
(** IPO Transforms.
This interface provides an ocaml API for LLVM interprocedural optimizations, the
classes in the [LLVMIPO] library. *)
(** See llvm::createAddArgumentPromotionPass *)
external add_argument_promotion : [ | `Module ] Llvm.PassManager.t -> unit =
"llvm_add_argument_promotion"
(** See llvm::createConstantMergePass function. *)
external add_constant_merge : [ | `Module ] Llvm.PassManager.t -> unit =
"llvm_add_constant_merge"
(** See llvm::createDeadArgEliminationPass function. *)
external add_dead_arg_elimination :
[ | `Module ] Llvm.PassManager.t -> unit = "llvm_add_dead_arg_elimination"
(** See llvm::createFunctionAttrsPass function. *)
external add_function_attrs : [ | `Module ] Llvm.PassManager.t -> unit =
"llvm_add_function_attrs"
(** See llvm::createFunctionInliningPass function. *)
external add_function_inlining : [ | `Module ] Llvm.PassManager.t -> unit =
"llvm_add_function_inlining"
(** See llvm::createGlobalDCEPass function. *)
external add_global_dce : [ | `Module ] Llvm.PassManager.t -> unit =
"llvm_add_global_dce"
(** See llvm::createGlobalOptimizerPass function. *)
external add_global_optimizer : [ | `Module ] Llvm.PassManager.t -> unit =
"llvm_add_global_optimizer"
(** See llvm::createIPConstantPropagationPass function. *)
external add_ipc_propagation : [ | `Module ] Llvm.PassManager.t -> unit =
"llvm_add_ipc_propagation"
(** See llvm::createPruneEHPass function. *)
external add_prune_eh : [ | `Module ] Llvm.PassManager.t -> unit =
"llvm_add_prune_eh"
(** See llvm::createIPSCCPPass function. *)
external add_ipsccp : [ | `Module ] Llvm.PassManager.t -> unit =
"llvm_add_ipsccp"
(** See llvm::createInternalizePass function. *)
external add_internalize : [ | `Module ] Llvm.PassManager.t -> bool -> unit =
"llvm_add_internalize"
(** See llvm::createStripDeadPrototypesPass function. *)
external add_strip_dead_prototypes :
[ | `Module ] Llvm.PassManager.t -> unit = "llvm_add_strip_dead_prototypes"
(** See llvm::createStripSymbolsPass function. *)
external add_strip_symbols : [ | `Module ] Llvm.PassManager.t -> unit =
"llvm_add_strip_symbols"

View File

@ -20,6 +20,15 @@ external add_aggressive_dce : [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
external
add_scalar_repl_aggregation : [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
= "llvm_add_scalar_repl_aggregation"
external
add_scalar_repl_aggregation_ssa : [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
= "llvm_add_scalar_repl_aggregation_ssa"
external
add_scalar_repl_aggregation_with_threshold : int -> [<Llvm.PassManager.any] Llvm.PassManager.t
-> unit
= "llvm_add_scalar_repl_aggregation_with_threshold"
external add_ind_var_simplification : [<Llvm.PassManager.any] Llvm.PassManager.t
-> unit
= "llvm_add_ind_var_simplification"
@ -67,6 +76,36 @@ external add_memcpy_opt : [<Llvm.PassManager.any] Llvm.PassManager.t
external add_loop_deletion : [<Llvm.PassManager.any] Llvm.PassManager.t
-> unit
= "llvm_add_loop_deletion"
external add_loop_idiom : [<Llvm.PassManager.any] Llvm.PassManager.t
-> unit
= "llvm_add_loop_idiom"
external
add_lib_call_simplification : [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
= "llvm_add_lib_call_simplification"
external
add_verifier : [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
= "llvm_add_verifier"
external
add_correlated_value_propagation : [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
= "llvm_add_correlated_value_propagation"
external
add_early_cse : [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
= "llvm_add_early_cse"
external
add_lower_expect_intrinsic : [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
= "llvm_add_lower_expect_intrinsic"
external
add_type_based_alias_analysis : [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
= "llvm_add_type_based_alias_analysis"
external
add_basic_alias_analysis : [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
= "llvm_add_basic_alias_analysis"

View File

@ -35,6 +35,17 @@ external
add_scalar_repl_aggregation : [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
= "llvm_add_scalar_repl_aggregation"
(** See the [llvm::createScalarReplAggregatesPassSSA] function. *)
external
add_scalar_repl_aggregation_ssa : [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
= "llvm_add_scalar_repl_aggregation_ssa"
(** See the [llvm::createScalarReplAggregatesWithThreshold] function. *)
external
add_scalar_repl_aggregation_with_threshold : int -> [<Llvm.PassManager.any] Llvm.PassManager.t
-> unit
= "llvm_add_scalar_repl_aggregation_with_threshold"
(** See the [llvm::createIndVarSimplifyPass] function. *)
external add_ind_var_simplification : [<Llvm.PassManager.any] Llvm.PassManager.t
-> unit
@ -112,7 +123,42 @@ external add_loop_deletion : [<Llvm.PassManager.any] Llvm.PassManager.t
-> unit
= "llvm_add_loop_deletion"
external add_loop_idiom : [<Llvm.PassManager.any] Llvm.PassManager.t
-> unit
= "llvm_add_loop_idiom"
(** See the [llvm::createSimplifyLibCallsPass] function. *)
external
add_lib_call_simplification : [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
= "llvm_add_lib_call_simplification"
(** See the [llvm::createVerifierPass] function. *)
external
add_verifier : [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
= "llvm_add_verifier"
(** See the [llvm::createCorrelatedValuePropagationPass] function. *)
external
add_correlated_value_propagation : [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
= "llvm_add_correlated_value_propagation"
(** See the [llvm::createEarlyCSE] function. *)
external
add_early_cse : [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
= "llvm_add_early_cse"
(** See the [llvm::createLowerExpectIntrinsicPass] function. *)
external
add_lower_expect_intrinsic : [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
= "llvm_add_lower_expect_intrinsic"
(** See the [llvm::createTypeBasedAliasAnalysisPass] function. *)
external
add_type_based_alias_analysis : [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
= "llvm_add_type_based_alias_analysis"
(** See the [llvm::createBasicAliasAnalysisPass] function. *)
external
add_basic_alias_analysis : [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
= "llvm_add_basic_alias_analysis"

View File

@ -49,6 +49,19 @@ CAMLprim value llvm_add_scalar_repl_aggregation(LLVMPassManagerRef PM) {
return Val_unit;
}
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
CAMLprim value llvm_add_scalar_repl_aggregation_ssa(LLVMPassManagerRef PM) {
LLVMAddScalarReplAggregatesPassSSA(PM);
return Val_unit;
}
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> int -> unit */
CAMLprim value llvm_add_scalar_repl_aggregation_with_threshold(value threshold,
LLVMPassManagerRef PM) {
LLVMAddScalarReplAggregatesPassWithThreshold(PM, Int_val(threshold));
return Val_unit;
}
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
CAMLprim value llvm_add_ind_var_simplification(LLVMPassManagerRef PM) {
LLVMAddIndVarSimplifyPass(PM);
@ -69,7 +82,7 @@ CAMLprim value llvm_add_licm(LLVMPassManagerRef PM) {
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
CAMLprim value llvm_add_loop_unswitch(LLVMPassManagerRef PM) {
LLVMAddLoopUnrollPass(PM);
LLVMAddLoopUnswitchPass(PM);
return Val_unit;
}
@ -139,8 +152,50 @@ CAMLprim value llvm_add_loop_deletion(LLVMPassManagerRef PM) {
return Val_unit;
}
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
CAMLprim value llvm_add_loop_idiom(LLVMPassManagerRef PM) {
LLVMAddLoopIdiomPass(PM);
return Val_unit;
}
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
CAMLprim value llvm_add_lib_call_simplification(LLVMPassManagerRef PM) {
LLVMAddSimplifyLibCallsPass(PM);
return Val_unit;
}
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
CAMLprim value llvm_add_verifier(LLVMPassManagerRef PM) {
LLVMAddVerifierPass(PM);
return Val_unit;
}
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
CAMLprim value llvm_add_correlated_value_propagation(LLVMPassManagerRef PM) {
LLVMAddCorrelatedValuePropagationPass(PM);
return Val_unit;
}
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
CAMLprim value llvm_add_early_cse(LLVMPassManagerRef PM) {
LLVMAddEarlyCSEPass(PM);
return Val_unit;
}
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
CAMLprim value llvm_add_lower_expect_intrinsic(LLVMPassManagerRef PM) {
LLVMAddLowerExpectIntrinsicPass(PM);
return Val_unit;
}
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
CAMLprim value llvm_add_type_based_alias_analysis(LLVMPassManagerRef PM) {
LLVMAddTypeBasedAliasAnalysisPass(PM);
return Val_unit;
}
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
CAMLprim value llvm_add_basic_alias_analysis(LLVMPassManagerRef PM) {
LLVMAddBasicAliasAnalysisPass(PM);
return Val_unit;
}

View File

@ -198,11 +198,6 @@ if( LLVM_USING_GLIBC )
add_llvm_definitions( -D_GNU_SOURCE )
endif()
# Type checks
check_type_exists(std::bidirectional_iterator<int,int> "iterator;iostream" HAVE_BI_ITERATOR)
check_type_exists(std::iterator<int,int,int> iterator HAVE_STD_ITERATOR)
check_type_exists(std::forward_iterator<int,int> iterator HAVE_FWD_ITERATOR)
set(headers "")
if (HAVE_SYS_TYPES_H)
set(headers ${headers} "sys/types.h")
@ -277,7 +272,7 @@ else()
unset(HAVE_FFI_CALL CACHE)
endif( LLVM_ENABLE_FFI )
# Define LLVM_MULTITHREADED if gcc atomic builtins exists.
# Define LLVM_HAS_ATOMICS if gcc or MSVC atomic builtins are supported.
include(CheckAtomic)
if( LLVM_ENABLE_PIC )
@ -336,7 +331,7 @@ else ()
message(STATUS "Native target architecture is ${LLVM_NATIVE_ARCH}")
set(LLVM_NATIVE_TARGET LLVMInitialize${LLVM_NATIVE_ARCH}Target)
set(LLVM_NATIVE_TARGETINFO LLVMInitialize${LLVM_NATIVE_ARCH}TargetInfo)
set(LLVM_NATIVE_MCASMINFO LLVMInitialize${LLVM_NATIVE_ARCH}MCAsmInfo)
set(LLVM_NATIVE_TARGETMC LLVMInitialize${LLVM_NATIVE_ARCH}TargetMC)
set(LLVM_NATIVE_ASMPRINTER LLVMInitialize${LLVM_NATIVE_ARCH}AsmPrinter)
endif ()

View File

@ -24,16 +24,17 @@ macro(add_llvm_library name)
LIBRARY DESTINATION lib${LLVM_LIBDIR_SUFFIX}
ARCHIVE DESTINATION lib${LLVM_LIBDIR_SUFFIX})
endif()
# The LLVM Target library shall be built before its sublibraries
# (asmprinter, etc) because those may use tablegenned files which
# generation is triggered by the main LLVM target library. Necessary
# for parallel builds:
if( CURRENT_LLVM_TARGET )
add_dependencies(${name} ${CURRENT_LLVM_TARGET})
endif()
set_target_properties(${name} PROPERTIES FOLDER "Libraries")
endmacro(add_llvm_library name)
macro(add_llvm_library_dependencies name)
# Save the dependencies of the LLVM library in a variable so that we can
# query it when resolve llvm-config-style component -> library mappings.
set_property(GLOBAL PROPERTY LLVM_LIB_DEPS_${name} ${ARGN})
# Then add the actual dependencies to the library target.
target_link_libraries(${name} ${ARGN})
endmacro(add_llvm_library_dependencies name)
macro(add_llvm_loadable_module name)
if( NOT LLVM_ON_UNIX OR CYGWIN )
@ -124,16 +125,9 @@ endmacro(add_llvm_utility name)
macro(add_llvm_target target_name)
if( TABLEGEN_OUTPUT )
add_custom_target(${target_name}Table_gen
DEPENDS ${TABLEGEN_OUTPUT})
add_dependencies(${target_name}Table_gen ${LLVM_COMMON_DEPENDS})
endif( TABLEGEN_OUTPUT )
include_directories(BEFORE ${CMAKE_CURRENT_BINARY_DIR})
include_directories(BEFORE
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR})
add_llvm_library(LLVM${target_name} ${ARGN} ${TABLEGEN_OUTPUT})
if ( TABLEGEN_OUTPUT )
add_dependencies(LLVM${target_name} ${target_name}Table_gen)
set_target_properties(${target_name}Table_gen PROPERTIES FOLDER "Tablegenning")
endif (TABLEGEN_OUTPUT)
set( CURRENT_LLVM_TARGET LLVM${target_name} )
endmacro(add_llvm_target)

View File

@ -3,6 +3,12 @@ set(LLVM_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX})
get_property(llvm_libs GLOBAL PROPERTY LLVM_LIBS)
foreach(lib ${llvm_libs})
get_property(llvm_lib_deps GLOBAL PROPERTY LLVM_LIB_DEPS_${lib})
set(all_llvm_lib_deps
"${all_llvm_lib_deps}\nset_property(GLOBAL PROPERTY LLVM_LIB_DEPS_${lib} ${llvm_lib_deps})")
endforeach(lib)
configure_file(
LLVMConfig.cmake.in
${llvm_cmake_builddir}/LLVMConfig.cmake
@ -17,7 +23,6 @@ install(FILES
${llvm_cmake_builddir}/LLVMConfig.cmake
${llvm_cmake_builddir}/LLVMConfigVersion.cmake
LLVM-Config.cmake
LLVMLibDeps.cmake
DESTINATION share/llvm/cmake)
install(DIRECTORY .
@ -27,8 +32,6 @@ install(DIRECTORY .
PATTERN LLVMConfig.cmake EXCLUDE
PATTERN LLVMConfigVersion.cmake EXCLUDE
PATTERN LLVM-Config.cmake EXCLUDE
PATTERN LLVMLibDeps.cmake EXCLUDE
PATTERN FindBison.cmake EXCLUDE
PATTERN GetTargetTriple.cmake EXCLUDE
PATTERN VersionFromVCS.cmake EXCLUDE
PATTERN CheckAtomic.cmake EXCLUDE)

View File

@ -22,8 +22,8 @@ int main() {
#endif
return 0;
}
" LLVM_MULTITHREADED)
" LLVM_HAS_ATOMICS)
if( NOT LLVM_MULTITHREADED )
if( NOT LLVM_HAS_ATOMICS )
message(STATUS "Warning: LLVM will be built thread-unsafe because atomic builtins are missing")
endif()

View File

@ -1,26 +0,0 @@
if( ${LLVM_TABLEGEN} STREQUAL "tblgen" )
set(CX_NATIVE_TG_DIR "${CMAKE_BINARY_DIR}/native")
set(LLVM_TABLEGEN_EXE "${CX_NATIVE_TG_DIR}/bin/tblgen")
add_custom_command(OUTPUT ${CX_NATIVE_TG_DIR}
COMMAND ${CMAKE_COMMAND} -E make_directory ${CX_NATIVE_TG_DIR}
COMMENT "Creating ${CX_NATIVE_TG_DIR}...")
add_custom_command(OUTPUT ${CX_NATIVE_TG_DIR}/CMakeCache.txt
COMMAND ${CMAKE_COMMAND} -UMAKE_TOOLCHAIN_FILE -DCMAKE_BUILD_TYPE=Release ${CMAKE_SOURCE_DIR}
WORKING_DIRECTORY ${CX_NATIVE_TG_DIR}
DEPENDS ${CX_NATIVE_TG_DIR}
COMMENT "Configuring native TableGen...")
add_custom_command(OUTPUT ${LLVM_TABLEGEN_EXE}
COMMAND ${CMAKE_BUILD_TOOL}
DEPENDS ${CX_NATIVE_TG_DIR}/CMakeCache.txt
WORKING_DIRECTORY ${CX_NATIVE_TG_DIR}/utils/TableGen
COMMENT "Building native TableGen...")
add_custom_target(NativeTableGen DEPENDS ${LLVM_TABLEGEN_EXE})
add_dependencies(tblgen NativeTableGen)
set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES ${CX_NATIVE_TG_DIR})
endif()

View File

@ -1,52 +0,0 @@
# - Try to find Bison
# Once done this will define
#
# BISON_FOUND - system has Bison
# BISON_EXECUTABLE - path of the bison executable
# BISON_VERSION - the version string, like "2.5.31"
#
MACRO(FIND_BISON)
FIND_PROGRAM(BISON_EXECUTABLE NAMES bison)
IF(BISON_EXECUTABLE)
SET(BISON_FOUND TRUE)
EXECUTE_PROCESS(COMMAND ${BISON_EXECUTABLE} --version
OUTPUT_VARIABLE _BISON_VERSION
)
string (REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+" BISON_VERSION "${_bison_VERSION}")
ENDIF(BISON_EXECUTABLE)
IF(BISON_FOUND)
IF(NOT Bison_FIND_QUIETLY)
MESSAGE(STATUS "Found Bison: ${BISON_EXECUTABLE}")
ENDIF(NOT Bison_FIND_QUIETLY)
ELSE(BISON_FOUND)
IF(Bison_FIND_REQUIRED)
MESSAGE(FATAL_ERROR "Could not find Bison")
ENDIF(Bison_FIND_REQUIRED)
ENDIF(BISON_FOUND)
ENDMACRO(FIND_BISON)
MACRO(BISON_GENERATOR _PREFIX _Y_INPUT _H_OUTPUT _CPP_OUTPUT)
IF(BISON_EXECUTABLE)
GET_FILENAME_COMPONENT(_Y_DIR ${_Y_INPUT} PATH)
ADD_CUSTOM_COMMAND(
OUTPUT ${_CPP_OUTPUT}
OUTPUT ${_H_OUTPUT}
DEPENDS ${_Y_INPUT}
COMMAND ${BISON_EXECUTABLE}
ARGS
-p ${_PREFIX} -o"${_CPP_OUTPUT}"
--defines="${_H_OUTPUT}" ${_Y_INPUT}
WORKING_DIRECTORY ${_Y_DIR}
)
SET_SOURCE_FILES_PROPERTIES(
${_CPP_OUTPUT} ${_H_OUTPUT}
GENERATED
)
ELSE(BISON_EXECUTABLE)
MESSAGE(SEND_ERROR "Can't find bison program, and it's required")
ENDIF(BISON_EXECUTABLE)
ENDMACRO(BISON_GENERATOR)

View File

@ -155,6 +155,7 @@ if( MSVC )
-wd4351 # Suppress 'new behavior: elements of array 'array' will be default initialized'
-wd4355 # Suppress ''this' : used in base member initializer list'
-wd4503 # Suppress ''identifier' : decorated name length exceeded, name was truncated'
-wd4551 # Suppress 'function call missing argument list'
-wd4624 # Suppress ''derived class' : destructor could not be generated because a base class destructor is inaccessible'
-wd4715 # Suppress ''function' : not all control paths return a value'
-wd4800 # Suppress ''type' : forcing value to bool 'true' or 'false' (performance warning)'
@ -185,7 +186,8 @@ elseif( LLVM_COMPILER_IS_GCC_COMPATIBLE )
endif (LLVM_ENABLE_WERROR)
endif( MSVC )
add_llvm_definitions( -D__STDC_LIMIT_MACROS )
add_llvm_definitions( -D__STDC_CONSTANT_MACROS )
add_llvm_definitions( -D__STDC_FORMAT_MACROS )
add_llvm_definitions( -D__STDC_LIMIT_MACROS )
option(LLVM_INCLUDE_TESTS "Generate build targets for the LLVM unit tests." ON)

View File

@ -135,14 +135,14 @@ function(explicit_map_components_to_libraries out_libs)
string(TOUPPER "${c}" capitalized)
list(FIND capitalized_libs LLVM${capitalized} lib_idx)
if( lib_idx LESS 0 )
# The component is unknown. Maybe is an omitted target?
is_llvm_target_library(${c} iltl_result)
if( NOT iltl_result )
message(FATAL_ERROR "Library `${c}' not found in list of llvm libraries.")
endif()
# The component is unknown. Maybe is an omitted target?
is_llvm_target_library(${c} iltl_result)
if( NOT iltl_result )
message(FATAL_ERROR "Library `${c}' not found in list of llvm libraries.")
endif()
else( lib_idx LESS 0 )
list(GET llvm_libs ${lib_idx} canonical_lib)
list(APPEND expanded_components ${canonical_lib})
list(GET llvm_libs ${lib_idx} canonical_lib)
list(APPEND expanded_components ${canonical_lib})
endif( lib_idx LESS 0 )
endif( NOT idx LESS 0 )
endforeach(c)
@ -152,7 +152,8 @@ function(explicit_map_components_to_libraries out_libs)
set(processed)
while( cursor LESS lst_size )
list(GET expanded_components ${cursor} lib)
list(APPEND expanded_components ${MSVC_LIB_DEPS_${lib}})
get_property(lib_deps GLOBAL PROPERTY LLVM_LIB_DEPS_${lib})
list(APPEND expanded_components ${lib_deps})
# Remove duplicates at the front:
list(REVERSE expanded_components)
list(REMOVE_DUPLICATES expanded_components)
@ -175,29 +176,3 @@ function(explicit_map_components_to_libraries out_libs)
endforeach(c)
set(${out_libs} ${result} PARENT_SCOPE)
endfunction(explicit_map_components_to_libraries)
# The library dependency data is contained in the file
# LLVMLibDeps.cmake on this directory. It is automatically generated
# by tools/llvm-config/CMakeLists.txt when the build comprises all the
# targets and we are on a environment Posix enough to build the
# llvm-config script. This, in practice, just excludes MSVC.
# When you remove or rename a library from the build, be sure to
# remove its file from lib/ as well, or the GenLibDeps.pl script will
# include it on its analysis!
# The format generated by GenLibDeps.pl
# LLVMARMAsmPrinter.o: LLVMARMCodeGen.o libLLVMAsmPrinter.a libLLVMCodeGen.a libLLVMCore.a libLLVMSupport.a libLLVMTarget.a
# is translated to:
# set(MSVC_LIB_DEPS_LLVMARMAsmPrinter LLVMARMCodeGen LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMSupport LLVMTarget)
# It is necessary to remove the `lib' prefix and the `.a'.
# This 'sed' script should do the trick:
# sed -e s'#\.a##g' -e 's#libLLVM#LLVM#g' -e 's#: # #' -e 's#\(.*\)#set(MSVC_LIB_DEPS_\1)#' ~/llvm/tools/llvm-config/LibDeps.txt
include(LLVMLibDeps)

View File

@ -12,6 +12,8 @@ set(LLVM_TARGETS_TO_BUILD @LLVM_TARGETS_TO_BUILD@)
set(LLVM_TARGETS_WITH_JIT @LLVM_TARGETS_WITH_JIT@)
@all_llvm_lib_deps@
set(TARGET_TRIPLE "@TARGET_TRIPLE@")
set(LLVM_TOOLS_BINARY_DIR @LLVM_TOOLS_BINARY_DIR@)

View File

@ -1,83 +0,0 @@
set(MSVC_LIB_DEPS_LLVMARMAsmParser LLVMARMCodeGen LLVMARMInfo LLVMMC LLVMMCParser LLVMSupport LLVMTarget)
set(MSVC_LIB_DEPS_LLVMARMAsmPrinter LLVMMC LLVMSupport)
set(MSVC_LIB_DEPS_LLVMARMCodeGen LLVMARMAsmPrinter LLVMARMDesc LLVMARMInfo LLVMAnalysis LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMMC LLVMSelectionDAG LLVMSupport LLVMTarget)
set(MSVC_LIB_DEPS_LLVMARMDesc LLVMARMInfo LLVMMC LLVMSupport)
set(MSVC_LIB_DEPS_LLVMARMDisassembler LLVMARMCodeGen LLVMARMDesc LLVMARMInfo LLVMMC LLVMSupport)
set(MSVC_LIB_DEPS_LLVMARMInfo LLVMMC LLVMSupport)
set(MSVC_LIB_DEPS_LLVMAlphaCodeGen LLVMAlphaDesc LLVMAlphaInfo LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMMC LLVMSelectionDAG LLVMSupport LLVMTarget)
set(MSVC_LIB_DEPS_LLVMAlphaDesc LLVMAlphaInfo LLVMMC)
set(MSVC_LIB_DEPS_LLVMAlphaInfo LLVMMC LLVMSupport)
set(MSVC_LIB_DEPS_LLVMAnalysis LLVMCore LLVMSupport LLVMTarget)
set(MSVC_LIB_DEPS_LLVMArchive LLVMBitReader LLVMCore LLVMSupport)
set(MSVC_LIB_DEPS_LLVMAsmParser LLVMCore LLVMSupport)
set(MSVC_LIB_DEPS_LLVMAsmPrinter LLVMAnalysis LLVMCodeGen LLVMCore LLVMMC LLVMMCParser LLVMSupport LLVMTarget)
set(MSVC_LIB_DEPS_LLVMBitReader LLVMCore LLVMSupport)
set(MSVC_LIB_DEPS_LLVMBitWriter LLVMCore LLVMSupport)
set(MSVC_LIB_DEPS_LLVMBlackfinCodeGen LLVMAsmPrinter LLVMBlackfinDesc LLVMBlackfinInfo LLVMCodeGen LLVMCore LLVMMC LLVMSelectionDAG LLVMSupport LLVMTarget)
set(MSVC_LIB_DEPS_LLVMBlackfinDesc LLVMBlackfinInfo LLVMMC)
set(MSVC_LIB_DEPS_LLVMBlackfinInfo LLVMMC LLVMSupport)
set(MSVC_LIB_DEPS_LLVMCBackend LLVMAnalysis LLVMCBackendInfo LLVMCodeGen LLVMCore LLVMMC LLVMScalarOpts LLVMSupport LLVMTarget LLVMTransformUtils)
set(MSVC_LIB_DEPS_LLVMCBackendInfo LLVMMC LLVMSupport)
set(MSVC_LIB_DEPS_LLVMCellSPUCodeGen LLVMAsmPrinter LLVMCellSPUDesc LLVMCellSPUInfo LLVMCodeGen LLVMCore LLVMMC LLVMSelectionDAG LLVMSupport LLVMTarget)
set(MSVC_LIB_DEPS_LLVMCellSPUDesc LLVMCellSPUInfo LLVMMC)
set(MSVC_LIB_DEPS_LLVMCellSPUInfo LLVMMC LLVMSupport)
set(MSVC_LIB_DEPS_LLVMCodeGen LLVMAnalysis LLVMCore LLVMMC LLVMScalarOpts LLVMSupport LLVMTarget LLVMTransformUtils)
set(MSVC_LIB_DEPS_LLVMCore LLVMSupport)
set(MSVC_LIB_DEPS_LLVMCppBackend LLVMCore LLVMCppBackendInfo LLVMSupport LLVMTarget)
set(MSVC_LIB_DEPS_LLVMCppBackendInfo LLVMMC LLVMSupport)
set(MSVC_LIB_DEPS_LLVMExecutionEngine LLVMCore LLVMMC LLVMSupport LLVMTarget)
set(MSVC_LIB_DEPS_LLVMInstCombine LLVMAnalysis LLVMCore LLVMSupport LLVMTarget LLVMTransformUtils)
set(MSVC_LIB_DEPS_LLVMInstrumentation LLVMAnalysis LLVMCore LLVMSupport LLVMTransformUtils)
set(MSVC_LIB_DEPS_LLVMInterpreter LLVMCodeGen LLVMCore LLVMExecutionEngine LLVMSupport LLVMTarget)
set(MSVC_LIB_DEPS_LLVMJIT LLVMCodeGen LLVMCore LLVMExecutionEngine LLVMMC LLVMSupport LLVMTarget)
set(MSVC_LIB_DEPS_LLVMLinker LLVMArchive LLVMBitReader LLVMCore LLVMSupport LLVMTransformUtils)
set(MSVC_LIB_DEPS_LLVMMBlazeAsmParser LLVMMBlazeCodeGen LLVMMBlazeInfo LLVMMC LLVMMCParser LLVMSupport LLVMTarget)
set(MSVC_LIB_DEPS_LLVMMBlazeAsmPrinter LLVMMC LLVMSupport)
set(MSVC_LIB_DEPS_LLVMMBlazeCodeGen LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMMBlazeAsmPrinter LLVMMBlazeDesc LLVMMBlazeInfo LLVMMC LLVMSelectionDAG LLVMSupport LLVMTarget)
set(MSVC_LIB_DEPS_LLVMMBlazeDesc LLVMMBlazeInfo LLVMMC LLVMSupport)
set(MSVC_LIB_DEPS_LLVMMBlazeDisassembler LLVMMBlazeCodeGen LLVMMBlazeDesc LLVMMBlazeInfo LLVMMC)
set(MSVC_LIB_DEPS_LLVMMBlazeInfo LLVMMC LLVMSupport)
set(MSVC_LIB_DEPS_LLVMMC LLVMSupport)
set(MSVC_LIB_DEPS_LLVMMCDisassembler LLVMARMAsmParser LLVMARMCodeGen LLVMARMDesc LLVMARMDisassembler LLVMARMInfo LLVMAlphaCodeGen LLVMAlphaDesc LLVMAlphaInfo LLVMBlackfinCodeGen LLVMBlackfinDesc LLVMBlackfinInfo LLVMCBackend LLVMCBackendInfo LLVMCellSPUCodeGen LLVMCellSPUDesc LLVMCellSPUInfo LLVMCppBackend LLVMCppBackendInfo LLVMMBlazeAsmParser LLVMMBlazeCodeGen LLVMMBlazeDesc LLVMMBlazeDisassembler LLVMMBlazeInfo LLVMMC LLVMMCParser LLVMMSP430CodeGen LLVMMSP430Desc LLVMMSP430Info LLVMMipsCodeGen LLVMMipsDesc LLVMMipsInfo LLVMPTXCodeGen LLVMPTXDesc LLVMPTXInfo LLVMPowerPCCodeGen LLVMPowerPCDesc LLVMPowerPCInfo LLVMSparcCodeGen LLVMSparcDesc LLVMSparcInfo LLVMSupport LLVMSystemZCodeGen LLVMSystemZDesc LLVMSystemZInfo LLVMTarget LLVMX86AsmParser LLVMX86CodeGen LLVMX86Desc LLVMX86Disassembler LLVMX86Info LLVMXCoreCodeGen LLVMXCoreDesc LLVMXCoreInfo)
set(MSVC_LIB_DEPS_LLVMMCJIT LLVMCore LLVMExecutionEngine LLVMRuntimeDyld LLVMSupport LLVMTarget)
set(MSVC_LIB_DEPS_LLVMMCParser LLVMMC LLVMSupport)
set(MSVC_LIB_DEPS_LLVMMSP430AsmPrinter LLVMMC LLVMSupport)
set(MSVC_LIB_DEPS_LLVMMSP430CodeGen LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMMC LLVMMSP430AsmPrinter LLVMMSP430Desc LLVMMSP430Info LLVMSelectionDAG LLVMSupport LLVMTarget)
set(MSVC_LIB_DEPS_LLVMMSP430Desc LLVMMC LLVMMSP430Info)
set(MSVC_LIB_DEPS_LLVMMSP430Info LLVMMC LLVMSupport)
set(MSVC_LIB_DEPS_LLVMMipsAsmPrinter LLVMMC LLVMSupport)
set(MSVC_LIB_DEPS_LLVMMipsCodeGen LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMMC LLVMMipsAsmPrinter LLVMMipsDesc LLVMMipsInfo LLVMSelectionDAG LLVMSupport LLVMTarget)
set(MSVC_LIB_DEPS_LLVMMipsDesc LLVMMC LLVMMipsInfo LLVMSupport)
set(MSVC_LIB_DEPS_LLVMMipsInfo LLVMMC LLVMSupport)
set(MSVC_LIB_DEPS_LLVMObject LLVMSupport)
set(MSVC_LIB_DEPS_LLVMPTXCodeGen LLVMAnalysis LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMMC LLVMPTXDesc LLVMPTXInfo LLVMSelectionDAG LLVMSupport LLVMTarget)
set(MSVC_LIB_DEPS_LLVMPTXDesc LLVMMC LLVMPTXInfo LLVMSupport)
set(MSVC_LIB_DEPS_LLVMPTXInfo LLVMMC LLVMSupport)
set(MSVC_LIB_DEPS_LLVMPowerPCAsmPrinter LLVMMC LLVMSupport)
set(MSVC_LIB_DEPS_LLVMPowerPCCodeGen LLVMAnalysis LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMMC LLVMPowerPCAsmPrinter LLVMPowerPCDesc LLVMPowerPCInfo LLVMSelectionDAG LLVMSupport LLVMTarget)
set(MSVC_LIB_DEPS_LLVMPowerPCDesc LLVMMC LLVMPowerPCInfo LLVMSupport)
set(MSVC_LIB_DEPS_LLVMPowerPCInfo LLVMMC LLVMSupport)
set(MSVC_LIB_DEPS_LLVMRuntimeDyld LLVMObject LLVMSupport)
set(MSVC_LIB_DEPS_LLVMScalarOpts LLVMAnalysis LLVMCore LLVMInstCombine LLVMSupport LLVMTarget LLVMTransformUtils)
set(MSVC_LIB_DEPS_LLVMSelectionDAG LLVMAnalysis LLVMCodeGen LLVMCore LLVMMC LLVMSupport LLVMTarget LLVMTransformUtils)
set(MSVC_LIB_DEPS_LLVMSparcCodeGen LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMMC LLVMSelectionDAG LLVMSparcDesc LLVMSparcInfo LLVMSupport LLVMTarget)
set(MSVC_LIB_DEPS_LLVMSparcDesc LLVMMC LLVMSparcInfo LLVMSupport)
set(MSVC_LIB_DEPS_LLVMSparcInfo LLVMMC LLVMSupport)
set(MSVC_LIB_DEPS_LLVMSupport )
set(MSVC_LIB_DEPS_LLVMSystemZCodeGen LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMMC LLVMSelectionDAG LLVMSupport LLVMSystemZDesc LLVMSystemZInfo LLVMTarget)
set(MSVC_LIB_DEPS_LLVMSystemZDesc LLVMMC LLVMSystemZInfo)
set(MSVC_LIB_DEPS_LLVMSystemZInfo LLVMMC LLVMSupport)
set(MSVC_LIB_DEPS_LLVMTarget LLVMCore LLVMMC LLVMSupport)
set(MSVC_LIB_DEPS_LLVMTransformUtils LLVMAnalysis LLVMCore LLVMSupport LLVMTarget LLVMipa)
set(MSVC_LIB_DEPS_LLVMX86AsmParser LLVMMC LLVMMCParser LLVMSupport LLVMTarget LLVMX86Info)
set(MSVC_LIB_DEPS_LLVMX86AsmPrinter LLVMMC LLVMSupport LLVMX86Utils)
set(MSVC_LIB_DEPS_LLVMX86CodeGen LLVMAnalysis LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMMC LLVMSelectionDAG LLVMSupport LLVMTarget LLVMX86AsmPrinter LLVMX86Desc LLVMX86Info LLVMX86Utils)
set(MSVC_LIB_DEPS_LLVMX86Desc LLVMMC LLVMSupport LLVMX86Info)
set(MSVC_LIB_DEPS_LLVMX86Disassembler LLVMMC LLVMSupport LLVMX86Info)
set(MSVC_LIB_DEPS_LLVMX86Info LLVMMC LLVMSupport)
set(MSVC_LIB_DEPS_LLVMX86Utils LLVMCore LLVMSupport)
set(MSVC_LIB_DEPS_LLVMXCoreCodeGen LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMMC LLVMSelectionDAG LLVMSupport LLVMTarget LLVMXCoreDesc LLVMXCoreInfo)
set(MSVC_LIB_DEPS_LLVMXCoreDesc LLVMMC LLVMXCoreInfo)
set(MSVC_LIB_DEPS_LLVMXCoreInfo LLVMMC LLVMSupport)
set(MSVC_LIB_DEPS_LLVMipa LLVMAnalysis LLVMCore LLVMSupport)
set(MSVC_LIB_DEPS_LLVMipo LLVMAnalysis LLVMCore LLVMScalarOpts LLVMSupport LLVMTarget LLVMTransformUtils LLVMipa)

View File

@ -2,7 +2,7 @@
# Extra parameters for `tblgen' may come after `ofn' parameter.
# Adds the name of the generated file to TABLEGEN_OUTPUT.
macro(tablegen ofn)
macro(tablegen project ofn)
file(GLOB local_tds "*.td")
file(GLOB_RECURSE global_tds "${LLVM_MAIN_SRC_DIR}/include/llvm/*.td")
@ -14,14 +14,14 @@ macro(tablegen ofn)
endif()
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${ofn}.tmp
# Generate tablegen output in a temporary file.
COMMAND ${LLVM_TABLEGEN_EXE} ${ARGN} -I ${CMAKE_CURRENT_SOURCE_DIR}
COMMAND ${${project}_TABLEGEN_EXE} ${ARGN} -I ${CMAKE_CURRENT_SOURCE_DIR}
-I ${LLVM_MAIN_SRC_DIR}/lib/Target -I ${LLVM_MAIN_INCLUDE_DIR}
${LLVM_TARGET_DEFINITIONS_ABSOLUTE}
-o ${CMAKE_CURRENT_BINARY_DIR}/${ofn}.tmp
# The file in LLVM_TARGET_DEFINITIONS may be not in the current
# directory and local_tds may not contain it, so we must
# explicitly list it here:
DEPENDS ${LLVM_TABLEGEN_EXE} ${local_tds} ${global_tds}
DEPENDS ${${project}_TABLEGEN_EXE} ${local_tds} ${global_tds}
${LLVM_TARGET_DEFINITIONS_ABSOLUTE}
COMMENT "Building ${ofn}..."
)
@ -44,3 +44,82 @@ macro(tablegen ofn)
set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/${ofn}
PROPERTIES GENERATED 1)
endmacro(tablegen)
function(add_public_tablegen_target target)
# Creates a target for publicly exporting tablegen dependencies.
if( TABLEGEN_OUTPUT )
add_custom_target(${target}
DEPENDS ${TABLEGEN_OUTPUT})
add_dependencies(${target} ${LLVM_COMMON_DEPENDS})
endif( TABLEGEN_OUTPUT )
endfunction()
if(CMAKE_CROSSCOMPILING)
set(CX_NATIVE_TG_DIR "${CMAKE_BINARY_DIR}/native")
add_custom_command(OUTPUT ${CX_NATIVE_TG_DIR}
COMMAND ${CMAKE_COMMAND} -E make_directory ${CX_NATIVE_TG_DIR}
COMMENT "Creating ${CX_NATIVE_TG_DIR}...")
add_custom_command(OUTPUT ${CX_NATIVE_TG_DIR}/CMakeCache.txt
COMMAND ${CMAKE_COMMAND} -UMAKE_TOOLCHAIN_FILE -DCMAKE_BUILD_TYPE=Release
-DLLVM_BUILD_POLLY=OFF ${CMAKE_SOURCE_DIR}
WORKING_DIRECTORY ${CX_NATIVE_TG_DIR}
DEPENDS ${CX_NATIVE_TG_DIR}
COMMENT "Configuring native TableGen...")
add_custom_target(ConfigureNativeTableGen DEPENDS ${CX_NATIVE_TG_DIR}/CMakeCache.txt)
set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES ${CX_NATIVE_TG_DIR})
endif()
macro(add_tablegen target project)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${LLVM_TOOLS_BINARY_DIR})
add_llvm_utility(${target} ${ARGN})
set(${project}_TABLEGEN "${target}" CACHE
STRING "Native TableGen executable. Saves building one when cross-compiling.")
# Upgrade existing LLVM_TABLEGEN setting.
if(${project} STREQUAL LLVM)
if(${LLVM_TABLEGEN} STREQUAL tblgen)
set(LLVM_TABLEGEN "${target}" CACHE
STRING "Native TableGen executable. Saves building one when cross-compiling."
FORCE)
endif()
endif()
# Effective tblgen executable to be used:
set(${project}_TABLEGEN_EXE ${${project}_TABLEGEN} PARENT_SCOPE)
if(CMAKE_CROSSCOMPILING)
if( ${${project}_TABLEGEN} STREQUAL "${target}" )
set(${project}_TABLEGEN_EXE "${CX_NATIVE_TG_DIR}/bin/${target}")
set(${project}_TABLEGEN_EXE ${${project}_TABLEGEN_EXE} PARENT_SCOPE)
add_custom_command(OUTPUT ${${project}_TABLEGEN_EXE}
COMMAND ${CMAKE_BUILD_TOOL} ${target}
DEPENDS ${CX_NATIVE_TG_DIR}/CMakeCache.txt
WORKING_DIRECTORY ${CX_NATIVE_TG_DIR}
COMMENT "Building native TableGen...")
add_custom_target(${project}NativeTableGen DEPENDS ${${project}_TABLEGEN_EXE})
add_dependencies(${project}NativeTableGen ConfigureNativeTableGen)
add_dependencies(${target} ${project}NativeTableGen)
endif()
endif()
target_link_libraries(${target} LLVMSupport LLVMTableGen)
if( MINGW )
target_link_libraries(${target} imagehlp psapi)
if(CMAKE_SIZEOF_VOID_P MATCHES "8")
set_target_properties(${target} PROPERTIES LINK_FLAGS -Wl,--stack,16777216)
endif(CMAKE_SIZEOF_VOID_P MATCHES "8")
endif( MINGW )
if( LLVM_ENABLE_THREADS AND HAVE_LIBPTHREAD AND NOT BEOS )
target_link_libraries(${target} pthread)
endif()
install(TARGETS ${target} RUNTIME DESTINATION bin)
endmacro()

8086
configure vendored

File diff suppressed because it is too large Load Diff

569
docs/Atomics.html Normal file
View File

@ -0,0 +1,569 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>LLVM Atomic Instructions and Concurrency Guide</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="stylesheet" href="llvm.css" type="text/css">
</head>
<body>
<h1>
LLVM Atomic Instructions and Concurrency Guide
</h1>
<ol>
<li><a href="#introduction">Introduction</a></li>
<li><a href="#outsideatomic">Optimization outside atomic</a></li>
<li><a href="#atomicinst">Atomic instructions</a></li>
<li><a href="#ordering">Atomic orderings</a></li>
<li><a href="#iropt">Atomics and IR optimization</a></li>
<li><a href="#codegen">Atomics and Codegen</a></li>
</ol>
<div class="doc_author">
<p>Written by Eli Friedman</p>
</div>
<!-- *********************************************************************** -->
<h2>
<a name="introduction">Introduction</a>
</h2>
<!-- *********************************************************************** -->
<div>
<p>Historically, LLVM has not had very strong support for concurrency; some
minimal intrinsics were provided, and <code>volatile</code> was used in some
cases to achieve rough semantics in the presence of concurrency. However, this
is changing; there are now new instructions which are well-defined in the
presence of threads and asynchronous signals, and the model for existing
instructions has been clarified in the IR.</p>
<p>The atomic instructions are designed specifically to provide readable IR and
optimized code generation for the following:</p>
<ul>
<li>The new C++0x <code>&lt;atomic&gt;</code> header.
(<a href="http://www.open-std.org/jtc1/sc22/wg21/">C++0x draft available here</a>.)
(<a href="http://www.open-std.org/jtc1/sc22/wg14/">C1x draft available here</a>)</li>
<li>Proper semantics for Java-style memory, for both <code>volatile</code> and
regular shared variables.
(<a href="http://java.sun.com/docs/books/jls/third_edition/html/memory.html">Java Specification</a>)</li>
<li>gcc-compatible <code>__sync_*</code> builtins.
(<a href="http://gcc.gnu.org/onlinedocs/gcc/Atomic-Builtins.html">Description</a>)</li>
<li>Other scenarios with atomic semantics, including <code>static</code>
variables with non-trivial constructors in C++.</li>
</ul>
<p>Atomic and volatile in the IR are orthogonal; "volatile" is the C/C++
volatile, which ensures that every volatile load and store happens and is
performed in the stated order. A couple examples: if a
SequentiallyConsistent store is immediately followed by another
SequentiallyConsistent store to the same address, the first store can
be erased. This transformation is not allowed for a pair of volatile
stores. On the other hand, a non-volatile non-atomic load can be moved
across a volatile load freely, but not an Acquire load.</p>
<p>This document is intended to provide a guide to anyone either writing a
frontend for LLVM or working on optimization passes for LLVM with a guide
for how to deal with instructions with special semantics in the presence of
concurrency. This is not intended to be a precise guide to the semantics;
the details can get extremely complicated and unreadable, and are not
usually necessary.</p>
</div>
<!-- *********************************************************************** -->
<h2>
<a name="outsideatomic">Optimization outside atomic</a>
</h2>
<!-- *********************************************************************** -->
<div>
<p>The basic <code>'load'</code> and <code>'store'</code> allow a variety of
optimizations, but can lead to undefined results in a concurrent environment;
see <a href="#o_nonatomic">NonAtomic</a>. This section specifically goes
into the one optimizer restriction which applies in concurrent environments,
which gets a bit more of an extended description because any optimization
dealing with stores needs to be aware of it.</p>
<p>From the optimizer's point of view, the rule is that if there
are not any instructions with atomic ordering involved, concurrency does
not matter, with one exception: if a variable might be visible to another
thread or signal handler, a store cannot be inserted along a path where it
might not execute otherwise. Take the following example:</p>
<pre>
/* C code, for readability; run through clang -O2 -S -emit-llvm to get
equivalent IR */
int x;
void f(int* a) {
for (int i = 0; i &lt; 100; i++) {
if (a[i])
x += 1;
}
}
</pre>
<p>The following is equivalent in non-concurrent situations:</p>
<pre>
int x;
void f(int* a) {
int xtemp = x;
for (int i = 0; i &lt; 100; i++) {
if (a[i])
xtemp += 1;
}
x = xtemp;
}
</pre>
<p>However, LLVM is not allowed to transform the former to the latter: it could
indirectly introduce undefined behavior if another thread can access x at
the same time. (This example is particularly of interest because before the
concurrency model was implemented, LLVM would perform this
transformation.)</p>
<p>Note that speculative loads are allowed; a load which
is part of a race returns <code>undef</code>, but does not have undefined
behavior.</p>
</div>
<!-- *********************************************************************** -->
<h2>
<a name="atomicinst">Atomic instructions</a>
</h2>
<!-- *********************************************************************** -->
<div>
<p>For cases where simple loads and stores are not sufficient, LLVM provides
various atomic instructions. The exact guarantees provided depend on the
ordering; see <a href="#ordering">Atomic orderings</a></p>
<p><code>load atomic</code> and <code>store atomic</code> provide the same
basic functionality as non-atomic loads and stores, but provide additional
guarantees in situations where threads and signals are involved.</p>
<p><code>cmpxchg</code> and <code>atomicrmw</code> are essentially like an
atomic load followed by an atomic store (where the store is conditional for
<code>cmpxchg</code>), but no other memory operation can happen on any thread
between the load and store. Note that LLVM's cmpxchg does not provide quite
as many options as the C++0x version.</p>
<p>A <code>fence</code> provides Acquire and/or Release ordering which is not
part of another operation; it is normally used along with Monotonic memory
operations. A Monotonic load followed by an Acquire fence is roughly
equivalent to an Acquire load.</p>
<p>Frontends generating atomic instructions generally need to be aware of the
target to some degree; atomic instructions are guaranteed to be lock-free,
and therefore an instruction which is wider than the target natively supports
can be impossible to generate.</p>
</div>
<!-- *********************************************************************** -->
<h2>
<a name="ordering">Atomic orderings</a>
</h2>
<!-- *********************************************************************** -->
<div>
<p>In order to achieve a balance between performance and necessary guarantees,
there are six levels of atomicity. They are listed in order of strength;
each level includes all the guarantees of the previous level except for
Acquire/Release. (See also <a href="LangRef.html#ordering">LangRef</a>.)</p>
<!-- ======================================================================= -->
<h3>
<a name="o_notatomic">NotAtomic</a>
</h3>
<div>
<p>NotAtomic is the obvious, a load or store which is not atomic. (This isn't
really a level of atomicity, but is listed here for comparison.) This is
essentially a regular load or store. If there is a race on a given memory
location, loads from that location return undef.</p>
<dl>
<dt>Relevant standard</dt>
<dd>This is intended to match shared variables in C/C++, and to be used
in any other context where memory access is necessary, and
a race is impossible. (The precise definition is in
<a href="LangRef.html#memmodel">LangRef</a>.)
<dt>Notes for frontends</dt>
<dd>The rule is essentially that all memory accessed with basic loads and
stores by multiple threads should be protected by a lock or other
synchronization; otherwise, you are likely to run into undefined
behavior. If your frontend is for a "safe" language like Java,
use Unordered to load and store any shared variable. Note that NotAtomic
volatile loads and stores are not properly atomic; do not try to use
them as a substitute. (Per the C/C++ standards, volatile does provide
some limited guarantees around asynchronous signals, but atomics are
generally a better solution.)
<dt>Notes for optimizers</dt>
<dd>Introducing loads to shared variables along a codepath where they would
not otherwise exist is allowed; introducing stores to shared variables
is not. See <a href="#outsideatomic">Optimization outside
atomic</a>.</dd>
<dt>Notes for code generation</dt>
<dd>The one interesting restriction here is that it is not allowed to write
to bytes outside of the bytes relevant to a store. This is mostly
relevant to unaligned stores: it is not allowed in general to convert
an unaligned store into two aligned stores of the same width as the
unaligned store. Backends are also expected to generate an i8 store
as an i8 store, and not an instruction which writes to surrounding
bytes. (If you are writing a backend for an architecture which cannot
satisfy these restrictions and cares about concurrency, please send an
email to llvmdev.)</dd>
</dl>
</div>
<!-- ======================================================================= -->
<h3>
<a name="o_unordered">Unordered</a>
</h3>
<div>
<p>Unordered is the lowest level of atomicity. It essentially guarantees that
races produce somewhat sane results instead of having undefined behavior.
It also guarantees the operation to be lock-free, so it do not depend on
the data being part of a special atomic structure or depend on a separate
per-process global lock. Note that code generation will fail for
unsupported atomic operations; if you need such an operation, use explicit
locking.</p>
<dl>
<dt>Relevant standard</dt>
<dd>This is intended to match the Java memory model for shared
variables.</dd>
<dt>Notes for frontends</dt>
<dd>This cannot be used for synchronization, but is useful for Java and
other "safe" languages which need to guarantee that the generated
code never exhibits undefined behavior. Note that this guarantee
is cheap on common platforms for loads of a native width, but can
be expensive or unavailable for wider loads, like a 64-bit store
on ARM. (A frontend for Java or other "safe" languages would normally
split a 64-bit store on ARM into two 32-bit unordered stores.)
<dt>Notes for optimizers</dt>
<dd>In terms of the optimizer, this prohibits any transformation that
transforms a single load into multiple loads, transforms a store
into multiple stores, narrows a store, or stores a value which
would not be stored otherwise. Some examples of unsafe optimizations
are narrowing an assignment into a bitfield, rematerializing
a load, and turning loads and stores into a memcpy call. Reordering
unordered operations is safe, though, and optimizers should take
advantage of that because unordered operations are common in
languages that need them.</dd>
<dt>Notes for code generation</dt>
<dd>These operations are required to be atomic in the sense that if you
use unordered loads and unordered stores, a load cannot see a value
which was never stored. A normal load or store instruction is usually
sufficient, but note that an unordered load or store cannot
be split into multiple instructions (or an instruction which
does multiple memory operations, like <code>LDRD</code> on ARM).</dd>
</dl>
</div>
<!-- ======================================================================= -->
<h3>
<a name="o_monotonic">Monotonic</a>
</h3>
<div>
<p>Monotonic is the weakest level of atomicity that can be used in
synchronization primitives, although it does not provide any general
synchronization. It essentially guarantees that if you take all the
operations affecting a specific address, a consistent ordering exists.
<dl>
<dt>Relevant standard</dt>
<dd>This corresponds to the C++0x/C1x <code>memory_order_relaxed</code>;
see those standards for the exact definition.
<dt>Notes for frontends</dt>
<dd>If you are writing a frontend which uses this directly, use with caution.
The guarantees in terms of synchronization are very weak, so make
sure these are only used in a pattern which you know is correct.
Generally, these would either be used for atomic operations which
do not protect other memory (like an atomic counter), or along with
a <code>fence</code>.</dd>
<dt>Notes for optimizers</dt>
<dd>In terms of the optimizer, this can be treated as a read+write on the
relevant memory location (and alias analysis will take advantage of
that). In addition, it is legal to reorder non-atomic and Unordered
loads around Monotonic loads. CSE/DSE and a few other optimizations
are allowed, but Monotonic operations are unlikely to be used in ways
which would make those optimizations useful.</dd>
<dt>Notes for code generation</dt>
<dd>Code generation is essentially the same as that for unordered for loads
and stores. No fences are required. <code>cmpxchg</code> and
<code>atomicrmw</code> are required to appear as a single operation.</dd>
</dl>
</div>
<!-- ======================================================================= -->
<h3>
<a name="o_acquire">Acquire</a>
</h3>
<div>
<p>Acquire provides a barrier of the sort necessary to acquire a lock to access
other memory with normal loads and stores.
<dl>
<dt>Relevant standard</dt>
<dd>This corresponds to the C++0x/C1x <code>memory_order_acquire</code>. It
should also be used for C++0x/C1x <code>memory_order_consume</code>.
<dt>Notes for frontends</dt>
<dd>If you are writing a frontend which uses this directly, use with caution.
Acquire only provides a semantic guarantee when paired with a Release
operation.</dd>
<dt>Notes for optimizers</dt>
<dd>Optimizers not aware of atomics can treat this like a nothrow call.
It is also possible to move stores from before an Acquire load
or read-modify-write operation to after it, and move non-Acquire
loads from before an Acquire operation to after it.</dd>
<dt>Notes for code generation</dt>
<dd>Architectures with weak memory ordering (essentially everything relevant
today except x86 and SPARC) require some sort of fence to maintain
the Acquire semantics. The precise fences required varies widely by
architecture, but for a simple implementation, most architectures provide
a barrier which is strong enough for everything (<code>dmb</code> on ARM,
<code>sync</code> on PowerPC, etc.). Putting such a fence after the
equivalent Monotonic operation is sufficient to maintain Acquire
semantics for a memory operation.</dd>
</dl>
</div>
<!-- ======================================================================= -->
<h3>
<a name="o_acquire">Release</a>
</h3>
<div>
<p>Release is similar to Acquire, but with a barrier of the sort necessary to
release a lock.
<dl>
<dt>Relevant standard</dt>
<dd>This corresponds to the C++0x/C1x <code>memory_order_release</code>.</dd>
<dt>Notes for frontends</dt>
<dd>If you are writing a frontend which uses this directly, use with caution.
Release only provides a semantic guarantee when paired with a Acquire
operation.</dd>
<dt>Notes for optimizers</dt>
<dd>Optimizers not aware of atomics can treat this like a nothrow call.
It is also possible to move loads from after a Release store
or read-modify-write operation to before it, and move non-Release
stores from after an Release operation to before it.</dd>
<dt>Notes for code generation</dt>
<dd>See the section on Acquire; a fence before the relevant operation is
usually sufficient for Release. Note that a store-store fence is not
sufficient to implement Release semantics; store-store fences are
generally not exposed to IR because they are extremely difficult to
use correctly.</dd>
</dl>
</div>
<!-- ======================================================================= -->
<h3>
<a name="o_acqrel">AcquireRelease</a>
</h3>
<div>
<p>AcquireRelease (<code>acq_rel</code> in IR) provides both an Acquire and a
Release barrier (for fences and operations which both read and write memory).
<dl>
<dt>Relevant standard</dt>
<dd>This corresponds to the C++0x/C1x <code>memory_order_acq_rel</code>.
<dt>Notes for frontends</dt>
<dd>If you are writing a frontend which uses this directly, use with caution.
Acquire only provides a semantic guarantee when paired with a Release
operation, and vice versa.</dd>
<dt>Notes for optimizers</dt>
<dd>In general, optimizers should treat this like a nothrow call; the
the possible optimizations are usually not interesting.</dd>
<dt>Notes for code generation</dt>
<dd>This operation has Acquire and Release semantics; see the sections on
Acquire and Release.</dd>
</dl>
</div>
<!-- ======================================================================= -->
<h3>
<a name="o_seqcst">SequentiallyConsistent</a>
</h3>
<div>
<p>SequentiallyConsistent (<code>seq_cst</code> in IR) provides
Acquire semantics for loads and Release semantics for
stores. Additionally, it guarantees that a total ordering exists
between all SequentiallyConsistent operations.
<dl>
<dt>Relevant standard</dt>
<dd>This corresponds to the C++0x/C1x <code>memory_order_seq_cst</code>,
Java volatile, and the gcc-compatible <code>__sync_*</code> builtins
which do not specify otherwise.
<dt>Notes for frontends</dt>
<dd>If a frontend is exposing atomic operations, these are much easier to
reason about for the programmer than other kinds of operations, and using
them is generally a practical performance tradeoff.</dd>
<dt>Notes for optimizers</dt>
<dd>Optimizers not aware of atomics can treat this like a nothrow call.
For SequentiallyConsistent loads and stores, the same reorderings are
allowed as for Acquire loads and Release stores, except that
SequentiallyConsistent operations may not be reordered.</dd>
<dt>Notes for code generation</dt>
<dd>SequentiallyConsistent loads minimally require the same barriers
as Acquire operations and SequentiallyConsistent stores require
Release barriers. Additionally, the code generator must enforce
ordering between SequentiallyConsistent stores followed by
SequentiallyConsistent loads. This is usually done by emitting
either a full fence before the loads or a full fence after the
stores; which is preferred varies by architecture.</dd>
</dl>
</div>
</div>
<!-- *********************************************************************** -->
<h2>
<a name="iropt">Atomics and IR optimization</a>
</h2>
<!-- *********************************************************************** -->
<div>
<p>Predicates for optimizer writers to query:
<ul>
<li>isSimple(): A load or store which is not volatile or atomic. This is
what, for example, memcpyopt would check for operations it might
transform.</li>
<li>isUnordered(): A load or store which is not volatile and at most
Unordered. This would be checked, for example, by LICM before hoisting
an operation.</li>
<li>mayReadFromMemory()/mayWriteToMemory(): Existing predicate, but note
that they return true for any operation which is volatile or at least
Monotonic.</li>
<li>Alias analysis: Note that AA will return ModRef for anything Acquire or
Release, and for the address accessed by any Monotonic operation.</li>
</ul>
<p>To support optimizing around atomic operations, make sure you are using
the right predicates; everything should work if that is done. If your
pass should optimize some atomic operations (Unordered operations in
particular), make sure it doesn't replace an atomic load or store with
a non-atomic operation.</p>
<p>Some examples of how optimizations interact with various kinds of atomic
operations:
<ul>
<li>memcpyopt: An atomic operation cannot be optimized into part of a
memcpy/memset, including unordered loads/stores. It can pull operations
across some atomic operations.
<li>LICM: Unordered loads/stores can be moved out of a loop. It just treats
monotonic operations like a read+write to a memory location, and anything
stricter than that like a nothrow call.
<li>DSE: Unordered stores can be DSE'ed like normal stores. Monotonic stores
can be DSE'ed in some cases, but it's tricky to reason about, and not
especially important.
<li>Folding a load: Any atomic load from a constant global can be
constant-folded, because it cannot be observed. Similar reasoning allows
scalarrepl with atomic loads and stores.
</ul>
</div>
<!-- *********************************************************************** -->
<h2>
<a name="codegen">Atomics and Codegen</a>
</h2>
<!-- *********************************************************************** -->
<div>
<p>Atomic operations are represented in the SelectionDAG with
<code>ATOMIC_*</code> opcodes. On architectures which use barrier
instructions for all atomic ordering (like ARM), appropriate fences are
split out as the DAG is built.</p>
<p>The MachineMemOperand for all atomic operations is currently marked as
volatile; this is not correct in the IR sense of volatile, but CodeGen
handles anything marked volatile very conservatively. This should get
fixed at some point.</p>
<p>Common architectures have some way of representing at least a pointer-sized
lock-free <code>cmpxchg</code>; such an operation can be used to implement
all the other atomic operations which can be represented in IR up to that
size. Backends are expected to implement all those operations, but not
operations which cannot be implemented in a lock-free manner. It is
expected that backends will give an error when given an operation which
cannot be implemented. (The LLVM code generator is not very helpful here
at the moment, but hopefully that will change.)</p>
<p>The implementation of atomics on LL/SC architectures (like ARM) is currently
a bit of a mess; there is a lot of copy-pasted code across targets, and
the representation is relatively unsuited to optimization (it would be nice
to be able to optimize loops involving cmpxchg etc.).</p>
<p>On x86, all atomic loads generate a <code>MOV</code>.
SequentiallyConsistent stores generate an <code>XCHG</code>, other stores
generate a <code>MOV</code>. SequentiallyConsistent fences generate an
<code>MFENCE</code>, other fences do not cause any code to be generated.
cmpxchg uses the <code>LOCK CMPXCHG</code> instruction.
<code>atomicrmw xchg</code> uses <code>XCHG</code>,
<code>atomicrmw add</code> and <code>atomicrmw sub</code> use
<code>XADD</code>, and all other <code>atomicrmw</code> operations generate
a loop with <code>LOCK CMPXCHG</code>. Depending on the users of the
result, some <code>atomicrmw</code> operations can be translated into
operations like <code>LOCK AND</code>, but that does not work in
general.</p>
<p>On ARM, MIPS, and many other RISC architectures, Acquire, Release, and
SequentiallyConsistent semantics require barrier instructions
for every such operation. Loads and stores generate normal instructions.
<code>cmpxchg</code> and <code>atomicrmw</code> can be represented using
a loop with LL/SC-style instructions which take some sort of exclusive
lock on a cache line (<code>LDREX</code> and <code>STREX</code> on
ARM, etc.). At the moment, the IR does not provide any way to represent a
weak <code>cmpxchg</code> which would not require a loop.</p>
</div>
<!-- *********************************************************************** -->
<hr>
<address>
<a href="http://jigsaw.w3.org/css-validator/check/referer"><img
src="http://jigsaw.w3.org/css-validator/images/vcss-blue" alt="Valid CSS"></a>
<a href="http://validator.w3.org/check/referer"><img
src="http://www.w3.org/Icons/valid-html401-blue" alt="Valid HTML 4.01"></a>
<a href="http://llvm.org/">LLVM Compiler Infrastructure</a><br>
Last modified: $Date: 2011-08-09 02:07:00 -0700 (Tue, 09 Aug 2011) $
</address>
</body>
</html>

View File

@ -216,18 +216,6 @@ non-obvious ways. Here are some hints and tips:<p>
the list of specified optimizations to be randomized and applied to the
program. This process will repeat until a bug is found or the user
kills <tt>bugpoint</tt>.
<li><p><tt>bugpoint</tt> does not understand the <tt>-O</tt> option
that is used to specify optimization level to <tt>opt</tt>. You
can use e.g.</p>
<div class="doc_code">
<p><tt>opt -O2 -debug-pass=Arguments foo.bc -disable-output</tt></p>
</div>
<p>to get a list of passes that are used with <tt>-O2</tt> and
then pass this list to <tt>bugpoint</tt>.</p>
</ol>
</div>
@ -243,7 +231,7 @@ non-obvious ways. Here are some hints and tips:<p>
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
<a href="http://llvm.org/">LLVM Compiler Infrastructure</a><br>
Last modified: $Date: 2011-04-23 02:30:22 +0200 (Sat, 23 Apr 2011) $
Last modified: $Date: 2011-08-30 20:26:11 +0200 (Tue, 30 Aug 2011) $
</address>
</body>

View File

@ -340,7 +340,7 @@
on Visual C++ and Xcode,
<tt>&quot;-sv&quot;</tt> on others.</dd>
<dt><b>LLVM_LIT_TOOLS_DIR</b>:STRING</dt>
<dt><b>LLVM_LIT_TOOLS_DIR</b>:PATH</dt>
<dd>The path to GnuWin32 tools for tests. Valid on Windows host.
Defaults to "", then Lit seeks tools according to %PATH%.
Lit can find tools(eg. grep, sort, &amp;c) on LLVM_LIT_TOOLS_DIR at first,
@ -423,8 +423,9 @@
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${LLVM_ROOT}/share/llvm/cmake")
include(LLVMConfig)
<b># Now set the header and library paths:</b>
include_directories( ${LLVM_ROOT}/include )
link_directories( ${LLVM_ROOT}/lib )
include_directories( ${LLVM_INCLUDE_DIRS} )
link_directories( ${LLVM_LIBRARY_DIRS} )
add_definitions( ${LLVM_DEFINITIONS} )
<b># Let's suppose we want to build a JIT compiler with support for
# binary code (no interpreter):</b>
llvm_map_components_to_libraries(REQ_LLVM_LIBRARIES jit native)

View File

@ -114,6 +114,7 @@
<li><a href="#ppc_prolog">Prolog/Epilog</a></li>
<li><a href="#ppc_dynamic">Dynamic Allocation</a></li>
</ul></li>
<li><a href="#ptx">The PTX backend</a></li>
</ul></li>
</ol>
@ -1768,22 +1769,28 @@ bool RegMapping_Fer::compatible_class(MachineFunction &amp;mf,
different register allocators:</p>
<ul>
<li><i>Linear Scan</i> &mdash; <i>The default allocator</i>. This is the
well-know linear scan register allocator. Whereas the
<i>Simple</i> and <i>Local</i> algorithms use a direct mapping
implementation technique, the <i>Linear Scan</i> implementation
uses a spiller in order to place load and stores.</li>
<li><i>Fast</i> &mdash; This register allocator is the default for debug
builds. It allocates registers on a basic block level, attempting to keep
values in registers and reusing registers as appropriate.</li>
<li><i>Basic</i> &mdash; This is an incremental approach to register
allocation. Live ranges are assigned to registers one at a time in
an order that is driven by heuristics. Since code can be rewritten
on-the-fly during allocation, this framework allows interesting
allocators to be developed as extensions. It is not itself a
production register allocator but is a potentially useful
stand-alone mode for triaging bugs and as a performance baseline.
<li><i>Greedy</i> &mdash; <i>The default allocator</i>. This is a
highly tuned implementation of the <i>Basic</i> allocator that
incorporates global live range splitting. This allocator works hard
to minimize the cost of spill code.
<li><i>PBQP</i> &mdash; A Partitioned Boolean Quadratic Programming (PBQP)
based register allocator. This allocator works by constructing a PBQP
problem representing the register allocation problem under consideration,
solving this using a PBQP solver, and mapping the solution back to a
register assignment.</li>
</ul>
<p>The type of register allocator used in <tt>llc</tt> can be chosen with the
@ -1805,7 +1812,121 @@ $ llc -regalloc=pbqp file.bc -o pbqp.s;
<h3>
<a name="proepicode">Prolog/Epilog Code Insertion</a>
</h3>
<div><p>To Be Written</p></div>
<!-- _______________________________________________________________________ -->
<h4>
<a name="compact_unwind">Compact Unwind</a>
</h4>
<div>
<p>Throwing an exception requires <em>unwinding</em> out of a function. The
information on how to unwind a given function is traditionally expressed in
DWARF unwind (a.k.a. frame) info. But that format was originally developed
for debuggers to backtrace, and each Frame Description Entry (FDE) requires
~20-30 bytes per function. There is also the cost of mapping from an address
in a function to the corresponding FDE at runtime. An alternative unwind
encoding is called <em>compact unwind</em> and requires just 4-bytes per
function.</p>
<p>The compact unwind encoding is a 32-bit value, which is encoded in an
architecture-specific way. It specifies which registers to restore and from
where, and how to unwind out of the function. When the linker creates a final
linked image, it will create a <code>__TEXT,__unwind_info</code>
section. This section is a small and fast way for the runtime to access
unwind info for any given function. If we emit compact unwind info for the
function, that compact unwind info will be encoded in
the <code>__TEXT,__unwind_info</code> section. If we emit DWARF unwind info,
the <code>__TEXT,__unwind_info</code> section will contain the offset of the
FDE in the <code>__TEXT,__eh_frame</code> section in the final linked
image.</p>
<p>For X86, there are three modes for the compact unwind encoding:</p>
<dl>
<dt><i>Function with a Frame Pointer (<code>EBP</code> or <code>RBP</code>)</i></dt>
<dd><p><code>EBP/RBP</code>-based frame, where <code>EBP/RBP</code> is pushed
onto the stack immediately after the return address,
then <code>ESP/RSP</code> is moved to <code>EBP/RBP</code>. Thus to
unwind, <code>ESP/RSP</code> is restored with the
current <code>EBP/RBP</code> value, then <code>EBP/RBP</code> is restored
by popping the stack, and the return is done by popping the stack once
more into the PC. All non-volatile registers that need to be restored must
have been saved in a small range on the stack that
starts <code>EBP-4</code> to <code>EBP-1020</code> (<code>RBP-8</code>
to <code>RBP-1020</code>). The offset (divided by 4 in 32-bit mode and 8
in 64-bit mode) is encoded in bits 16-23 (mask: <code>0x00FF0000</code>).
The registers saved are encoded in bits 0-14
(mask: <code>0x00007FFF</code>) as five 3-bit entries from the following
table:</p>
<table border="1" cellspacing="0">
<tr>
<th>Compact Number</th>
<th>i386 Register</th>
<th>x86-64 Regiser</th>
</tr>
<tr>
<td>1</td>
<td><code>EBX</code></td>
<td><code>RBX</code></td>
</tr>
<tr>
<td>2</td>
<td><code>ECX</code></td>
<td><code>R12</code></td>
</tr>
<tr>
<td>3</td>
<td><code>EDX</code></td>
<td><code>R13</code></td>
</tr>
<tr>
<td>4</td>
<td><code>EDI</code></td>
<td><code>R14</code></td>
</tr>
<tr>
<td>5</td>
<td><code>ESI</code></td>
<td><code>R15</code></td>
</tr>
<tr>
<td>6</td>
<td><code>EBP</code></td>
<td><code>RBP</code></td>
</tr>
</table>
</dd>
<dt><i>Frameless with a Small Constant Stack Size (<code>EBP</code>
or <code>RBP</code> is not used as a frame pointer)</i></dt>
<dd><p>To return, a constant (encoded in the compact unwind encoding) is added
to the <code>ESP/RSP</code>. Then the return is done by popping the stack
into the PC. All non-volatile registers that need to be restored must have
been saved on the stack immediately after the return address. The stack
size (divided by 4 in 32-bit mode and 8 in 64-bit mode) is encoded in bits
16-23 (mask: <code>0x00FF0000</code>). There is a maximum stack size of
1024 bytes in 32-bit mode and 2048 in 64-bit mode. The number of registers
saved is encoded in bits 9-12 (mask: <code>0x00001C00</code>). Bits 0-9
(mask: <code>0x000003FF</code>) contain which registers were saved and
their order. (See
the <code>encodeCompactUnwindRegistersWithoutFrame()</code> function
in <code>lib/Target/X86FrameLowering.cpp</code> for the encoding
algorithm.)</p></dd>
<dt><i>Frameless with a Large Constant Stack Size (<code>EBP</code>
or <code>RBP</code> is not used as a frame pointer)</i></dt>
<dd><p>This case is like the "Frameless with a Small Constant Stack Size"
case, but the stack size is too large to encode in the compact unwind
encoding. Instead it requires that the function contains "<code>subl
$nnnnnn, %esp</code>" in its prolog. The compact encoding contains the
offset to the <code>$nnnnnn</code> value in the function in bits 9-12
(mask: <code>0x00001C00</code>).</p></dd>
</dl>
</div>
<!-- ======================================================================= -->
<h3>
<a name="latemco">Late Machine Code Optimizations</a>
@ -2165,7 +2286,7 @@ is the key:</p>
<td class="yes"></td> <!-- PowerPC -->
<td class="unknown"></td> <!-- Sparc -->
<td class="unknown"></td> <!-- SystemZ -->
<td class="yes"><a href="#feat_inlineasm_x86">*</a></td> <!-- X86 -->
<td class="yes"></td> <!-- X86 -->
<td class="unknown"></td> <!-- XCore -->
</tr>
@ -2261,9 +2382,6 @@ disassembling machine opcode bytes into MCInst's.</p>
<p>This box indicates whether the target supports most popular inline assembly
constraints and modifiers.</p>
<p id="feat_inlineasm_x86">X86 lacks reliable support for inline assembly
constraints relating to the X86 floating point stack.</p>
</div>
<!-- _______________________________________________________________________ -->
@ -2792,6 +2910,70 @@ MOVSX32rm16 -&gt; movsx, 32-bit register, 16-bit memory
</div>
</div>
<!-- ======================================================================= -->
<h3>
<a name="ptx">The PTX backend</a>
</h3>
<div>
<p>The PTX code generator lives in the lib/Target/PTX directory. It is
currently a work-in-progress, but already supports most of the code
generation functionality needed to generate correct PTX kernels for
CUDA devices.</p>
<p>The code generator can target PTX 2.0+, and shader model 1.0+. The
PTX ISA Reference Manual is used as the primary source of ISA
information, though an effort is made to make the output of the code
generator match the output of the NVidia nvcc compiler, whenever
possible.</p>
<p>Code Generator Options:</p>
<table border="1" cellspacing="0">
<tr>
<th>Option</th>
<th>Description</th>
</tr>
<tr>
<td><code>double</code></td>
<td align="left">If enabled, the map_f64_to_f32 directive is
disabled in the PTX output, allowing native double-precision
arithmetic</td>
</tr>
<tr>
<td><code>no-fma</code></td>
<td align="left">Disable generation of Fused-Multiply Add
instructions, which may be beneficial for some devices</td>
</tr>
<tr>
<td><code>smxy / computexy</code></td>
<td align="left">Set shader model/compute capability to x.y,
e.g. sm20 or compute13</td>
</tr>
</table>
<p>Working:</p>
<ul>
<li>Arithmetic instruction selection (including combo FMA)</li>
<li>Bitwise instruction selection</li>
<li>Control-flow instruction selection</li>
<li>Function calls (only on SM 2.0+ and no return arguments)</li>
<li>Addresses spaces (0 = global, 1 = constant, 2 = local, 4 =
shared)</li>
<li>Thread synchronization (bar.sync)</li>
<li>Special register reads ([N]TID, [N]CTAID, PMx, CLOCK, etc.)</li>
</ul>
<p>In Progress:</p>
<ul>
<li>Robust call instruction selection</li>
<li>Stack frame allocation</li>
<li>Device-specific instruction scheduling optimizations</li>
</ul>
</div>
</div>
@ -2806,7 +2988,7 @@ MOVSX32rm16 -&gt; movsx, 32-bit register, 16-bit memory
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
<a href="http://llvm.org/">The LLVM Compiler Infrastructure</a><br>
Last modified: $Date: 2011-05-23 00:28:47 +0200 (Mon, 23 May 2011) $
Last modified: $Date: 2011-09-19 20:15:46 +0200 (Mon, 19 Sep 2011) $
</address>
</body>

View File

@ -854,8 +854,12 @@ rules:</p>
<ul>
<li><p><b>Type names</b> (including classes, structs, enums, typedefs, etc)
should be nouns and start with an upper-case letter (e.g.
<tt>TextFileReader</tt>).</p></li>
should be nouns and start with an upper-case letter (e.g.
<tt>TextFileReader</tt>).</p></li>
<li><p><b>Variable names</b> should be nouns (as they represent state). The
name should be camel case, and start with an upper case letter (e.g.
<tt>Leader</tt> or <tt>Boats</tt>).</p></li>
<li><p><b>Function names</b> should be verb phrases (as they represent
actions), and command-like function should be imperative. The name should
@ -1522,7 +1526,7 @@ something.</p>
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
<a href="http://llvm.org/">LLVM Compiler Infrastructure</a><br>
Last modified: $Date: 2011-04-23 02:30:22 +0200 (Sat, 23 Apr 2011) $
Last modified: $Date: 2011-08-12 21:49:16 +0200 (Fri, 12 Aug 2011) $
</address>
</body>

View File

@ -69,9 +69,6 @@ options) arguments to the tool you are interested in.</p>
<li><a href="/cmds/llvm-config.html"><b>llvm-config</b></a> -
print out LLVM compilation options, libraries, etc. as configured</li>
<li><a href="/cmds/llvmc.html"><b>llvmc</b></a> -
a generic customizable compiler driver</li>
<li><a href="/cmds/llvm-diff.html"><b>llvm-diff</b></a> -
structurally compare two modules</li>
@ -79,25 +76,6 @@ options) arguments to the tool you are interested in.</p>
</div>
<!-- *********************************************************************** -->
<h2>
<a name="frontend">C and C++ Front-end Commands</a>
</h2>
<!-- *********************************************************************** -->
<div>
<ul>
<li><a href="/cmds/llvmgcc.html"><b>llvm-gcc</b></a> -
GCC-based C front-end for LLVM
<li><a href="/cmds/llvmgxx.html"><b>llvm-g++</b></a> -
GCC-based C++ front-end for LLVM</li>
</ul>
</div>
<!-- *********************************************************************** -->
<h2>
<a name="debug">Debugging Tools</a>
@ -151,7 +129,7 @@ options) arguments to the tool you are interested in.</p>
src="http://www.w3.org/Icons/valid-html401-blue" alt="Valid HTML 4.01"></a>
<a href="http://llvm.org/">LLVM Compiler Infrastructure</a><br>
Last modified: $Date: 2011-04-23 02:30:22 +0200 (Sat, 23 Apr 2011) $
Last modified: $Date: 2011-09-20 20:24:04 +0200 (Tue, 20 Sep 2011) $
</address>
</body>

View File

@ -37,11 +37,23 @@ B<llvm-extract> will write raw bitcode regardless of the output device.
Extract the function named I<function-name> from the LLVM bitcode. May be
specified multiple times to extract multiple functions at once.
=item B<--rfunc> I<function-regular-expr>
Extract the function(s) matching I<function-regular-expr> from the LLVM bitcode.
All functions matching the regular expression will be extracted. May be
specified multiple times.
=item B<--glob> I<global-name>
Extract the global variable named I<global-name> from the LLVM bitcode. May be
specified multiple times to extract multiple global variables at once.
=item B<--rglob> I<glob-regular-expr>
Extract the global variable(s) matching I<global-regular-expr> from the LLVM
bitcode. All global variables matching the regular expression will be extracted.
May be specified multiple times.
=item B<-help>
Print a summary of command line options.

View File

@ -1,190 +0,0 @@
=pod
=head1 NAME
llvmc - The LLVM Compiler Driver (WIP)
=head1 SYNOPSIS
B<llvmc> [I<options>] I<filenames...>
=head1 DESCRIPTION
B<llvmc> is a configurable driver for invoking other LLVM (and non-LLVM) tools
in order to compile, optimize and link software for multiple languages. For
those familiar with FSF's B<gcc> tool, it is very similar. Please note that
B<llvmc> is considered an experimental tool.
=head1 OPTIONS
=head2 Built-in Options
LLVMC has some built-in options that can't be overridden in the
configuration libraries.
=over
=item B<-o> I<filename>
Output file name.
=item B<-x> I<language>
Specify the language of the following input files until the next B<-x>
option.
=item B<-load> I<plugin_name>
Load the specified plugin DLL. Example:
S<-load $LLVM_DIR/Release/lib/LLVMCSimple.so>.
=item B<-v> or B<--verbose>
Enable verbose mode, i.e. print out all executed commands.
=item B<--check-graph>
Check the compilation for common errors like mismatched output/input language
names, multiple default edges and cycles. Because of plugins, these checks can't
be performed at compile-time. Exit with code zero if no errors were found, and
return the number of found errors otherwise. Hidden option, useful for debugging
LLVMC plugins.
=item B<--view-graph>
Show a graphical representation of the compilation graph and exit. Requires that
you have I<dot> and I<gv> programs installed. Hidden option, useful for
debugging LLVMC plugins.
=item B<--write-graph>
Write a I<compilation-graph.dot> file in the current directory with the
compilation graph description in Graphviz format (identical to the file used by
the B<--view-graph> option). The B<-o> option can be used to set the output file
name. Hidden option, useful for debugging LLVMC plugins.
=item B<--save-temps>
Write temporary files to the current directory and do not delete them on
exit. This option can also take an argument: the I<--save-temps=obj> switch will
write files into the directory specified with the I<-o> option. The
I<--save-temps=cwd> and I<--save-temps> switches are both synonyms for the
default behaviour.
=item B<--temp-dir> I<directory>
Store temporary files in the given directory. This directory is deleted on exit
unless I<--save-temps> is specified. If I<--save-temps=obj> is also specified,
I<--temp-dir> is given the precedence.
=item B<-help>
Print a summary of command-line options and exit.
=item B<-help-hidden>
Print a summary of command-line options and exit. Print help even for
options intended for developers.
=item B<--version>
Print version information and exit.
=item B<@>I<file>
Read command-line options from I<file>. The options read are inserted
in place of the original @I<file> option. If I<file> does not exist, or
cannot be read, then the option will be treated literally, and not
removed.
Options in I<file> are separated by whitespace. A whitespace character
may be included in an option by surrounding the entire option in
either single or double quotes. Any character (including a backslash)
may be included by prefixing the character to be included with a
backslash. The file may itself contain additional @I<file> options;
any such options will be processed recursively.
=back
=head2 Control Options
By default, LLVMC is built with some standard configuration libraries
that define the following options:
=over
=item B<-clang>
Use Clang instead of llvm-gcc.
=item B<-opt>
Enable optimization passes with B<opt>. To pass options to the B<opt> program
use the B<-Wo,> option.
=item B<-I> I<directory>
Add a directory to the header file search path.
=item B<-L> I<directory>
Add I<directory> to the library search path.
=item B<-F> I<directory>
Add I<directory> to the framework search path.
=item B<-l>I<name>
Link in the library libI<name>.[bc | a | so]. This library should
be a bitcode library.
=item B<-framework> I<name>
Link in the library libI<name>.[bc | a | so]. This library should
be a bitcode library.
=item B<-emit-llvm>
Output LLVM bitcode (with B<-c>) or assembly (with B<-S>) instead of native
object (or assembly). If B<-emit-llvm> is given without either B<-c> or B<-S>
it has no effect.
=item B<-Wa>
Pass options to assembler.
=item B<-Wl>
Pass options to linker.
=item B<-Wo>
Pass options to opt.
=item B<-Wllc>
Pass options to llc (code generator).
=back
=head1 EXIT STATUS
If B<llvmc> succeeds, it will exit with code 0. Otherwise, if an
error occurs, it will exit with a non-zero value. If one of the
compilation tools returns a non-zero status, pending actions will be
discarded and B<llvmc> will return the same result code as the failing
compilation tool.
=head1 SEE ALSO
L<llvm-gcc|llvmgcc>, L<llvm-g++|llvmgxx>, L<llvm-as|llvm-as>,
L<llvm-dis|llvm-dis>, L<llc|llc>, L<llvm-link|llvm-link>
=head1 AUTHORS
Maintained by the LLVM Team (L<http://llvm.org/>).
=cut

View File

@ -1,76 +0,0 @@
=pod
=head1 NAME
llvm-gcc - LLVM C front-end
=head1 SYNOPSIS
B<llvm-gcc> [I<options>] I<filename>
=head1 DESCRIPTION
The B<llvm-gcc> command is the LLVM C front end. It is a modified
version of gcc that compiles C/ObjC programs into native objects, LLVM
bitcode or LLVM assembly language, depending upon the options.
By default, B<llvm-gcc> compiles to native objects just like GCC does. If the
B<-emit-llvm> and B<-c> options are given then it will generate LLVM bitcode files
instead. If B<-emit-llvm> and B<-S> are given, then it will generate LLVM
assembly.
Being derived from the GNU Compiler Collection, B<llvm-gcc> has many
of gcc's features and accepts most of gcc's options. It handles a
number of gcc's extensions to the C programming language. See the gcc
documentation for details.
=head1 OPTIONS
=over
=item B<--help>
Print a summary of command line options.
=item B<-o> I<filename>
Specify the output file to be I<filename>.
=item B<-I> I<directory>
Add a directory to the header file search path. This option can be
repeated.
=item B<-L> I<directory>
Add I<directory> to the library search path. This option can be
repeated.
=item B<-l>I<name>
Link in the library libI<name>.[bc | a | so]. This library should
be a bitcode library.
=item B<-emit-llvm>
Make the output be LLVM bitcode (with B<-c>) or assembly (with B<-s>) instead
of native object (or assembly). If B<-emit-llvm> is given without either B<-c>
or B<-S> it has no effect.
=back
=head1 EXIT STATUS
If B<llvm-gcc> succeeds, it will exit with 0. Otherwise, if an error
occurs, it will exit with a non-zero value.
=head1 SEE ALSO
L<llvm-g++|llvmgxx>
=head1 AUTHORS
Maintained by the LLVM Team (L<http://llvm.org/>).
=cut

View File

@ -1,85 +0,0 @@
=pod
=head1 NAME
llvm-g++ - LLVM C++ front-end
=head1 SYNOPSIS
B<llvm-g++> [I<options>] I<filename>
=head1 DESCRIPTION
The B<llvm-g++> command is the LLVM C++ front end. It is a modified
version of g++ that compiles C++/ObjC++ programs into native code,
LLVM bitcode or assembly language, depending upon the options.
By default, B<llvm-g++> compiles to native objects just like GCC does. If the
B<-emit-llvm> option is given then it will generate LLVM bitcode files instead.
If B<-S> (assembly) is also given, then it will generate LLVM assembly.
Being derived from the GNU Compiler Collection, B<llvm-g++> has many
of g++'s features and accepts most of g++'s options. It handles a
number of g++'s extensions to the C++ programming language.
=head1 OPTIONS
=over
=item B<--help>
Print a summary of command line options.
=item B<-S>
Do not generate an LLVM bitcode file. Rather, compile the source
file into an LLVM assembly language file.
=item B<-c>
Do not generate a linked executable. Rather, compile the source
file into an LLVM bitcode file. This bitcode file can then be
linked with other bitcode files later on to generate a full LLVM
executable.
=item B<-o> I<filename>
Specify the output file to be I<filename>.
=item B<-I> I<directory>
Add a directory to the header file search path. This option can be
repeated.
=item B<-L> I<directory>
Add I<directory> to the library search path. This option can be
repeated.
=item B<-l>I<name>
Link in the library libI<name>.[bc | a | so]. This library should
be a bitcode library.
=item B<-emit-llvm>
Make the output be LLVM bitcode (or assembly) instead of native object (or
assembly).
=back
=head1 EXIT STATUS
If B<llvm-g++> succeeds, it will exit with 0. Otherwise, if an error
occurs, it will exit with a non-zero value.
=head1 SEE ALSO
L<llvm-gcc|llvmgcc>
=head1 AUTHORS
Maintained by the LLVM Team (L<http://llvm.org/>).
=cut

View File

@ -1,687 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.6: http://docutils.sourceforge.net/" />
<title>Customizing LLVMC: Reference Manual</title>
<link rel="stylesheet" href="llvm.css" type="text/css" />
</head>
<body>
<div class="document" id="customizing-llvmc-reference-manual">
<h1 class="title">Customizing LLVMC: Reference Manual</h1>
<!-- This file was automatically generated by rst2html.
Please do not edit directly!
The ReST source lives in the directory 'tools/llvmc/doc'. -->
<div class="contents topic" id="contents">
<p class="topic-title first">Contents</p>
<ul class="simple">
<li><a class="reference internal" href="#introduction" id="id7">Introduction</a></li>
<li><a class="reference internal" href="#compiling-with-llvmc" id="id8">Compiling with <tt class="docutils literal">llvmc</tt></a></li>
<li><a class="reference internal" href="#predefined-options" id="id9">Predefined options</a></li>
<li><a class="reference internal" href="#compiling-llvmc-based-drivers" id="id10">Compiling LLVMC-based drivers</a></li>
<li><a class="reference internal" href="#customizing-llvmc-the-compilation-graph" id="id11">Customizing LLVMC: the compilation graph</a></li>
<li><a class="reference internal" href="#describing-options" id="id12">Describing options</a></li>
<li><a class="reference internal" href="#conditional-evaluation" id="id13">Conditional evaluation</a></li>
<li><a class="reference internal" href="#writing-a-tool-description" id="id14">Writing a tool description</a><ul>
<li><a class="reference internal" href="#id4" id="id15">Actions</a></li>
</ul>
</li>
<li><a class="reference internal" href="#language-map" id="id16">Language map</a></li>
<li><a class="reference internal" href="#option-preprocessor" id="id17">Option preprocessor</a></li>
<li><a class="reference internal" href="#more-advanced-topics" id="id18">More advanced topics</a><ul>
<li><a class="reference internal" href="#hooks-and-environment-variables" id="id19">Hooks and environment variables</a></li>
<li><a class="reference internal" href="#debugging" id="id20">Debugging</a></li>
<li><a class="reference internal" href="#conditioning-on-the-executable-name" id="id21">Conditioning on the executable name</a></li>
</ul>
</li>
</ul>
</div>
<div class="doc_author">
<p>Written by <a href="mailto:foldr@codedgers.com">Mikhail Glushenkov</a></p>
</div><div class="section" id="introduction">
<h1><a class="toc-backref" href="#id7">Introduction</a></h1>
<p>LLVMC is a generic compiler driver, designed to be customizable and
extensible. It plays the same role for LLVM as the <tt class="docutils literal">gcc</tt> program does for
GCC - LLVMC's job is essentially to transform a set of input files into a set of
targets depending on configuration rules and user options. What makes LLVMC
different is that these transformation rules are completely customizable - in
fact, LLVMC knows nothing about the specifics of transformation (even the
command-line options are mostly not hard-coded) and regards the transformation
structure as an abstract graph. The structure of this graph is described in
high-level TableGen code, from which an efficient C++ representation is
automatically derived. This makes it possible to adapt LLVMC for other
purposes - for example, as a build tool for game resources.</p>
<p>Because LLVMC employs <a class="reference external" href="http://llvm.org/docs/TableGenFundamentals.html">TableGen</a> as its configuration language, you
need to be familiar with it to customize LLVMC.</p>
</div>
<div class="section" id="compiling-with-llvmc">
<h1><a class="toc-backref" href="#id8">Compiling with <tt class="docutils literal">llvmc</tt></a></h1>
<p>LLVMC tries hard to be as compatible with <tt class="docutils literal">gcc</tt> as possible,
although there are some small differences. Most of the time, however,
you shouldn't be able to notice them:</p>
<pre class="literal-block">
$ # This works as expected:
$ llvmc -O3 -Wall hello.cpp
$ ./a.out
hello
</pre>
<p>One nice feature of LLVMC is that one doesn't have to distinguish between
different compilers for different languages (think <tt class="docutils literal">g++</tt> vs. <tt class="docutils literal">gcc</tt>) - the
right toolchain is chosen automatically based on input language names (which
are, in turn, determined from file extensions). If you want to force files
ending with &quot;.c&quot; to compile as C++, use the <tt class="docutils literal"><span class="pre">-x</span></tt> option, just like you would
do it with <tt class="docutils literal">gcc</tt>:</p>
<pre class="literal-block">
$ # hello.c is really a C++ file
$ llvmc -x c++ hello.c
$ ./a.out
hello
</pre>
<p>On the other hand, when using LLVMC as a linker to combine several C++
object files you should provide the <tt class="docutils literal"><span class="pre">--linker</span></tt> option since it's
impossible for LLVMC to choose the right linker in that case:</p>
<pre class="literal-block">
$ llvmc -c hello.cpp
$ llvmc hello.o
[A lot of link-time errors skipped]
$ llvmc --linker=c++ hello.o
$ ./a.out
hello
</pre>
<p>By default, LLVMC uses <tt class="docutils literal"><span class="pre">llvm-gcc</span></tt> to compile the source code. It is also
possible to choose the <tt class="docutils literal">clang</tt> compiler with the <tt class="docutils literal"><span class="pre">-clang</span></tt> option.</p>
</div>
<div class="section" id="predefined-options">
<h1><a class="toc-backref" href="#id9">Predefined options</a></h1>
<p>LLVMC has some built-in options that can't be overridden in the TableGen code:</p>
<ul class="simple">
<li><tt class="docutils literal"><span class="pre">-o</span> FILE</tt> - Output file name.</li>
<li><tt class="docutils literal"><span class="pre">-x</span> LANGUAGE</tt> - Specify the language of the following input files
until the next -x option.</li>
<li><tt class="docutils literal"><span class="pre">-v</span></tt> - Enable verbose mode, i.e. print out all executed commands.</li>
<li><tt class="docutils literal"><span class="pre">--save-temps</span></tt> - Write temporary files to the current directory and do not
delete them on exit. This option can also take an argument: the
<tt class="docutils literal"><span class="pre">--save-temps=obj</span></tt> switch will write files into the directory specified with
the <tt class="docutils literal"><span class="pre">-o</span></tt> option. The <tt class="docutils literal"><span class="pre">--save-temps=cwd</span></tt> and <tt class="docutils literal"><span class="pre">--save-temps</span></tt> switches are
both synonyms for the default behaviour.</li>
<li><tt class="docutils literal"><span class="pre">--temp-dir</span> DIRECTORY</tt> - Store temporary files in the given directory. This
directory is deleted on exit unless <tt class="docutils literal"><span class="pre">--save-temps</span></tt> is specified. If
<tt class="docutils literal"><span class="pre">--save-temps=obj</span></tt> is also specified, <tt class="docutils literal"><span class="pre">--temp-dir</span></tt> is given the
precedence.</li>
<li><tt class="docutils literal"><span class="pre">--check-graph</span></tt> - Check the compilation for common errors like mismatched
output/input language names, multiple default edges and cycles. Exit with code
zero if no errors were found, and return the number of found errors
otherwise. Hidden option, useful for debugging.</li>
<li><tt class="docutils literal"><span class="pre">--view-graph</span></tt> - Show a graphical representation of the compilation graph
and exit. Requires that you have <tt class="docutils literal">dot</tt> and <tt class="docutils literal">gv</tt> programs installed. Hidden
option, useful for debugging.</li>
<li><tt class="docutils literal"><span class="pre">--write-graph</span></tt> - Write a <tt class="docutils literal"><span class="pre">compilation-graph.dot</span></tt> file in the current
directory with the compilation graph description in Graphviz format (identical
to the file used by the <tt class="docutils literal"><span class="pre">--view-graph</span></tt> option). The <tt class="docutils literal"><span class="pre">-o</span></tt> option can be
used to set the output file name. Hidden option, useful for debugging.</li>
<li><tt class="docutils literal"><span class="pre">--help</span></tt>, <tt class="docutils literal"><span class="pre">--help-hidden</span></tt>, <tt class="docutils literal"><span class="pre">--version</span></tt> - These options have
their standard meaning.</li>
</ul>
</div>
<div class="section" id="compiling-llvmc-based-drivers">
<h1><a class="toc-backref" href="#id10">Compiling LLVMC-based drivers</a></h1>
<p>It's easiest to start working on your own LLVMC driver by copying the skeleton
project which lives under <tt class="docutils literal">$LLVMC_DIR/examples/Skeleton</tt>:</p>
<pre class="literal-block">
$ cd $LLVMC_DIR/examples
$ cp -r Skeleton MyDriver
$ cd MyDriver
$ ls
AutoGenerated.td Hooks.cpp Main.cpp Makefile
</pre>
<p>As you can see, our basic driver consists of only three files (not counting the
build script). <tt class="docutils literal">AutoGenerated.td</tt> contains TableGen description of the
compilation graph; its format is documented in the following
sections. <tt class="docutils literal">Hooks.cpp</tt> is an empty file that should be used for hook
definitions (see <a class="reference internal" href="#hooks">below</a>). <tt class="docutils literal">Main.cpp</tt> is just a helper used to compile the
auto-generated C++ code produced from TableGen source.</p>
<p>The first thing that you should do is to change the <tt class="docutils literal">LLVMC_BASED_DRIVER</tt>
variable in the <tt class="docutils literal">Makefile</tt>:</p>
<pre class="literal-block">
LLVMC_BASED_DRIVER=MyDriver
</pre>
<p>It can also be a good idea to put your TableGen code into a file with a less
generic name:</p>
<pre class="literal-block">
$ touch MyDriver.td
$ vim AutoGenerated.td
[...]
include &quot;MyDriver.td&quot;
</pre>
<p>If you have more than one TableGen source file, they all should be included from
<tt class="docutils literal">AutoGenerated.td</tt>, since this file is used by the build system to generate
C++ code.</p>
<p>To build your driver, just <tt class="docutils literal">cd</tt> to its source directory and run <tt class="docutils literal">make</tt>. The
resulting executable will be put into <tt class="docutils literal"><span class="pre">$LLVM_OBJ_DIR/$(BuildMode)/bin</span></tt>.</p>
<p>If you're compiling LLVM with different source and object directories, then you
must perform the following additional steps before running <tt class="docutils literal">make</tt>:</p>
<pre class="literal-block">
# LLVMC_SRC_DIR = $LLVM_SRC_DIR/tools/llvmc/
# LLVMC_OBJ_DIR = $LLVM_OBJ_DIR/tools/llvmc/
$ mkdir $LLVMC_OBJ_DIR/examples/MyDriver/
$ cp $LLVMC_SRC_DIR/examples/MyDriver/Makefile \
$LLVMC_OBJ_DIR/examples/MyDriver/
$ cd $LLVMC_OBJ_DIR/examples/MyDriver
$ make
</pre>
</div>
<div class="section" id="customizing-llvmc-the-compilation-graph">
<h1><a class="toc-backref" href="#id11">Customizing LLVMC: the compilation graph</a></h1>
<p>Each TableGen configuration file should include the common definitions:</p>
<pre class="literal-block">
include &quot;llvm/CompilerDriver/Common.td&quot;
</pre>
<p>Internally, LLVMC stores information about possible source transformations in
form of a graph. Nodes in this graph represent tools, and edges between two
nodes represent a transformation path. A special &quot;root&quot; node is used to mark
entry points for the transformations. LLVMC also assigns a weight to each edge
(more on this later) to choose between several alternative edges.</p>
<p>The definition of the compilation graph (see file <tt class="docutils literal">llvmc/src/Base.td</tt> for an
example) is just a list of edges:</p>
<pre class="literal-block">
def CompilationGraph : CompilationGraph&lt;[
Edge&lt;&quot;root&quot;, &quot;llvm_gcc_c&quot;&gt;,
Edge&lt;&quot;root&quot;, &quot;llvm_gcc_assembler&quot;&gt;,
...
Edge&lt;&quot;llvm_gcc_c&quot;, &quot;llc&quot;&gt;,
Edge&lt;&quot;llvm_gcc_cpp&quot;, &quot;llc&quot;&gt;,
...
OptionalEdge&lt;&quot;llvm_gcc_c&quot;, &quot;opt&quot;, (case (switch_on &quot;opt&quot;),
(inc_weight))&gt;,
OptionalEdge&lt;&quot;llvm_gcc_cpp&quot;, &quot;opt&quot;, (case (switch_on &quot;opt&quot;),
(inc_weight))&gt;,
...
OptionalEdge&lt;&quot;llvm_gcc_assembler&quot;, &quot;llvm_gcc_cpp_linker&quot;,
(case (input_languages_contain &quot;c++&quot;), (inc_weight),
(or (parameter_equals &quot;linker&quot;, &quot;g++&quot;),
(parameter_equals &quot;linker&quot;, &quot;c++&quot;)), (inc_weight))&gt;,
...
]&gt;;
</pre>
<p>As you can see, the edges can be either default or optional, where optional
edges are differentiated by an additional <tt class="docutils literal">case</tt> expression used to calculate
the weight of this edge. Notice also that we refer to tools via their names (as
strings). This makes it possible to add edges to an existing compilation graph
without having to know about all tool definitions used in the graph.</p>
<p>The default edges are assigned a weight of 1, and optional edges get a weight of
0 + 2*N where N is the number of tests that evaluated to true in the <tt class="docutils literal">case</tt>
expression. It is also possible to provide an integer parameter to
<tt class="docutils literal">inc_weight</tt> and <tt class="docutils literal">dec_weight</tt> - in this case, the weight is increased (or
decreased) by the provided value instead of the default 2. Default weight of an
optional edge can be changed by using the <tt class="docutils literal">default</tt> clause of the <tt class="docutils literal">case</tt>
construct.</p>
<p>When passing an input file through the graph, LLVMC picks the edge with the
maximum weight. To avoid ambiguity, there should be only one default edge
between two nodes (with the exception of the root node, which gets a special
treatment - there you are allowed to specify one default edge <em>per language</em>).</p>
<p>When multiple compilation graphs are defined, they are merged together. Multiple
edges with the same end nodes are not allowed (i.e. the graph is not a
multigraph), and will lead to a compile-time error.</p>
<p>To get a visual representation of the compilation graph (useful for debugging),
run <tt class="docutils literal">llvmc <span class="pre">--view-graph</span></tt>. You will need <tt class="docutils literal">dot</tt> and <tt class="docutils literal">gsview</tt> installed for
this to work properly.</p>
</div>
<div class="section" id="describing-options">
<h1><a class="toc-backref" href="#id12">Describing options</a></h1>
<p>Command-line options supported by the driver are defined by using an
<tt class="docutils literal">OptionList</tt>:</p>
<pre class="literal-block">
def Options : OptionList&lt;[
(switch_option &quot;E&quot;, (help &quot;Help string&quot;)),
(alias_option &quot;quiet&quot;, &quot;q&quot;)
...
]&gt;;
</pre>
<p>As you can see, the option list is just a list of DAGs, where each DAG is an
option description consisting of the option name and some properties. More than
one option list can be defined (they are all merged together in the end), which
can be handy if one wants to separate option groups syntactically.</p>
<ul>
<li><p class="first">Possible option types:</p>
<blockquote>
<ul class="simple">
<li><tt class="docutils literal">switch_option</tt> - a simple boolean switch without arguments, for example
<tt class="docutils literal"><span class="pre">-O2</span></tt> or <tt class="docutils literal"><span class="pre">-time</span></tt>. At most one occurrence is allowed by default.</li>
<li><tt class="docutils literal">parameter_option</tt> - option that takes one argument, for example
<tt class="docutils literal"><span class="pre">-std=c99</span></tt>. It is also allowed to use spaces instead of the equality
sign: <tt class="docutils literal"><span class="pre">-std</span> c99</tt>. At most one occurrence is allowed.</li>
<li><tt class="docutils literal">parameter_list_option</tt> - same as the above, but more than one option
occurrence is allowed.</li>
<li><tt class="docutils literal">prefix_option</tt> - same as the parameter_option, but the option name and
argument do not have to be separated. Example: <tt class="docutils literal"><span class="pre">-ofile</span></tt>. This can be also
specified as <tt class="docutils literal"><span class="pre">-o</span> file</tt>; however, <tt class="docutils literal"><span class="pre">-o=file</span></tt> will be parsed incorrectly
(<tt class="docutils literal">=file</tt> will be interpreted as option value). At most one occurrence is
allowed.</li>
<li><tt class="docutils literal">prefix_list_option</tt> - same as the above, but more than one occurrence of
the option is allowed; example: <tt class="docutils literal"><span class="pre">-lm</span> <span class="pre">-lpthread</span></tt>.</li>
<li><tt class="docutils literal">alias_option</tt> - a special option type for creating aliases. Unlike other
option types, aliases are not allowed to have any properties besides the
aliased option name.
Usage example: <tt class="docutils literal">(alias_option &quot;preprocess&quot;, &quot;E&quot;)</tt></li>
<li><tt class="docutils literal">switch_list_option</tt> - like <tt class="docutils literal">switch_option</tt> with the <tt class="docutils literal">zero_or_more</tt>
property, but remembers how many times the switch was turned on. Useful
mostly for forwarding. Example: when <tt class="docutils literal"><span class="pre">-foo</span></tt> is a switch option (with the
<tt class="docutils literal">zero_or_more</tt> property), the command <tt class="docutils literal">driver <span class="pre">-foo</span> <span class="pre">-foo</span></tt> is forwarded
as <tt class="docutils literal"><span class="pre">some-tool</span> <span class="pre">-foo</span></tt>, but when <tt class="docutils literal"><span class="pre">-foo</span></tt> is a switch list, the same command
is forwarded as <tt class="docutils literal"><span class="pre">some-tool</span> <span class="pre">-foo</span> <span class="pre">-foo</span></tt>.</li>
</ul>
</blockquote>
</li>
<li><p class="first">Possible option properties:</p>
<blockquote>
<ul class="simple">
<li><tt class="docutils literal">help</tt> - help string associated with this option. Used for <tt class="docutils literal"><span class="pre">--help</span></tt>
output.</li>
<li><tt class="docutils literal">required</tt> - this option must be specified exactly once (or, in case of
the list options without the <tt class="docutils literal">multi_val</tt> property, at least
once). Incompatible with <tt class="docutils literal">optional</tt> and <tt class="docutils literal">one_or_more</tt>.</li>
<li><tt class="docutils literal">optional</tt> - the option can be specified either zero times or exactly
once. The default for switch options. Useful only for list options in
conjunction with <tt class="docutils literal">multi_val</tt>. Incompatible with <tt class="docutils literal">required</tt>,
<tt class="docutils literal">zero_or_more</tt> and <tt class="docutils literal">one_or_more</tt>.</li>
<li><tt class="docutils literal">one_or_more</tt> - the option must be specified at least once. Can be useful
to allow switch options be both obligatory and be specified multiple
times. For list options is useful only in conjunction with <tt class="docutils literal">multi_val</tt>;
for ordinary it is synonymous with <tt class="docutils literal">required</tt>. Incompatible with
<tt class="docutils literal">required</tt>, <tt class="docutils literal">optional</tt> and <tt class="docutils literal">zero_or_more</tt>.</li>
<li><tt class="docutils literal">zero_or_more</tt> - the option can be specified zero or more times. Useful
to allow a single switch option to be specified more than
once. Incompatible with <tt class="docutils literal">required</tt>, <tt class="docutils literal">optional</tt> and <tt class="docutils literal">one_or_more</tt>.</li>
<li><tt class="docutils literal">hidden</tt> - the description of this option will not appear in
the <tt class="docutils literal"><span class="pre">--help</span></tt> output (but will appear in the <tt class="docutils literal"><span class="pre">--help-hidden</span></tt>
output).</li>
<li><tt class="docutils literal">really_hidden</tt> - the option will not be mentioned in any help
output.</li>
<li><tt class="docutils literal">comma_separated</tt> - Indicates that any commas specified for an option's
value should be used to split the value up into multiple values for the
option. This property is valid only for list options. In conjunction with
<tt class="docutils literal">forward_value</tt> can be used to implement option forwarding in style of
gcc's <tt class="docutils literal"><span class="pre">-Wa,</span></tt>.</li>
<li><tt class="docutils literal">multi_val n</tt> - this option takes <em>n</em> arguments (can be useful in some
special cases). Usage example: <tt class="docutils literal">(parameter_list_option &quot;foo&quot;, (multi_val
3))</tt>; the command-line syntax is '-foo a b c'. Only list options can have
this attribute; you can, however, use the <tt class="docutils literal">one_or_more</tt>, <tt class="docutils literal">optional</tt>
and <tt class="docutils literal">required</tt> properties.</li>
<li><tt class="docutils literal">init</tt> - this option has a default value, either a string (if it is a
parameter), or a boolean (if it is a switch; as in C++, boolean constants
are called <tt class="docutils literal">true</tt> and <tt class="docutils literal">false</tt>). List options can't have <tt class="docutils literal">init</tt>
attribute.
Usage examples: <tt class="docutils literal">(switch_option &quot;foo&quot;, (init true))</tt>; <tt class="docutils literal">(prefix_option
&quot;bar&quot;, (init <span class="pre">&quot;baz&quot;))</span></tt>.</li>
</ul>
</blockquote>
</li>
</ul>
</div>
<div class="section" id="conditional-evaluation">
<span id="case"></span><h1><a class="toc-backref" href="#id13">Conditional evaluation</a></h1>
<p>The 'case' construct is the main means by which programmability is achieved in
LLVMC. It can be used to calculate edge weights, program actions and modify the
shell commands to be executed. The 'case' expression is designed after the
similarly-named construct in functional languages and takes the form <tt class="docutils literal">(case
(test_1), statement_1, (test_2), statement_2, ... (test_N), statement_N)</tt>. The
statements are evaluated only if the corresponding tests evaluate to true.</p>
<p>Examples:</p>
<pre class="literal-block">
// Edge weight calculation
// Increases edge weight by 5 if &quot;-A&quot; is provided on the
// command-line, and by 5 more if &quot;-B&quot; is also provided.
(case
(switch_on &quot;A&quot;), (inc_weight 5),
(switch_on &quot;B&quot;), (inc_weight 5))
// Tool command line specification
// Evaluates to &quot;cmdline1&quot; if the option &quot;-A&quot; is provided on the
// command line; to &quot;cmdline2&quot; if &quot;-B&quot; is provided;
// otherwise to &quot;cmdline3&quot;.
(case
(switch_on &quot;A&quot;), &quot;cmdline1&quot;,
(switch_on &quot;B&quot;), &quot;cmdline2&quot;,
(default), &quot;cmdline3&quot;)
</pre>
<p>Note the slight difference in 'case' expression handling in contexts of edge
weights and command line specification - in the second example the value of the
<tt class="docutils literal">&quot;B&quot;</tt> switch is never checked when switch <tt class="docutils literal">&quot;A&quot;</tt> is enabled, and the whole
expression always evaluates to <tt class="docutils literal">&quot;cmdline1&quot;</tt> in that case.</p>
<p>Case expressions can also be nested, i.e. the following is legal:</p>
<pre class="literal-block">
(case (switch_on &quot;E&quot;), (case (switch_on &quot;o&quot;), ..., (default), ...)
(default), ...)
</pre>
<p>You should, however, try to avoid doing that because it hurts readability. It is
usually better to split tool descriptions and/or use TableGen inheritance
instead.</p>
<ul class="simple">
<li>Possible tests are:<ul>
<li><tt class="docutils literal">switch_on</tt> - Returns true if a given command-line switch is provided by
the user. Can be given multiple arguments, in that case <tt class="docutils literal">(switch_on &quot;foo&quot;,
&quot;bar&quot;, &quot;baz&quot;)</tt> is equivalent to <tt class="docutils literal">(and (switch_on <span class="pre">&quot;foo&quot;),</span> (switch_on
<span class="pre">&quot;bar&quot;),</span> (switch_on <span class="pre">&quot;baz&quot;))</span></tt>.
Example: <tt class="docutils literal">(switch_on &quot;opt&quot;)</tt>.</li>
<li><tt class="docutils literal">any_switch_on</tt> - Given a number of switch options, returns true if any of
the switches is turned on.
Example: <tt class="docutils literal">(any_switch_on &quot;foo&quot;, &quot;bar&quot;, &quot;baz&quot;)</tt> is equivalent to <tt class="docutils literal">(or
(switch_on <span class="pre">&quot;foo&quot;),</span> (switch_on <span class="pre">&quot;bar&quot;),</span> (switch_on <span class="pre">&quot;baz&quot;))</span></tt>.</li>
<li><tt class="docutils literal">parameter_equals</tt> - Returns true if a command-line parameter (first
argument) equals a given value (second argument).
Example: <tt class="docutils literal">(parameter_equals &quot;W&quot;, &quot;all&quot;)</tt>.</li>
<li><tt class="docutils literal">element_in_list</tt> - Returns true if a command-line parameter list (first
argument) contains a given value (second argument).
Example: <tt class="docutils literal">(element_in_list &quot;l&quot;, &quot;pthread&quot;)</tt>.</li>
<li><tt class="docutils literal">input_languages_contain</tt> - Returns true if a given language
belongs to the current input language set.
Example: <tt class="docutils literal">(input_languages_contain <span class="pre">&quot;c++&quot;)</span></tt>.</li>
<li><tt class="docutils literal">in_language</tt> - Evaluates to true if the input file language is equal to
the argument. At the moment works only with <tt class="docutils literal">command</tt> and <tt class="docutils literal">actions</tt> (on
non-join nodes).
Example: <tt class="docutils literal">(in_language <span class="pre">&quot;c++&quot;)</span></tt>.</li>
<li><tt class="docutils literal">not_empty</tt> - Returns true if a given option (which should be either a
parameter or a parameter list) is set by the user. Like <tt class="docutils literal">switch_on</tt>, can
be also given multiple arguments.
Examples: <tt class="docutils literal">(not_empty &quot;o&quot;)</tt>, <tt class="docutils literal">(not_empty &quot;o&quot;, &quot;l&quot;)</tt>.</li>
<li><tt class="docutils literal">any_not_empty</tt> - Returns true if <tt class="docutils literal">not_empty</tt> returns true for any of
the provided options.
Example: <tt class="docutils literal">(any_not_empty &quot;foo&quot;, &quot;bar&quot;, &quot;baz&quot;)</tt> is equivalent to <tt class="docutils literal">(or
(not_empty <span class="pre">&quot;foo&quot;),</span> (not_empty <span class="pre">&quot;bar&quot;),</span> (not_empty <span class="pre">&quot;baz&quot;))</span></tt>.</li>
<li><tt class="docutils literal">empty</tt> - The opposite of <tt class="docutils literal">not_empty</tt>. Equivalent to <tt class="docutils literal">(not (not_empty
X))</tt>. Can be given multiple arguments.</li>
<li><tt class="docutils literal">any_not_empty</tt> - Returns true if <tt class="docutils literal">not_empty</tt> returns true for any of
the provided options.
Example: <tt class="docutils literal">(any_empty &quot;foo&quot;, &quot;bar&quot;, &quot;baz&quot;)</tt> is equivalent to <tt class="docutils literal">(or
(not_empty <span class="pre">&quot;foo&quot;),</span> (not_empty <span class="pre">&quot;bar&quot;),</span> (not_empty <span class="pre">&quot;baz&quot;))</span></tt>.</li>
<li><tt class="docutils literal">single_input_file</tt> - Returns true if there was only one input file
provided on the command-line. Used without arguments:
<tt class="docutils literal">(single_input_file)</tt>.</li>
<li><tt class="docutils literal">multiple_input_files</tt> - Equivalent to <tt class="docutils literal">(not (single_input_file))</tt> (the
case of zero input files is considered an error).</li>
<li><tt class="docutils literal">default</tt> - Always evaluates to true. Should always be the last
test in the <tt class="docutils literal">case</tt> expression.</li>
<li><tt class="docutils literal">and</tt> - A standard logical combinator that returns true iff all of
its arguments return true. Used like this: <tt class="docutils literal">(and (test1), (test2),
... (testN))</tt>. Nesting of <tt class="docutils literal">and</tt> and <tt class="docutils literal">or</tt> is allowed, but not
encouraged.</li>
<li><tt class="docutils literal">or</tt> - A logical combinator that returns true iff any of its arguments
return true.
Example: <tt class="docutils literal">(or (test1), (test2), ... (testN))</tt>.</li>
<li><tt class="docutils literal">not</tt> - Standard unary logical combinator that negates its
argument.
Example: <tt class="docutils literal">(not (or (test1), (test2), ... <span class="pre">(testN)))</span></tt>.</li>
</ul>
</li>
</ul>
</div>
<div class="section" id="writing-a-tool-description">
<h1><a class="toc-backref" href="#id14">Writing a tool description</a></h1>
<p>As was said earlier, nodes in the compilation graph represent tools, which are
described separately. A tool definition looks like this (taken from the
<tt class="docutils literal">llvmc/src/Base.td</tt> file):</p>
<pre class="literal-block">
def llvm_gcc_cpp : Tool&lt;[
(in_language &quot;c++&quot;),
(out_language &quot;llvm-assembler&quot;),
(output_suffix &quot;bc&quot;),
(command &quot;llvm-g++ -c -emit-llvm&quot;),
(sink)
]&gt;;
</pre>
<p>This defines a new tool called <tt class="docutils literal">llvm_gcc_cpp</tt>, which is an alias for
<tt class="docutils literal"><span class="pre">llvm-g++</span></tt>. As you can see, a tool definition is just a list of properties;
most of them should be self-explanatory. The <tt class="docutils literal">sink</tt> property means that this
tool should be passed all command-line options that aren't mentioned in the
option list.</p>
<p>The complete list of all currently implemented tool properties follows.</p>
<ul class="simple">
<li>Possible tool properties:<ul>
<li><tt class="docutils literal">in_language</tt> - input language name. Can be given multiple arguments, in
case the tool supports multiple input languages. Used for typechecking and
mapping file extensions to tools.</li>
<li><tt class="docutils literal">out_language</tt> - output language name. Multiple output languages are
allowed. Used for typechecking the compilation graph.</li>
<li><tt class="docutils literal">output_suffix</tt> - output file suffix. Can also be changed dynamically, see
documentation on <a class="reference internal" href="#actions">actions</a>.</li>
</ul>
</li>
</ul>
<blockquote>
<ul class="simple">
<li><tt class="docutils literal">command</tt> - the actual command used to run the tool. You can use output
redirection with <tt class="docutils literal">&gt;</tt>, hook invocations (<tt class="docutils literal">$CALL</tt>), environment variables
(via <tt class="docutils literal">$ENV</tt>) and the <tt class="docutils literal">case</tt> construct.</li>
<li><tt class="docutils literal">join</tt> - this tool is a &quot;join node&quot; in the graph, i.e. it gets a list of
input files and joins them together. Used for linkers.</li>
<li><tt class="docutils literal">sink</tt> - all command-line options that are not handled by other tools are
passed to this tool.</li>
<li><tt class="docutils literal">actions</tt> - A single big <tt class="docutils literal">case</tt> expression that specifies how this tool
reacts on command-line options (described in more detail <a class="reference internal" href="#actions">below</a>).</li>
</ul>
</blockquote>
<blockquote>
<ul class="simple">
<li><tt class="docutils literal">out_file_option</tt>, <tt class="docutils literal">in_file_option</tt> - Options appended to the
<tt class="docutils literal">command</tt> string to designate output and input files. Default values are
<tt class="docutils literal"><span class="pre">&quot;-o&quot;</span></tt> and <tt class="docutils literal">&quot;&quot;</tt>, respectively.</li>
</ul>
</blockquote>
<div class="section" id="id4">
<span id="actions"></span><h2><a class="toc-backref" href="#id15">Actions</a></h2>
<p>A tool often needs to react to command-line options, and this is precisely what
the <tt class="docutils literal">actions</tt> property is for. The next example illustrates this feature:</p>
<pre class="literal-block">
def llvm_gcc_linker : Tool&lt;[
(in_language &quot;object-code&quot;),
(out_language &quot;executable&quot;),
(output_suffix &quot;out&quot;),
(command &quot;llvm-gcc&quot;),
(join),
(actions (case (not_empty &quot;L&quot;), (forward &quot;L&quot;),
(not_empty &quot;l&quot;), (forward &quot;l&quot;),
(not_empty &quot;dummy&quot;),
[(append_cmd &quot;-dummy1&quot;), (append_cmd &quot;-dummy2&quot;)])
]&gt;;
</pre>
<p>The <tt class="docutils literal">actions</tt> tool property is implemented on top of the omnipresent <tt class="docutils literal">case</tt>
expression. It associates one or more different <em>actions</em> with given
conditions - in the example, the actions are <tt class="docutils literal">forward</tt>, which forwards a given
option unchanged, and <tt class="docutils literal">append_cmd</tt>, which appends a given string to the tool
execution command. Multiple actions can be associated with a single condition by
using a list of actions (used in the example to append some dummy options). The
same <tt class="docutils literal">case</tt> construct can also be used in the <tt class="docutils literal">cmd_line</tt> property to modify
the tool command line.</p>
<p>The &quot;join&quot; property used in the example means that this tool behaves like a
linker.</p>
<p>The list of all possible actions follows.</p>
<ul>
<li><p class="first">Possible actions:</p>
<blockquote>
<ul class="simple">
<li><tt class="docutils literal">append_cmd</tt> - Append a string to the tool invocation command.
Example: <tt class="docutils literal">(case (switch_on <span class="pre">&quot;pthread&quot;),</span> (append_cmd <span class="pre">&quot;-lpthread&quot;))</span></tt>.</li>
<li><tt class="docutils literal">error</tt> - Exit with error.
Example: <tt class="docutils literal">(error &quot;Mixing <span class="pre">-c</span> and <span class="pre">-S</span> is not <span class="pre">allowed!&quot;)</span></tt>.</li>
<li><tt class="docutils literal">warning</tt> - Print a warning.
Example: <tt class="docutils literal">(warning &quot;Specifying both <span class="pre">-O1</span> and <span class="pre">-O2</span> is <span class="pre">meaningless!&quot;)</span></tt>.</li>
<li><tt class="docutils literal">forward</tt> - Forward the option unchanged.
Example: <tt class="docutils literal">(forward &quot;Wall&quot;)</tt>.</li>
<li><tt class="docutils literal">forward_as</tt> - Change the option's name, but forward the argument
unchanged.
Example: <tt class="docutils literal">(forward_as &quot;O0&quot;, <span class="pre">&quot;--disable-optimization&quot;)</span></tt>.</li>
<li><tt class="docutils literal">forward_value</tt> - Forward only option's value. Cannot be used with switch
options (since they don't have values), but works fine with lists.
Example: <tt class="docutils literal">(forward_value <span class="pre">&quot;Wa,&quot;)</span></tt>.</li>
<li><tt class="docutils literal">forward_transformed_value</tt> - As above, but applies a hook to the
option's value before forwarding (see <a class="reference internal" href="#hooks">below</a>). When
<tt class="docutils literal">forward_transformed_value</tt> is applied to a list
option, the hook must have signature
<tt class="docutils literal"><span class="pre">std::string</span> <span class="pre">hooks::HookName</span> (const <span class="pre">std::vector&lt;std::string&gt;&amp;)</span></tt>.
Example: <tt class="docutils literal">(forward_transformed_value &quot;m&quot;, &quot;ConvertToMAttr&quot;)</tt>.</li>
<li><tt class="docutils literal">output_suffix</tt> - Modify the output suffix of this tool.
Example: <tt class="docutils literal">(output_suffix &quot;i&quot;)</tt>.</li>
<li><tt class="docutils literal">stop_compilation</tt> - Stop compilation after this tool processes its
input. Used without arguments.
Example: <tt class="docutils literal">(stop_compilation)</tt>.</li>
</ul>
</blockquote>
</li>
</ul>
</div>
</div>
<div class="section" id="language-map">
<h1><a class="toc-backref" href="#id16">Language map</a></h1>
<p>If you are adding support for a new language to LLVMC, you'll need to modify the
language map, which defines mappings from file extensions to language names. It
is used to choose the proper toolchain(s) for a given input file set. Language
map definition looks like this:</p>
<pre class="literal-block">
def LanguageMap : LanguageMap&lt;
[LangToSuffixes&lt;&quot;c++&quot;, [&quot;cc&quot;, &quot;cp&quot;, &quot;cxx&quot;, &quot;cpp&quot;, &quot;CPP&quot;, &quot;c++&quot;, &quot;C&quot;]&gt;,
LangToSuffixes&lt;&quot;c&quot;, [&quot;c&quot;]&gt;,
...
]&gt;;
</pre>
<p>For example, without those definitions the following command wouldn't work:</p>
<pre class="literal-block">
$ llvmc hello.cpp
llvmc: Unknown suffix: cpp
</pre>
<p>The language map entries are needed only for the tools that are linked from the
root node. A tool can have multiple output languages.</p>
</div>
<div class="section" id="option-preprocessor">
<h1><a class="toc-backref" href="#id17">Option preprocessor</a></h1>
<p>It is sometimes useful to run error-checking code before processing the
compilation graph. For example, if optimization options &quot;-O1&quot; and &quot;-O2&quot; are
implemented as switches, we might want to output a warning if the user invokes
the driver with both of these options enabled.</p>
<p>The <tt class="docutils literal">OptionPreprocessor</tt> feature is reserved specially for these
occasions. Example (adapted from <tt class="docutils literal">llvm/src/Base.td.in</tt>):</p>
<pre class="literal-block">
def Preprocess : OptionPreprocessor&lt;
(case (not (any_switch_on &quot;O0&quot;, &quot;O1&quot;, &quot;O2&quot;, &quot;O3&quot;)),
(set_option &quot;O2&quot;),
(and (switch_on &quot;O3&quot;), (any_switch_on &quot;O0&quot;, &quot;O1&quot;, &quot;O2&quot;)),
(unset_option &quot;O0&quot;, &quot;O1&quot;, &quot;O2&quot;),
(and (switch_on &quot;O2&quot;), (any_switch_on &quot;O0&quot;, &quot;O1&quot;)),
(unset_option &quot;O0&quot;, &quot;O1&quot;),
(and (switch_on &quot;O1&quot;), (switch_on &quot;O0&quot;)),
(unset_option &quot;O0&quot;))
&gt;;
</pre>
<p>Here, <tt class="docutils literal">OptionPreprocessor</tt> is used to unset all spurious <tt class="docutils literal"><span class="pre">-O</span></tt> options so
that they are not forwarded to the compiler. If no optimization options are
specified, <tt class="docutils literal"><span class="pre">-O2</span></tt> is enabled.</p>
<p><tt class="docutils literal">OptionPreprocessor</tt> is basically a single big <tt class="docutils literal">case</tt> expression, which is
evaluated only once right after the driver is started. The only allowed actions
in <tt class="docutils literal">OptionPreprocessor</tt> are <tt class="docutils literal">error</tt>, <tt class="docutils literal">warning</tt>, and two special actions:
<tt class="docutils literal">unset_option</tt> and <tt class="docutils literal">set_option</tt>. As their names suggest, they can be used to
set or unset a given option. To set an option with <tt class="docutils literal">set_option</tt>, use the
two-argument form: <tt class="docutils literal">(set_option &quot;parameter&quot;, VALUE)</tt>. Here, <tt class="docutils literal">VALUE</tt> can be
either a string, a string list, or a boolean constant.</p>
<p>For convenience, <tt class="docutils literal">set_option</tt> and <tt class="docutils literal">unset_option</tt> also work with multiple
arguments. That is, instead of <tt class="docutils literal">[(unset_option <span class="pre">&quot;A&quot;),</span> (unset_option <span class="pre">&quot;B&quot;)]</span></tt> you
can use <tt class="docutils literal">(unset_option &quot;A&quot;, &quot;B&quot;)</tt>. Obviously, <tt class="docutils literal">(set_option &quot;A&quot;, &quot;B&quot;)</tt> is
only valid if both <tt class="docutils literal">A</tt> and <tt class="docutils literal">B</tt> are switches.</p>
</div>
<div class="section" id="more-advanced-topics">
<h1><a class="toc-backref" href="#id18">More advanced topics</a></h1>
<div class="section" id="hooks-and-environment-variables">
<span id="hooks"></span><h2><a class="toc-backref" href="#id19">Hooks and environment variables</a></h2>
<p>Normally, LLVMC searches for programs in the system <tt class="docutils literal">PATH</tt>. Sometimes, this is
not sufficient: for example, we may want to specify tool paths or names in the
configuration file. This can be achieved via the hooks mechanism. To write your
own hooks, add their definitions to the <tt class="docutils literal">Hooks.cpp</tt> or drop a <tt class="docutils literal">.cpp</tt> file
into your driver directory. Hooks should live in the <tt class="docutils literal">hooks</tt> namespace and
have the signature <tt class="docutils literal"><span class="pre">std::string</span> <span class="pre">hooks::MyHookName</span> ([const char* Arg0 [ const
char* Arg2 [, <span class="pre">...]]])</span></tt>. They can be used from the <tt class="docutils literal">command</tt> tool property:</p>
<pre class="literal-block">
(command &quot;$CALL(MyHook)/path/to/file -o $CALL(AnotherHook)&quot;)
</pre>
<p>To pass arguments to hooks, use the following syntax:</p>
<pre class="literal-block">
(command &quot;$CALL(MyHook, 'Arg1', 'Arg2', 'Arg # 3')/path/to/file -o1 -o2&quot;)
</pre>
<p>It is also possible to use environment variables in the same manner:</p>
<pre class="literal-block">
(command &quot;$ENV(VAR1)/path/to/file -o $ENV(VAR2)&quot;)
</pre>
<p>To change the command line string based on user-provided options use
the <tt class="docutils literal">case</tt> expression (documented <a class="reference internal" href="#case">above</a>):</p>
<pre class="literal-block">
(command
(case
(switch_on &quot;E&quot;),
&quot;llvm-g++ -E -x c $INFILE -o $OUTFILE&quot;,
(default),
&quot;llvm-g++ -c -x c $INFILE -o $OUTFILE -emit-llvm&quot;))
</pre>
</div>
<div class="section" id="debugging">
<h2><a class="toc-backref" href="#id20">Debugging</a></h2>
<p>When writing LLVMC-based drivers, it can be useful to get a visual view of the
resulting compilation graph. This can be achieved via the command line option
<tt class="docutils literal"><span class="pre">--view-graph</span></tt> (which assumes that <a class="reference external" href="http://www.graphviz.org/">Graphviz</a> and <a class="reference external" href="http://pages.cs.wisc.edu/~ghost/">Ghostview</a> are
installed). There is also a <tt class="docutils literal"><span class="pre">--write-graph</span></tt> option that creates a Graphviz
source file (<tt class="docutils literal"><span class="pre">compilation-graph.dot</span></tt>) in the current directory.</p>
<p>Another useful <tt class="docutils literal">llvmc</tt> option is <tt class="docutils literal"><span class="pre">--check-graph</span></tt>. It checks the compilation
graph for common errors like mismatched output/input language names, multiple
default edges and cycles. When invoked with <tt class="docutils literal"><span class="pre">--check-graph</span></tt>, <tt class="docutils literal">llvmc</tt> doesn't
perform any compilation tasks and returns the number of encountered errors as
its status code. In the future, these checks will be performed at compile-time
and this option will disappear.</p>
</div>
<div class="section" id="conditioning-on-the-executable-name">
<h2><a class="toc-backref" href="#id21">Conditioning on the executable name</a></h2>
<p>For now, the executable name (the value passed to the driver in <tt class="docutils literal">argv[0]</tt>) is
accessible only in the C++ code (i.e. hooks). Use the following code:</p>
<pre class="literal-block">
namespace llvmc {
extern const char* ProgramName;
}
namespace hooks {
std::string MyHook() {
//...
if (strcmp(ProgramName, &quot;mydriver&quot;) == 0) {
//...
}
} // end namespace hooks
</pre>
<p>In general, you're encouraged not to make the behaviour dependent on the
executable file name, and use command-line switches instead. See for example how
the <tt class="docutils literal">llvmc</tt> program behaves when it needs to choose the correct linker options
(think <tt class="docutils literal">g++</tt> vs. <tt class="docutils literal">gcc</tt>).</p>
<hr />
<address>
<a href="http://jigsaw.w3.org/css-validator/check/referer">
<img src="http://jigsaw.w3.org/css-validator/images/vcss-blue"
alt="Valid CSS" /></a>
<a href="http://validator.w3.org/check?uri=referer">
<img src="http://www.w3.org/Icons/valid-xhtml10-blue"
alt="Valid XHTML 1.0 Transitional"/></a>
<a href="mailto:foldr@codedgers.com">Mikhail Glushenkov</a><br />
<a href="http://llvm.org">LLVM Compiler Infrastructure</a><br />
Last modified: $Date: 2011-05-07 00:11:29 +0200 (Sat, 07 May 2011) $
</address></div>
</div>
</div>
</body>
</html>

View File

@ -1,125 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.6: http://docutils.sourceforge.net/" />
<title>Tutorial - Using LLVMC</title>
<link rel="stylesheet" href="llvm.css" type="text/css" />
</head>
<body>
<div class="document" id="tutorial-using-llvmc">
<h1 class="title">Tutorial - Using LLVMC</h1>
<!-- This file was automatically generated by rst2html.
Please do not edit directly!
The ReST source lives in the directory 'tools/llvmc/doc'. -->
<div class="contents topic" id="contents">
<p class="topic-title first">Contents</p>
<ul class="simple">
<li><a class="reference internal" href="#introduction" id="id1">Introduction</a></li>
<li><a class="reference internal" href="#using-the-llvmc-program" id="id2">Using the <tt class="docutils literal">llvmc</tt> program</a></li>
<li><a class="reference internal" href="#using-llvmc-to-generate-toolchain-drivers" id="id3">Using LLVMC to generate toolchain drivers</a></li>
</ul>
</div>
<div class="doc_author">
<p>Written by <a href="mailto:foldr@codedgers.com">Mikhail Glushenkov</a></p>
</div><div class="section" id="introduction">
<h1><a class="toc-backref" href="#id1">Introduction</a></h1>
<p>LLVMC is a generic compiler driver, which plays the same role for LLVM as the
<tt class="docutils literal">gcc</tt> program does for GCC - the difference being that LLVMC is designed to be
more adaptable and easier to customize. Most of LLVMC functionality is
implemented via high-level TableGen code, from which a corresponding C++ source
file is automatically generated. This tutorial describes the basic usage and
configuration of LLVMC.</p>
</div>
<div class="section" id="using-the-llvmc-program">
<h1><a class="toc-backref" href="#id2">Using the <tt class="docutils literal">llvmc</tt> program</a></h1>
<p>In general, <tt class="docutils literal">llvmc</tt> tries to be command-line compatible with <tt class="docutils literal">gcc</tt> as much
as possible, so most of the familiar options work:</p>
<pre class="literal-block">
$ llvmc -O3 -Wall hello.cpp
$ ./a.out
hello
</pre>
<p>This will invoke <tt class="docutils literal"><span class="pre">llvm-g++</span></tt> under the hood (you can see which commands are
executed by using the <tt class="docutils literal"><span class="pre">-v</span></tt> option). For further help on command-line LLVMC
usage, refer to the <tt class="docutils literal">llvmc <span class="pre">--help</span></tt> output.</p>
</div>
<div class="section" id="using-llvmc-to-generate-toolchain-drivers">
<h1><a class="toc-backref" href="#id3">Using LLVMC to generate toolchain drivers</a></h1>
<p>LLVMC-based drivers are written mostly using <a class="reference external" href="http://llvm.org/docs/TableGenFundamentals.html">TableGen</a>, so you need to be
familiar with it to get anything done.</p>
<p>Start by compiling <tt class="docutils literal">example/Simple</tt>, which is a primitive wrapper for
<tt class="docutils literal">gcc</tt>:</p>
<pre class="literal-block">
$ cd $LLVM_OBJ_DIR/tools/examples/Simple
$ make
$ cat &gt; hello.c
#include &lt;stdio.h&gt;
int main() { printf(&quot;Hello\n&quot;); }
$ $LLVM_BIN_DIR/Simple -v hello.c
gcc hello.c -o hello.out
$ ./hello.out
Hello
</pre>
<p>We have thus produced a simple driver called, appropriately, <tt class="docutils literal">Simple</tt>, from
the input TableGen file <tt class="docutils literal">Simple.td</tt>. The <tt class="docutils literal">llvmc</tt> program itself is generated
using a similar process (see <tt class="docutils literal">llvmc/src</tt>). Contents of the file <tt class="docutils literal">Simple.td</tt>
look like this:</p>
<pre class="literal-block">
// Include common definitions
include &quot;llvm/CompilerDriver/Common.td&quot;
// Tool descriptions
def gcc : Tool&lt;
[(in_language &quot;c&quot;),
(out_language &quot;executable&quot;),
(output_suffix &quot;out&quot;),
(command &quot;gcc&quot;),
(sink),
// -o is what is used by default, out_file_option here is included for
// instructive purposes.
(out_file_option &quot;-o&quot;)
]&gt;;
// Language map
def LanguageMap : LanguageMap&lt;[(lang_to_suffixes &quot;c&quot;, &quot;c&quot;)]&gt;;
// Compilation graph
def CompilationGraph : CompilationGraph&lt;[(edge &quot;root&quot;, &quot;gcc&quot;)]&gt;;
</pre>
<p>As you can see, this file consists of three parts: tool descriptions, language
map, and the compilation graph definition.</p>
<p>At the heart of LLVMC is the idea of a compilation graph: vertices in this graph
are tools, and edges represent a transformation path between two tools (for
example, assembly source produced by the compiler can be transformed into
executable code by an assembler). The compilation graph is basically a list of
edges; a special node named <tt class="docutils literal">root</tt> is used to mark graph entry points.</p>
<p>Tool descriptions are represented as property lists: most properties in the
example above should be self-explanatory; the <tt class="docutils literal">sink</tt> property means that all
options lacking an explicit description should be forwarded to this tool.</p>
<p>The <tt class="docutils literal">LanguageMap</tt> associates a language name with a list of suffixes and is
used for deciding which toolchain corresponds to a given input file.</p>
<p>To learn more about writing your own drivers with LLVMC, refer to the reference
manual and examples in the <tt class="docutils literal">examples</tt> directory. Of a particular interest is
the <tt class="docutils literal">Skeleton</tt> example, which can serve as a template for your LLVMC-based
drivers.</p>
<hr />
<address>
<a href="http://jigsaw.w3.org/css-validator/check/referer">
<img src="http://jigsaw.w3.org/css-validator/images/vcss-blue"
alt="Valid CSS" /></a>
<a href="http://validator.w3.org/check?uri=referer">
<img src="http://www.w3.org/Icons/valid-xhtml10-blue"
alt="Valid XHTML 1.0 Transitional"/></a>
<a href="mailto:foldr@codedgers.com">Mikhail Glushenkov</a><br />
<a href="http://llvm.org">LLVM Compiler Infrastructure</a><br />
Last modified: $Date: 2008-12-11 11:34:48 -0600 (Thu, 11 Dec 2008) $
</address></div>
</div>
</body>
</html>

View File

@ -207,7 +207,11 @@
<li><b>Chris Lattner</b>: Everything not covered by someone else.</li>
<li><b>Duncan Sands</b>: llvm-gcc 4.2.</li>
<li><b>John McCall</b>: Clang LLVM IR generation.</li>
<li><b>Jakob Olesen</b>: Register allocators and TableGen.</li>
<li><b>Duncan Sands</b>: dragonegg and llvm-gcc 4.2.</li>
</ol>
<p>Note that code ownership is completely different than reviewers: anyone can
@ -492,8 +496,9 @@
<div>
<p>This section addresses the issues of copyright, license and patents for the
LLVM project. Currently, the University of Illinois is the LLVM copyright
holder and the terms of its license to LLVM users and developers is the
LLVM project. The copyright holder for the code is held by the individual
contributors of the code and the terms of its license to LLVM users and
developers is the
<a href="http://www.opensource.org/licenses/UoI-NCSA.php">University of
Illinois/NCSA Open Source License</a>.</p>
@ -611,7 +616,7 @@
Written by the
<a href="mailto:llvm-oversight@cs.uiuc.edu">LLVM Oversight Group</a><br>
<a href="http://llvm.org/">The LLVM Compiler Infrastructure</a><br>
Last modified: $Date: 2011-04-23 02:30:22 +0200 (Sat, 23 Apr 2011) $
Last modified: $Date: 2011-10-07 19:26:38 +0200 (Fri, 07 Oct 2011) $
</address>
</body>
</html>

View File

@ -33,9 +33,6 @@
</ol></li>
<li><a href="#format_common_intrinsics">Exception Handling Intrinsics</a>
<ol>
<li><a href="#llvm_eh_exception"><tt>llvm.eh.exception</tt></a></li>
<li><a href="#llvm_eh_selector"><tt>llvm.eh.selector</tt></a></li>
<li><a href="#llvm_eh_resume"><tt>llvm.eh.resume</tt></a></li>
<li><a href="#llvm_eh_typeid_for"><tt>llvm.eh.typeid.for</tt></a></li>
<li><a href="#llvm_eh_sjlj_setjmp"><tt>llvm.eh.sjlj.setjmp</tt></a></li>
<li><a href="#llvm_eh_sjlj_longjmp"><tt>llvm.eh.sjlj.longjmp</tt></a></li>
@ -48,7 +45,6 @@
<li><a href="#unwind_tables">Exception Handling Frame</a></li>
<li><a href="#exception_tables">Exception Tables</a></li>
</ol></li>
<li><a href="#todo">ToDo</a></li>
</ul>
</td>
</tr></table>
@ -69,7 +65,7 @@
handling information takes, which is useful for those interested in creating
front-ends or dealing directly with the information. Further, this document
provides specific examples of what exception handling information is used for
in C/C++.</p>
in C and C++.</p>
<!-- ======================================================================= -->
<h3>
@ -96,8 +92,8 @@
Exception Handling</a>. A description of the exception frame format can be
found at
<a href="http://refspecs.freestandards.org/LSB_3.0.0/LSB-Core-generic/LSB-Core-generic/ehframechpt.html">Exception
Frames</a>, with details of the DWARF 3 specification at
<a href="http://www.eagercon.com/dwarf/dwarf3std.htm">DWARF 3 Standard</a>.
Frames</a>, with details of the DWARF 4 specification at
<a href="http://dwarfstd.org/Dwarf4Std.php">DWARF 4 Standard</a>.
A description for the C++ exception table formats can be found at
<a href="http://www.codesourcery.com/cxx-abi/exceptions.pdf">Exception Handling
Tables</a>.</p>
@ -116,10 +112,10 @@
<a href="#llvm_eh_sjlj_longjmp"><tt>llvm.eh.sjlj.longjmp</tt></a> to
handle control flow for exception handling.</p>
<p>For each function which does exception processing, be it try/catch blocks
or cleanups, that function registers itself on a global frame list. When
exceptions are being unwound, the runtime uses this list to identify which
functions need processing.<p>
<p>For each function which does exception processing &mdash; be
it <tt>try</tt>/<tt>catch</tt> blocks or cleanups &mdash; that function
registers itself on a global frame list. When exceptions are unwinding, the
runtime uses this list to identify which functions need processing.<p>
<p>Landing pad selection is encoded in the call site entry of the function
context. The runtime returns to the function via
@ -134,6 +130,7 @@
exceptions are thrown. As exceptions are, by their nature, intended for
uncommon code paths, DWARF exception handling is generally preferred to
SJLJ.</p>
</div>
<!-- ======================================================================= -->
@ -148,19 +145,19 @@
<p>The runtime first attempts to find an <i>exception frame</i> corresponding to
the function where the exception was thrown. If the programming language
(e.g. C++) supports exception handling, the exception frame contains a
supports exception handling (e.g. C++), the exception frame contains a
reference to an exception table describing how to process the exception. If
the language (e.g. C) does not support exception handling, or if the
the language does not support exception handling (e.g. C), or if the
exception needs to be forwarded to a prior activation, the exception frame
contains information about how to unwind the current activation and restore
the state of the prior activation. This process is repeated until the
exception is handled. If the exception is not handled and no activations
exception is handled. If the exception is not handled and no activations
remain, then the application is terminated with an appropriate error
message.</p>
<p>Because different programming languages have different behaviors when
handling exceptions, the exception handling ABI provides a mechanism for
supplying <i>personalities.</i> An exception handling personality is defined
supplying <i>personalities</i>. An exception handling personality is defined
by way of a <i>personality function</i> (e.g. <tt>__gxx_personality_v0</tt>
in C++), which receives the context of the exception, an <i>exception
structure</i> containing the exception object type and value, and a reference
@ -168,19 +165,20 @@
for the current compile unit is specified in a <i>common exception
frame</i>.</p>
<p>The organization of an exception table is language dependent. For C++, an
<p>The organization of an exception table is language dependent. For C++, an
exception table is organized as a series of code ranges defining what to do
if an exception occurs in that range. Typically, the information associated
if an exception occurs in that range. Typically, the information associated
with a range defines which types of exception objects (using C++ <i>type
info</i>) that are handled in that range, and an associated action that
should take place. Actions typically pass control to a <i>landing
should take place. Actions typically pass control to a <i>landing
pad</i>.</p>
<p>A landing pad corresponds to the code found in the <i>catch</i> portion of
a <i>try</i>/<i>catch</i> sequence. When execution resumes at a landing
pad, it receives the exception structure and a selector corresponding to
the <i>type</i> of exception thrown. The selector is then used to determine
which <i>catch</i> should actually process the exception.</p>
<p>A landing pad corresponds roughly to the code found in the <tt>catch</tt>
portion of a <tt>try</tt>/<tt>catch</tt> sequence. When execution resumes at
a landing pad, it receives an <i>exception structure</i> and a
<i>selector value</i> corresponding to the <i>type</i> of exception
thrown. The selector is then used to determine which <i>catch</i> should
actually process the exception.</p>
</div>
@ -193,11 +191,8 @@
<div>
<p>At the time of this writing, only C++ exception handling support is available
in LLVM. So the remainder of this document will be somewhat C++-centric.</p>
<p>From the C++ developers perspective, exceptions are defined in terms of the
<tt>throw</tt> and <tt>try</tt>/<tt>catch</tt> statements. In this section
<p>From a C++ developer's perspective, exceptions are defined in terms of the
<tt>throw</tt> and <tt>try</tt>/<tt>catch</tt> statements. In this section
we will describe the implementation of LLVM exception handling in terms of
C++ examples.</p>
@ -209,17 +204,22 @@
<div>
<p>Languages that support exception handling typically provide a <tt>throw</tt>
operation to initiate the exception process. Internally, a throw operation
breaks down into two steps. First, a request is made to allocate exception
space for an exception structure. This structure needs to survive beyond the
current activation. This structure will contain the type and value of the
object being thrown. Second, a call is made to the runtime to raise the
exception, passing the exception structure as an argument.</p>
operation to initiate the exception process. Internally, a <tt>throw</tt>
operation breaks down into two steps.</p>
<p>In C++, the allocation of the exception structure is done by
the <tt>__cxa_allocate_exception</tt> runtime function. The exception
raising is handled by <tt>__cxa_throw</tt>. The type of the exception is
represented using a C++ RTTI structure.</p>
<ol>
<li>A request is made to allocate exception space for an exception structure.
This structure needs to survive beyond the current activation. This
structure will contain the type and value of the object being thrown.</li>
<li>A call is made to the runtime to raise the exception, passing the
exception structure as an argument.</li>
</ol>
<p>In C++, the allocation of the exception structure is done by the
<tt>__cxa_allocate_exception</tt> runtime function. The exception raising is
handled by <tt>__cxa_throw</tt>. The type of the exception is represented
using a C++ RTTI structure.</p>
</div>
@ -231,81 +231,68 @@
<div>
<p>A call within the scope of a <i>try</i> statement can potentially raise an
exception. In those circumstances, the LLVM C++ front-end replaces the call
with an <tt>invoke</tt> instruction. Unlike a call, the <tt>invoke</tt> has
two potential continuation points: where to continue when the call succeeds
as per normal; and where to continue if the call raises an exception, either
by a throw or the unwinding of a throw.</p>
exception. In those circumstances, the LLVM C++ front-end replaces the call
with an <tt>invoke</tt> instruction. Unlike a call, the <tt>invoke</tt> has
two potential continuation points:</p>
<ol>
<li>where to continue when the call succeeds as per normal, and</li>
<li>where to continue if the call raises an exception, either by a throw or
the unwinding of a throw</li>
</ol>
<p>The term used to define a the place where an <tt>invoke</tt> continues after
an exception is called a <i>landing pad</i>. LLVM landing pads are
an exception is called a <i>landing pad</i>. LLVM landing pads are
conceptually alternative function entry points where an exception structure
reference and a type info index are passed in as arguments. The landing pad
reference and a type info index are passed in as arguments. The landing pad
saves the exception structure reference and then proceeds to select the catch
block that corresponds to the type info of the exception object.</p>
<p>Two LLVM intrinsic functions are used to convey information about the landing
pad to the back end.</p>
<p>The LLVM <a href="LangRef.html#i_landingpad"><tt>landingpad</tt>
instruction</a> is used to convey information about the landing pad to the
back end. For C++, the <tt>landingpad</tt> instruction returns a pointer and
integer pair corresponding to the pointer to the <i>exception structure</i>
and the <i>selector value</i> respectively.</p>
<ol>
<li><a href="#llvm_eh_exception"><tt>llvm.eh.exception</tt></a> takes no
arguments and returns a pointer to the exception structure. This only
returns a sensible value if called after an <tt>invoke</tt> has branched
to a landing pad. Due to code generation limitations, it must currently
be called in the landing pad itself.</li>
<li><a href="#llvm_eh_selector"><tt>llvm.eh.selector</tt></a> takes a minimum
of three arguments. The first argument is the reference to the exception
structure. The second argument is a reference to the personality function
to be used for this <tt>try</tt>/<tt>catch</tt> sequence. Each of the
remaining arguments is either a reference to the type info for
a <tt>catch</tt> statement, a <a href="#throw_filters">filter</a>
expression, or the number zero (<tt>0</tt>) representing
a <a href="#cleanups">cleanup</a>. The exception is tested against the
arguments sequentially from first to last. The result of
the <a href="#llvm_eh_selector"><tt>llvm.eh.selector</tt></a> is a
positive number if the exception matched a type info, a negative number if
it matched a filter, and zero if it matched a cleanup. If nothing is
matched, the behaviour of the program
is <a href="#restrictions">undefined</a>. This only returns a sensible
value if called after an <tt>invoke</tt> has branched to a landing pad.
Due to codegen limitations, it must currently be called in the landing pad
itself. If a type info matched, then the selector value is the index of
the type info in the exception table, which can be obtained using the
<a href="#llvm_eh_typeid_for"><tt>llvm.eh.typeid.for</tt></a>
intrinsic.</li>
</ol>
<p>The <tt>landingpad</tt> instruction takes a reference to the personality
function to be used for this <tt>try</tt>/<tt>catch</tt> sequence. The
remainder of the instruction is a list of <i>cleanup</i>, <i>catch</i>,
and <i>filter</i> clauses. The exception is tested against the clauses
sequentially from first to last. The selector value is a positive number if
the exception matched a type info, a negative number if it matched a filter,
and zero if it matched a cleanup. If nothing is matched, the behavior of
the program is <a href="#restrictions">undefined</a>. If a type info matched,
then the selector value is the index of the type info in the exception table,
which can be obtained using the
<a href="#llvm_eh_typeid_for"><tt>llvm.eh.typeid.for</tt></a> intrinsic.</p>
<p>Once the landing pad has the type info selector, the code branches to the
code for the first catch. The catch then checks the value of the type info
code for the first catch. The catch then checks the value of the type info
selector against the index of type info for that catch. Since the type info
index is not known until all the type info have been gathered in the backend,
the catch code will call the
<a href="#llvm_eh_typeid_for"><tt>llvm.eh.typeid.for</tt></a> intrinsic
to determine the index for a given type info. If the catch fails to match
the selector then control is passed on to the next catch. Note: Since the
landing pad will not be used if there is no match in the list of type info on
the call to <a href="#llvm_eh_selector"><tt>llvm.eh.selector</tt></a>, then
neither the last catch nor <i>catch all</i> need to perform the check
against the selector.</p>
index is not known until all the type infos have been gathered in the
backend, the catch code must call the
<a href="#llvm_eh_typeid_for"><tt>llvm.eh.typeid.for</tt></a> intrinsic to
determine the index for a given type info. If the catch fails to match the
selector then control is passed on to the next catch.</p>
<p>Finally, the entry and exit of catch code is bracketed with calls
to <tt>__cxa_begin_catch</tt> and <tt>__cxa_end_catch</tt>.</p>
<p>Finally, the entry and exit of catch code is bracketed with calls to
<tt>__cxa_begin_catch</tt> and <tt>__cxa_end_catch</tt>.</p>
<ul>
<li><tt>__cxa_begin_catch</tt> takes a exception structure reference as an
<li><tt>__cxa_begin_catch</tt> takes an exception structure reference as an
argument and returns the value of the exception object.</li>
<li><tt>__cxa_end_catch</tt> takes no arguments. This function:<br><br>
<ol>
<li>Locates the most recently caught exception and decrements its handler
count,</li>
<li>Removes the exception from the "caught" stack if the handler count
goes to zero, and</li>
<li>Destroys the exception if the handler count goes to zero, and the
<li>Removes the exception from the <i>caught</i> stack if the handler
count goes to zero, and</li>
<li>Destroys the exception if the handler count goes to zero and the
exception was not re-thrown by throw.</li>
</ol>
<p>Note: a rethrow from within the catch may replace this call with
<p><b>Note:</b> a rethrow from within the catch may replace this call with
a <tt>__cxa_rethrow</tt>.</p></li>
</ul>
@ -318,28 +305,26 @@
<div>
<p>A cleanup is extra code which needs to be run as part of unwinding
a scope. C++ destructors are a prominent example, but other
languages and language extensions provide a variety of different
kinds of cleanup. In general, a landing pad may need to run
arbitrary amounts of cleanup code before actually entering a catch
block. To indicate the presence of cleanups, a landing pad's call
to <a href="#llvm_eh_selector"><tt>llvm.eh.selector</tt></a> should
end with the argument <tt>i32 0</tt>; otherwise, the unwinder will
not stop at the landing pad if there are no catches or filters that
require it to.</p>
<p>A cleanup is extra code which needs to be run as part of unwinding a scope.
C++ destructors are a typical example, but other languages and language
extensions provide a variety of different kinds of cleanups. In general, a
landing pad may need to run arbitrary amounts of cleanup code before actually
entering a catch block. To indicate the presence of cleanups, a
<a href="LangRef.html#i_landingpad"><tt>landingpad</tt> instruction</a>
should have a <i>cleanup</i> clause. Otherwise, the unwinder will not stop at
the landing pad if there are no catches or filters that require it to.</p>
<p>Do not allow a new exception to propagate out of the execution of a
cleanup. This can corrupt the internal state of the unwinder.
Different languages describe different high-level semantics for
these situations: for example, C++ requires that the process be
terminated, whereas Ada cancels both exceptions and throws a third.</p>
<p><b>Note:</b> Do not allow a new exception to propagate out of the execution
of a cleanup. This can corrupt the internal state of the unwinder.
Different languages describe different high-level semantics for these
situations: for example, C++ requires that the process be terminated, whereas
Ada cancels both exceptions and throws a third.</p>
<p>When all cleanups have completed, if the exception is not handled
by the current function, resume unwinding by calling the
<a href="#llvm_eh_resume"><tt>llvm.eh.resume</tt></a> intrinsic,
passing in the results of <tt>llvm.eh.exception</tt> and
<tt>llvm.eh.selector</tt> for the original landing pad.</p>
<p>When all cleanups are finished, if the exception is not handled by the
current function, resume unwinding by calling the
<a href="LangRef.html#i_resume"><tt>resume</tt> instruction</a>, passing in
the result of the <tt>landingpad</tt> instruction for the original landing
pad.</p>
</div>
@ -350,23 +335,21 @@
<div>
<p>C++ allows the specification of which exception types can be thrown from a
function. To represent this a top level landing pad may exist to filter out
invalid types. To express this in LLVM code the landing pad will
call <a href="#llvm_eh_selector"><tt>llvm.eh.selector</tt></a>. The
arguments are a reference to the exception structure, a reference to the
personality function, the length of the filter expression (the number of type
infos plus one), followed by the type infos themselves.
<a href="#llvm_eh_selector"><tt>llvm.eh.selector</tt></a> will return a
negative value if the exception does not match any of the type infos. If no
match is found then a call to <tt>__cxa_call_unexpected</tt> should be made,
otherwise <tt>_Unwind_Resume</tt>. Each of these functions requires a
reference to the exception structure. Note that the most general form of an
<a href="#llvm_eh_selector"><tt>llvm.eh.selector</tt></a> call can contain
any number of type infos, filter expressions and cleanups (though having more
than one cleanup is pointless). The LLVM C++ front-end can generate such
<a href="#llvm_eh_selector"><tt>llvm.eh.selector</tt></a> calls due to
inlining creating nested exception handling scopes.</p>
<p>C++ allows the specification of which exception types may be thrown from a
function. To represent this, a top level landing pad may exist to filter out
invalid types. To express this in LLVM code the
<a href="LangRef.html#i_landingpad"><tt>landingpad</tt> instruction</a> will
have a filter clause. The clause consists of an array of type infos.
<tt>landingpad</tt> will return a negative value if the exception does not
match any of the type infos. If no match is found then a call
to <tt>__cxa_call_unexpected</tt> should be made, otherwise
<tt>_Unwind_Resume</tt>. Each of these functions requires a reference to the
exception structure. Note that the most general form of a
<a href="LangRef.html#i_landingpad"><tt>landingpad</tt> instruction</a> can
have any number of catch, cleanup, and filter clauses (though having more
than one cleanup is pointless). The LLVM C++ front-end can generate such
<a href="LangRef.html#i_landingpad"><tt>landingpad</tt> instructions</a> due
to inlining creating nested exception handling scopes.</p>
</div>
@ -377,29 +360,23 @@
<div>
<p>The unwinder delegates the decision of whether to stop in a call
frame to that call frame's language-specific personality function.
Not all personalities functions guarantee that they will stop to
perform cleanups: for example, the GNU C++ personality doesn't do
so unless the exception is actually caught somewhere further up the
stack. When using this personality to implement EH for a language
that guarantees that cleanups will always be run, be sure to
indicate a catch-all in the
<a href="#llvm_eh_selector"><tt>llvm.eh.selector</tt></a> call
rather than just cleanups.</p>
<p>The unwinder delegates the decision of whether to stop in a call frame to
that call frame's language-specific personality function. Not all unwinders
guarantee that they will stop to perform cleanups. For example, the GNU C++
unwinder doesn't do so unless the exception is actually caught somewhere
further up the stack.</p>
<p>In order for inlining to behave correctly, landing pads must be
prepared to handle selector results that they did not originally
advertise. Suppose that a function catches exceptions of
type <tt>A</tt>, and it's inlined into a function that catches
exceptions of type <tt>B</tt>. The inliner will update the
selector for the inlined landing pad to include the fact
that <tt>B</tt> is caught. If that landing pad assumes that it
will only be entered to catch an <tt>A</tt>, it's in for a rude
surprise. Consequently, landing pads must test for the selector
results they understand and then resume exception propagation
with the <a href="#llvm_eh_resume"><tt>llvm.eh.resume</tt></a>
intrinsic if none of the conditions match.</p>
<p>In order for inlining to behave correctly, landing pads must be prepared to
handle selector results that they did not originally advertise. Suppose that
a function catches exceptions of type <tt>A</tt>, and it's inlined into a
function that catches exceptions of type <tt>B</tt>. The inliner will update
the <tt>landingpad</tt> instruction for the inlined landing pad to include
the fact that <tt>B</tt> is also caught. If that landing pad assumes that it
will only be entered to catch an <tt>A</tt>, it's in for a rude awakening.
Consequently, landing pads must test for the selector results they understand
and then resume exception propagation with the
<a href="LangRef.html#i_resume"><tt>resume</tt> instruction</a> if none of
the conditions match.</p>
</div>
@ -412,67 +389,13 @@
<div>
<p>LLVM uses several intrinsic functions (name prefixed with "llvm.eh") to
<p>In addition to the
<a href="LangRef.html#i_landingpad"><tt>landingpad</tt></a> and
<a href="LangRef.html#i_resume"><tt>resume</tt></a> instructions, LLVM uses
several intrinsic functions (name prefixed with <i><tt>llvm.eh</tt></i>) to
provide exception handling information at various points in generated
code.</p>
<!-- ======================================================================= -->
<h4>
<a name="llvm_eh_exception">llvm.eh.exception</a>
</h4>
<div>
<pre>
i8* %<a href="#llvm_eh_exception">llvm.eh.exception</a>()
</pre>
<p>This intrinsic returns a pointer to the exception structure.</p>
</div>
<!-- ======================================================================= -->
<h4>
<a name="llvm_eh_selector">llvm.eh.selector</a>
</h4>
<div>
<pre>
i32 %<a href="#llvm_eh_selector">llvm.eh.selector</a>(i8*, i8*, ...)
</pre>
<p>This intrinsic is used to compare the exception with the given type infos,
filters and cleanups.</p>
<p><a href="#llvm_eh_selector"><tt>llvm.eh.selector</tt></a> takes a
minimum of three arguments. The first argument is the reference to
the exception structure. The second argument is a reference to the
personality function to be used for this try catch sequence. Each
of the remaining arguments is either a reference to the type info
for a catch statement, a <a href="#throw_filters">filter</a>
expression, or the number zero representing
a <a href="#cleanups">cleanup</a>. The exception is tested against
the arguments sequentially from first to last. The result of
the <a href="#llvm_eh_selector"><tt>llvm.eh.selector</tt></a> is a
positive number if the exception matched a type info, a negative
number if it matched a filter, and zero if it matched a cleanup.
If nothing is matched, or if only a cleanup is matched, different
personality functions may or may not cause control to stop at the
landing pad; see <a href="#restrictions">the restrictions</a> for
more information. If a type info matched then the selector value
is the index of the type info in the exception table, which can be
obtained using the
<a href="#llvm_eh_typeid_for"><tt>llvm.eh.typeid.for</tt></a> intrinsic.</p>
<p>If a landing pad containing a call to <tt>llvm.eh.selector</tt> is
inlined into an <tt>invoke</tt> instruction, the selector arguments
for the outer landing pad are appended to those of the inlined
landing pad. Consequently, landing pads must be written to ignore
selector values that they did not originally advertise.</p>
</div>
<!-- ======================================================================= -->
<h4>
<a name="llvm_eh_typeid_for">llvm.eh.typeid.for</a>
@ -481,40 +404,13 @@
<div>
<pre>
i32 %<a href="#llvm_eh_typeid_for">llvm.eh.typeid.for</a>(i8*)
i32 @llvm.eh.typeid.for(i8* %type_info)
</pre>
<p>This intrinsic returns the type info index in the exception table of the
current function. This value can be used to compare against the result
of <a href="#llvm_eh_selector"><tt>llvm.eh.selector</tt></a>. The single
argument is a reference to a type info.</p>
</div>
<!-- ======================================================================= -->
<h4>
<a name="llvm_eh_resume">llvm.eh.resume</a>
</h4>
<div>
<pre>
void %<a href="#llvm_eh_resume">llvm.eh.resume</a>(i8*, i32) noreturn
</pre>
<p>This intrinsic is used to resume propagation of an exception after
landing at a landing pad. The first argument should be the result
of <a href="#llvm_eh_exception">llvm.eh.exception</a> for that
landing pad, and the second argument should be the result of
<a href="#llvm_eh_selector">llvm.eh.selector</a>. When a call to
this intrinsic is inlined into an invoke, the call is transformed
into a branch to the invoke's unwind destination, using its
arguments in place of the calls
to <a href="#llvm_eh_exception">llvm.eh.exception</a> and
<a href="#llvm_eh_selector">llvm.eh.selector</a> there.</p>
<p>This intrinsic is not implicitly <tt>nounwind</tt>; calls to it
will always throw. It may not be invoked.</p>
of <a href="LangRef.html#i_landingpad"><tt>landingpad</tt> instruction</a>.
The single argument is a reference to a type info.</p>
</div>
@ -526,16 +422,16 @@
<div>
<pre>
i32 %<a href="#llvm_eh_sjlj_setjmp">llvm.eh.sjlj.setjmp</a>(i8*)
i32 @llvm.eh.sjlj.setjmp(i8* %setjmp_buf)
</pre>
<p>The SJLJ exception handling uses this intrinsic to force register saving for
the current function and to store the address of the following instruction
for use as a destination address by <a href="#llvm_eh_sjlj_longjmp">
<tt>llvm.eh.sjlj.longjmp</tt></a>. The buffer format and the overall
functioning of this intrinsic is compatible with the GCC
<tt>__builtin_setjmp</tt> implementation, allowing code built with the
two compilers to interoperate.</p>
<p>For SJLJ based exception handling, this intrinsic forces register saving for
the current function and stores the address of the following instruction for
use as a destination address
by <a href="#llvm_eh_sjlj_longjmp"><tt>llvm.eh.sjlj.longjmp</tt></a>. The
buffer format and the overall functioning of this intrinsic is compatible
with the GCC <tt>__builtin_setjmp</tt> implementation allowing code built
with the clang and GCC to interoperate.</p>
<p>The single parameter is a pointer to a five word buffer in which the calling
context is saved. The front end places the frame pointer in the first word,
@ -555,16 +451,15 @@
<div>
<pre>
void %<a href="#llvm_eh_sjlj_longjmp">llvm.eh.sjlj.setjmp</a>(i8*)
void @llvm.eh.sjlj.longjmp(i8* %setjmp_buf)
</pre>
<p>The <a href="#llvm_eh_sjlj_longjmp"><tt>llvm.eh.sjlj.longjmp</tt></a>
intrinsic is used to implement <tt>__builtin_longjmp()</tt> for SJLJ
style exception handling. The single parameter is a pointer to a
buffer populated by <a href="#llvm_eh_sjlj_setjmp">
<tt>llvm.eh.sjlj.setjmp</tt></a>. The frame pointer and stack pointer
are restored from the buffer, then control is transferred to the
destination address.</p>
<p>For SJLJ based exception handling, the <tt>llvm.eh.sjlj.longjmp</tt>
intrinsic is used to implement <tt>__builtin_longjmp()</tt>. The single
parameter is a pointer to a buffer populated
by <a href="#llvm_eh_sjlj_setjmp"><tt>llvm.eh.sjlj.setjmp</tt></a>. The frame
pointer and stack pointer are restored from the buffer, then control is
transferred to the destination address.</p>
</div>
<!-- ======================================================================= -->
@ -575,14 +470,13 @@
<div>
<pre>
i8* %<a href="#llvm_eh_sjlj_lsda">llvm.eh.sjlj.lsda</a>()
i8* @llvm.eh.sjlj.lsda()
</pre>
<p>Used for SJLJ based exception handling, the <a href="#llvm_eh_sjlj_lsda">
<tt>llvm.eh.sjlj.lsda</tt></a> intrinsic returns the address of the Language
Specific Data Area (LSDA) for the current function. The SJLJ front-end code
stores this address in the exception handling function context for use by the
runtime.</p>
<p>For SJLJ based exception handling, the <tt>llvm.eh.sjlj.lsda</tt> intrinsic
returns the address of the Language Specific Data Area (LSDA) for the current
function. The SJLJ front-end code stores this address in the exception
handling function context for use by the runtime.</p>
</div>
@ -594,13 +488,13 @@
<div>
<pre>
void %<a href="#llvm_eh_sjlj_callsite">llvm.eh.sjlj.callsite</a>(i32)
void @llvm.eh.sjlj.callsite(i32 %call_site_num)
</pre>
<p>For SJLJ based exception handling, the <a href="#llvm_eh_sjlj_callsite">
<tt>llvm.eh.sjlj.callsite</tt></a> intrinsic identifies the callsite value
associated with the following invoke instruction. This is used to ensure
that landing pad entries in the LSDA are generated in the matching order.</p>
<p>For SJLJ based exception handling, the <tt>llvm.eh.sjlj.callsite</tt>
intrinsic identifies the callsite value associated with the
following <tt>invoke</tt> instruction. This is used to ensure that landing
pad entries in the LSDA are generated in matching order.</p>
</div>
@ -612,12 +506,12 @@
<div>
<pre>
void %<a href="#llvm_eh_sjlj_dispatchsetup">llvm.eh.sjlj.dispatchsetup</a>(i32)
void @llvm.eh.sjlj.dispatchsetup(i32 %dispatch_value)
</pre>
<p>For SJLJ based exception handling, the <a href="#llvm_eh_sjlj_dispatchsetup">
<tt>llvm.eh.sjlj.dispatchsetup</tt></a> intrinsic is used by targets to do
any unwind-edge setup they need. By default, no action is taken. </p>
<p>For SJLJ based exception handling, the <tt>llvm.eh.sjlj.dispatchsetup</tt>
intrinsic is used by targets to do any unwind edge setup they need. By
default, no action is taken.</p>
</div>
@ -631,7 +525,7 @@
<div>
<p>There are two tables that are used by the exception handling runtime to
determine which actions should take place when an exception is thrown.</p>
determine which actions should be taken when an exception is thrown.</p>
<!-- ======================================================================= -->
<h3>
@ -641,13 +535,13 @@
<div>
<p>An exception handling frame <tt>eh_frame</tt> is very similar to the unwind
frame used by dwarf debug info. The frame contains all the information
frame used by DWARF debug info. The frame contains all the information
necessary to tear down the current frame and restore the state of the prior
frame. There is an exception handling frame for each function in a compile
frame. There is an exception handling frame for each function in a compile
unit, plus a common exception handling frame that defines information common
to all functions in the unit.</p>
<p>Todo - Table details here.</p>
<!-- Todo - Table details here. -->
</div>
@ -659,31 +553,17 @@
<div>
<p>An exception table contains information about what actions to take when an
exception is thrown in a particular part of a function's code. There is one
exception table per function except leaf routines and functions that have
only calls to non-throwing functions will not need an exception table.</p>
exception is thrown in a particular part of a function's code. There is one
exception table per function, except leaf functions and functions that have
calls only to non-throwing functions. They do not need an exception
table.</p>
<p>Todo - Table details here.</p>
<!-- Todo - Table details here. -->
</div>
</div>
<!-- ======================================================================= -->
<h2>
<a name="todo">ToDo</a>
</h2>
<div>
<ol>
<li>Testing/Testing/Testing.</li>
</ol>
</div>
<!-- *********************************************************************** -->
<hr>
@ -695,7 +575,7 @@
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
<a href="http://llvm.org/">LLVM Compiler Infrastructure</a><br>
Last modified: $Date: 2011-05-28 09:45:59 +0200 (Sat, 28 May 2011) $
Last modified: $Date: 2011-09-27 22:16:57 +0200 (Tue, 27 Sep 2011) $
</address>
</body>

View File

@ -72,9 +72,6 @@
<li>After Subversion update, rebuilding gives the error "No rule to make
target".</li>
<li><a href="#llvmc">The <tt>llvmc</tt> program gives me errors/doesn't
work.</a></li>
<li><a href="#srcdir-objdir">When I compile LLVM-GCC with srcdir == objdir,
it fails. Why?</a></li>
</ol></li>
@ -419,16 +416,6 @@ Stop.
rebuilding.</p>
</div>
<div class="question">
<p><a name="llvmc">The <tt>llvmc</tt> program gives me errors/doesn't
work.</a></p>
</div>
<div class="answer">
<p><tt>llvmc</tt> is experimental and isn't really supported. We suggest
using <tt>llvm-gcc</tt> instead.</p>
</div>
<div class="question">
<p><a name="srcdir-objdir">When I compile LLVM-GCC with srcdir == objdir, it
fails. Why?</a></p>
@ -540,10 +527,7 @@ Stop.
<p>Currently, there isn't much. LLVM supports an intermediate representation
which is useful for code representation but will not support the high level
(abstract syntax tree) representation needed by most compilers. There are no
facilities for lexical nor semantic analysis. There is, however, a <i>mostly
implemented</i> configuration-driven
<a href="CompilerDriver.html">compiler driver</a> which simplifies the task
of running optimizations, linking, and executable generation.</p>
facilities for lexical nor semantic analysis.</p>
</div>
<div class="question">
@ -933,7 +917,7 @@ F.i:
src="http://www.w3.org/Icons/valid-html401-blue" alt="Valid HTML 4.01"></a>
<a href="http://llvm.org/">LLVM Compiler Infrastructure</a><br>
Last modified: $Date: 2011-04-19 01:59:50 +0200 (Tue, 19 Apr 2011) $
Last modified: $Date: 2011-09-20 02:42:28 +0200 (Tue, 20 Sep 2011) $
</address>
</body>

View File

@ -290,10 +290,8 @@ doing so is very simple. (This code is heavily commented to help you
understand the data structure, but there are only 20 lines of meaningful
code.)</p>
</div>
<div class="doc_code"><pre
>/// @brief The map for a single function's stack frame. One of these is
<pre class="doc_code">
/// @brief The map for a single function's stack frame. One of these is
/// compiled as constant data into the executable for each function.
///
/// Storage of metadata values is elided if the %metadata parameter to
@ -338,7 +336,9 @@ void visitGCRoots(void (*Visitor)(void **Root, const void *Meta)) {
for (unsigned e = R->Map->NumRoots; i != e; ++i)
Visitor(&amp;R->Roots[i], NULL);
}
}</pre></div>
}</pre>
</div>
<!-- ======================================================================= -->
<h3>
@ -395,12 +395,12 @@ program.</p>
<a name="gcattr">Specifying GC code generation: <tt>gc "..."</tt></a>
</h3>
<div>
<div class="doc_code"><tt>
define <i>ty</i> @<i>name</i>(...) <span style="text-decoration: underline">gc "<i>name</i>"</span> { ...
</tt></div>
<div>
<p>The <tt>gc</tt> function attribute is used to specify the desired GC style
to the compiler. Its programmatic equivalent is the <tt>setGC</tt> method of
<tt>Function</tt>.</p>
@ -420,12 +420,12 @@ programs that use different garbage collection algorithms (or none at all).</p>
<a name="gcroot">Identifying GC roots on the stack: <tt>llvm.gcroot</tt></a>
</h3>
<div>
<div class="doc_code"><tt>
void @llvm.gcroot(i8** %ptrloc, i8* %metadata)
</tt></div>
<div>
<p>The <tt>llvm.gcroot</tt> intrinsic is used to inform LLVM that a stack
variable references an object on the heap and is to be tracked for garbage
collection. The exact impact on generated code is specified by a <a
@ -453,7 +453,7 @@ the stack frame.</p>
<p>Consider the following fragment of Java code:</p>
<pre>
<pre class="doc_code">
{
Object X; // A null-initialized reference to an object
...
@ -463,7 +463,7 @@ the stack frame.</p>
<p>This block (which may be located in the middle of a function or in a loop
nest), could be compiled to this LLVM code:</p>
<pre>
<pre class="doc_code">
Entry:
;; In the entry block for the function, allocate the
;; stack space for X, which is an LLVM pointer.
@ -537,12 +537,12 @@ are used.</p>
<a name="gcwrite">Write barrier: <tt>llvm.gcwrite</tt></a>
</h4>
<div>
<div class="doc_code"><tt>
void @llvm.gcwrite(i8* %value, i8* %object, i8** %derived)
</tt></div>
<div>
<p>For write barriers, LLVM provides the <tt>llvm.gcwrite</tt> intrinsic
function. It has exactly the same semantics as a non-volatile <tt>store</tt> to
the derived pointer (the third argument). The exact code generated is specified
@ -559,12 +559,12 @@ implement reference counting.</p>
<a name="gcread">Read barrier: <tt>llvm.gcread</tt></a>
</h4>
<div>
<div class="doc_code"><tt>
i8* @llvm.gcread(i8* %object, i8** %derived)<br>
</tt></div>
<div>
<p>For read barriers, LLVM provides the <tt>llvm.gcread</tt> intrinsic function.
It has exactly the same semantics as a non-volatile <tt>load</tt> from the
derived pointer (the second argument). The exact code generated is specified by
@ -1379,7 +1379,7 @@ Fergus Henderson. International Symposium on Memory Management 2002.</p>
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
<a href="http://llvm.org/">LLVM Compiler Infrastructure</a><br>
Last modified: $Date: 2011-04-23 02:30:22 +0200 (Sat, 23 Apr 2011) $
Last modified: $Date: 2011-08-12 08:17:17 +0200 (Fri, 12 Aug 2011) $
</address>
</body>

View File

@ -441,13 +441,13 @@ href="GCCFEBuildInstrs.html">try to compile it</a> on your platform.</p>
<tr>
<td><a href="http://www.gnu.org/software/autoconf/">GNU Autoconf</a></td>
<td>2.60</td>
<td>2.61</td>
<td>Configuration script builder<sup><a href="#sf4">4</a></sup></td>
</tr>
<tr>
<td><a href="http://www.gnu.org/software/automake/">GNU Automake</a></td>
<td>1.9.6</td>
<td>1.10</td>
<td>aclocal macro generator<sup><a href="#sf4">4</a></sup></td>
</tr>
@ -471,8 +471,8 @@ href="GCCFEBuildInstrs.html">try to compile it</a> on your platform.</p>
<li><a name="sf3">Only needed if you want to run the automated test
suite in the <tt>llvm/test</tt> directory.</a></li>
<li><a name="sf4">If you want to make changes to the configure scripts,
you will need GNU autoconf (2.60), and consequently, GNU M4 (version 1.4
or higher). You will also need automake (1.9.6). We only use aclocal
you will need GNU autoconf (2.61), and consequently, GNU M4 (version 1.4
or higher). You will also need automake (1.10). We only use aclocal
from that package.</a></li>
</ol>
</div>
@ -747,6 +747,7 @@ revision), you can checkout it from the '<tt>tags</tt>' directory (instead of
subdirectories of the '<tt>tags</tt>' directory:</p>
<ul>
<li>Release 3.0: <b>RELEASE_30/final</b></li>
<li>Release 2.9: <b>RELEASE_29/final</b></li>
<li>Release 2.8: <b>RELEASE_28</b></li>
<li>Release 2.7: <b>RELEASE_27</b></li>
@ -802,10 +803,150 @@ instructions</a> to successfully get and build the LLVM GCC front-end.</p>
now mirrors reflect only <tt>trunk</tt> for each project. You can do the
read-only GIT clone of LLVM via:</p>
<pre>
% git clone http://llvm.org/git/llvm.git
<pre class="doc_code">
git clone http://llvm.org/git/llvm.git
</pre>
<p>If you want to check out clang too, run:</p>
<pre class="doc_code">
git clone http://llvm.org/git/llvm.git
cd llvm/tools
git clone http://llvm.org/git/clang.git
</pre>
<p>
Since the upstream repository is in Subversion, you should use
<tt>&quot;git pull --rebase&quot;</tt>
instead of <tt>&quot;git pull&quot;</tt> to avoid generating a non-linear
history in your clone.
To configure <tt>&quot;git pull&quot;</tt> to pass <tt>--rebase</tt> by default
on the master branch, run the following command:
</p>
<pre class="doc_code">
git config branch.master.rebase true
</pre>
<h4>Sending patches with Git</h4>
<div>
<p>
Please read <a href="DeveloperPolicy.html#patches">Developer Policy</a>, too.
</p>
<p>
Assume <tt>master</tt> points the upstream and <tt>mybranch</tt> points your
working branch, and <tt>mybranch</tt> is rebased onto <tt>master</tt>.
At first you may check sanity of whitespaces:
</p>
<pre class="doc_code">
git diff --check master..mybranch
</pre>
<p>
The easiest way to generate a patch is as below:
</p>
<pre class="doc_code">
git diff master..mybranch &gt; /path/to/mybranch.diff
</pre>
<p>
It is a little different from svn-generated diff. git-diff-generated diff has
prefixes like <tt>a/</tt> and <tt>b/</tt>. Don't worry, most developers might
know it could be accepted with <tt>patch -p1 -N</tt>.
</p>
<p>
But you may generate patchset with git-format-patch. It generates
by-each-commit patchset. To generate patch files to attach to your article:
</p>
<pre class="doc_code">
git format-patch --no-attach master..mybranch -o /path/to/your/patchset
</pre>
<p>
If you would like to send patches directly, you may use git-send-email or
git-imap-send. Here is an example to generate the patchset in Gmail's [Drafts].
</p>
<pre class="doc_code">
git format-patch --attach master..mybranch --stdout | git imap-send
</pre>
<p>
Then, your .git/config should have [imap] sections.
</p>
<pre class="doc_code">
[imap]
host = imaps://imap.gmail.com
user = <em>your.gmail.account</em>@gmail.com
pass = <em>himitsu!</em>
port = 993
sslverify = false
; in English
folder = "[Gmail]/Drafts"
; example for Japanese, "Modified UTF-7" encoded.
folder = "[Gmail]/&amp;Tgtm+DBN-"
</pre>
</div>
<h4>For developers to work with git-svn</h4>
<div>
<p>To set up clone from which you can submit code using
<tt>git-svn</tt>, run:</p>
<pre class="doc_code">
git clone http://llvm.org/git/llvm.git
cd llvm
git svn init https://llvm.org/svn/llvm-project/llvm/trunk --username=&lt;username>
git config svn-remote.svn.fetch :refs/remotes/origin/master
git svn rebase -l # -l avoids fetching ahead of the git mirror.
# If you have clang too:
cd tools
git clone http://llvm.org/git/clang.git
cd clang
git svn init https://llvm.org/svn/llvm-project/cfe/trunk --username=&lt;username>
git config svn-remote.svn.fetch :refs/remotes/origin/master
git svn rebase -l
</pre>
<p>To update this clone without generating git-svn tags that conflict
with the upstream git repo, run:</p>
<pre class="doc_code">
git fetch && (cd tools/clang && git fetch) # Get matching revisions of both trees.
git checkout master
git svn rebase -l
(cd tools/clang &&
git checkout master &&
git svn rebase -l)
</pre>
<p>This leaves your working directories on their master branches, so
you'll need to <tt>checkout</tt> each working branch individually and
<tt>rebase</tt> it on top of its parent branch. (Note: This script is
intended for relative newbies to git. If you have more experience,
you can likely improve on it.)</p>
<p>The git-svn metadata can get out of sync after you mess around with
branches and <code>dcommit</code>. When that happens, <code>git svn
dcommit</code> stops working, complaining about files with uncommitted
changes. The fix is to rebuild the metadata:</p>
<pre class="doc_code">
rm -rf .git/svn
git svn rebase -l
</pre>
</div>
</div>
<!-- ======================================================================= -->
@ -1362,13 +1503,9 @@ different <a href="#tools">tools</a>.</p>
at runtime in both interpreted and JIT compiled fashions.</dd>
<dt><tt><b>llvm/lib/Support/</b></tt></dt>
<dd> This directory contains the source code that corresponds to the header
files located in <tt>llvm/include/Support/</tt>.</dd>
<!--FIXME: obsoleted -->
<dt><tt><b>llvm/lib/System/</b></tt></dt>
<dd>This directory contains the operating system abstraction layer that
shields LLVM from platform-specific coding.</dd>
<dd> This directory contains the source code that corresponds to the header
files located in <tt>llvm/include/ADT/</tt>
and <tt>llvm/include/Support/</tt>.</dd>
</dl>
</div>
@ -1455,16 +1592,6 @@ information is in the <a href="CommandGuide/index.html">Command Guide</a>.</p>
href="HowToSubmitABug.html">HowToSubmitABug.html</a> for more information
on using <tt>bugpoint</tt>.</dd>
<dt><tt><b>llvmc</b></tt></dt>
<dd>The LLVM Compiler Driver. This program can
be configured to utilize both LLVM and non-LLVM compilation tools to enable
pre-processing, translation, optimization, assembly, and linking of programs
all from one command line. <tt>llvmc</tt> also takes care of processing the
dependent libraries found in bitcode. This reduces the need to get the
traditional <tt>-l&lt;name&gt;</tt> options right on the command line. Please
note that this tool, while functional, is still experimental and not feature
complete.</dd>
<dt><tt><b>llvm-ar</b></tt></dt>
<dd>The archiver produces an archive containing
the given LLVM bitcode files, optionally with an index for faster
@ -1480,9 +1607,9 @@ information is in the <a href="CommandGuide/index.html">Command Guide</a>.</p>
<dt><tt><b>llvm-ld</b></tt></dt>
<dd><tt>llvm-ld</tt> is a general purpose and extensible linker for LLVM.
This is the linker invoked by <tt>llvmc</tt>. It performs standard link time
optimizations and allows optimization modules to be loaded and run so that
language specific optimizations can be applied at link time.</dd>
It performs standard link time optimizations and allows optimization
modules to be loaded and run so that language specific optimizations can
be applied at link time.</dd>
<dt><tt><b>llvm-link</b></tt></dt>
<dd><tt>llvm-link</tt>, not surprisingly, links multiple LLVM modules into
@ -1743,7 +1870,7 @@ out:</p>
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
<a href="http://llvm.x10sys.com/rspencer/">Reid Spencer</a><br>
<a href="http://llvm.org/">The LLVM Compiler Infrastructure</a><br>
Last modified: $Date: 2011-04-23 02:30:22 +0200 (Sat, 23 Apr 2011) $
Last modified: $Date: 2011-10-17 08:31:32 +0200 (Mon, 17 Oct 2011) $
</address>
</body>
</html>

View File

@ -75,6 +75,7 @@ placed.
<h2><a name="usage">Usage</a></h2>
<!--=========================================================================-->
<div>
<p>The linker takes a <tt>-plugin</tt> option that points to the path of
the plugin <tt>.so</tt> file. To find out what link command <tt>gcc</tt>
would run in a given situation, run <tt>gcc -v <em>[...]</em></tt> and look
@ -82,19 +83,21 @@ placed.
<tt>ld-new -plugin /path/to/LLVMgold.so</tt> to test it out. Once you're
ready to switch to using gold, backup your existing <tt>/usr/bin/ld</tt>
then replace it with <tt>ld-new</tt>.</p>
<p>You can produce bitcode files from <tt>llvm-gcc</tt> using
<p>You can produce bitcode files from <tt>clang</tt> using
<tt>-emit-llvm</tt> or <tt>-flto</tt>, or the <tt>-O4</tt> flag which is
synonymous with <tt>-O3 -flto</tt>.</p>
<p><tt>llvm-gcc</tt> has a <tt>-use-gold-plugin</tt> option which looks
for the gold plugin in the same directories as it looks for <tt>cc1</tt> and
passes the <tt>-plugin</tt> option to ld. It will not look for an alternate
<p><tt>Clang</tt> has a <tt>-use-gold-plugin</tt> option which looks for the
gold plugin in the same directories as it looks for <tt>cc1</tt> and passes
the <tt>-plugin</tt> option to <tt>ld</tt>. It will not look for an alternate
linker, which is why you need gold to be the installed system linker in your
path.</p>
<p>If you want <tt>ar</tt> and <tt>nm</tt> to work seamlessly as well, install
<tt>LLVMgold.so</tt> to <tt>/usr/lib/bfd-plugins</tt>. If you built your
own gold, be sure to install the <tt>ar</tt> and <tt>nm-new</tt> you built to
<tt>/usr/bin</tt>.
<p>
<tt>/usr/bin</tt>.<p>
<!-- ======================================================================= -->
<h3>
@ -137,11 +140,12 @@ void foo4(void) {
}
--- command lines ---
$ llvm-gcc -flto a.c -c -o a.o # &lt;-- a.o is LLVM bitcode file
$ clang -flto a.c -c -o a.o # &lt;-- a.o is LLVM bitcode file
$ ar q a.a a.o # &lt;-- a.a is an archive with LLVM bitcode
$ llvm-gcc b.c -c -o b.o # &lt;-- b.o is native object file
$ llvm-gcc -use-gold-plugin a.a b.o -o main # &lt;-- link with LLVMgold plugin
$ clang b.c -c -o b.o # &lt;-- b.o is native object file
$ clang -use-gold-plugin a.a b.o -o main # &lt;-- link with LLVMgold plugin
</pre>
<p>Gold informs the plugin that foo3 is never referenced outside the IR,
leading LLVM to delete that function. However, unlike in the
<a href="LinkTimeOptimization.html#example1">libLTO
@ -158,20 +162,21 @@ $ llvm-gcc -use-gold-plugin a.a b.o -o main # &lt;-- link with LLVMgold plugin
</h2>
<!--=========================================================================-->
<div>
<p>Once your system <tt>ld</tt>, <tt>ar</tt> and <tt>nm</tt> all support LLVM
bitcode, everything is in place for an easy to use LTO build of autotooled
projects:</p>
<p>Once your system <tt>ld</tt>, <tt>ar</tt>, and <tt>nm</tt> all support LLVM
bitcode, everything is in place for an easy to use LTO build of autotooled
projects:</p>
<ul>
<li>Follow the instructions <a href="#build">on how to build LLVMgold.so</a>.</li>
<li>Install the newly built binutils to <tt>$PREFIX</tt></li>
<li>Copy <tt>Release/lib/LLVMgold.so</tt> to
<tt>$PREFIX/libexec/gcc/x86_64-unknown-linux-gnu/4.2.1/</tt> and
<tt>$PREFIX/lib/bfd-plugins/</tt></li>
<li>Set environment variables (<tt>$PREFIX</tt> is where you installed llvm-gcc and
binutils):
<pre class="doc_code">
export CC="$PREFIX/bin/llvm-gcc -use-gold-plugin"
export CXX="$PREFIX/bin/llvm-g++ -use-gold-plugin"
<tt>$PREFIX/libexec/gcc/x86_64-unknown-linux-gnu/4.2.1/</tt> and
<tt>$PREFIX/lib/bfd-plugins/</tt></li>
<li>Set environment variables (<tt>$PREFIX</tt> is where you installed clang and
binutils):
<pre class="doc_code">
export CC="$PREFIX/bin/clang -use-gold-plugin"
export CXX="$PREFIX/bin/clang++ -use-gold-plugin"
export AR="$PREFIX/bin/ar"
export NM="$PREFIX/bin/nm"
export RANLIB=/bin/true #ranlib is not needed, and doesn't support .bc files in .a
@ -179,18 +184,22 @@ export CFLAGS="-O4"
</pre>
</li>
<li>Or you can just set your path:
<pre class="doc_code">
<pre class="doc_code">
export PATH="$PREFIX/bin:$PATH"
export CC="llvm-gcc -use-gold-plugin"
export CXX="llvm-g++ -use-gold-plugin"
export CC="clang -use-gold-plugin"
export CXX="clang++ -use-gold-plugin"
export RANLIB=/bin/true
export CFLAGS="-O4"
</pre>
</li>
<li>Configure &amp; build the project as usual: <tt>./configure &amp;&amp; make &amp;&amp; make check</tt> </li>
</pre></li>
<li>Configure &amp; build the project as usual:
<pre class="doc_code">
% ./configure &amp;&amp; make &amp;&amp; make check
</pre></li>
</ul>
<p> The environment variable settings may work for non-autotooled projects
too, but you may need to set the <tt>LD</tt> environment variable as well.</p>
<p>The environment variable settings may work for non-autotooled projects
too, but you may need to set the <tt>LD</tt> environment variable as
well.</p>
</div>
<!--=========================================================================-->

View File

@ -29,7 +29,7 @@
<div>
<p>This document contains information about successfully releasing LLVM &mdash;
including subprojects: e.g., <tt>llvm-gcc</tt> and <tt>clang</tt> &mdash; to
including subprojects: e.g., <tt>clang</tt> and <tt>dragonegg</tt> &mdash; to
the public. It is the Release Manager's responsibility to ensure that a high
quality build of LLVM is released.</p>
@ -92,7 +92,6 @@
<ol>
<li><a href="#dist">Build the LLVM Source Distributions</a></li>
<li><a href="#build">Build LLVM</a></li>
<li><a href="#llvmgccbin">Build the LLVM-GCC Binary Distribution</a></li>
<li><a href="#clangbin">Build the Clang Binary Distribution</a></li>
<li><a href="#target-build">Target Specific Build Details</a></li>
</ol>
@ -100,7 +99,6 @@
<li><a href="#release-qualify">Release Qualification Criteria</a>
<ol>
<li><a href="#llvm-qualify">Qualify LLVM</a></li>
<li><a href="#llvmgcc-qualify">Qualify LLVM-GCC</a></li>
<li><a href="#clang-qualify">Qualify Clang</a></li>
<li><a href="#targets">Specific Target Qualification Details</a></li>
</ol>
@ -149,25 +147,25 @@
<li><p>Verify that the current Subversion trunk is in decent shape by
examining nightly tester and buildbot results.</p></li>
<li><p>Create the release branch for <tt>llvm</tt>, <tt>llvm-gcc-4.2</tt>,
<tt>clang</tt>, and the <tt>test-suite</tt> from the last known good
revision. The branch's name is <tt>release_XY</tt>, where <tt>X</tt> is
the major and <tt>Y</tt> the minor release numbers. The branches should be
created using the following commands:</p>
<li><p>Create the release branch for <tt>llvm</tt>, <tt>clang</tt>,
the <tt>test-suite</tt>, and <tt>dragonegg</tt> from the last known good
revision. The branch's name is <tt>release_<i>XY</i></tt>,
where <tt>X</tt> is the major and <tt>Y</tt> the minor release
numbers. The branches should be created using the following commands:</p>
<div class="doc_code">
<pre>
$ svn copy https://llvm.org/svn/llvm-project/llvm/trunk \
https://llvm.org/svn/llvm-project/llvm/branches/release_<i>XY</i>
$ svn copy https://llvm.org/svn/llvm-project/llvm-gcc-4.2/trunk \
https://llvm.org/svn/llvm-project/llvm-gcc-4.2/branches/release_<i>XY</i>
$ svn copy https://llvm.org/svn/llvm-project/cfe/trunk \
https://llvm.org/svn/llvm-project/cfe/branches/release_<i>XY</i>
$ svn copy https://llvm.org/svn/llvm-project/dragonegg/trunk \
https://llvm.org/svn/llvm-project/dragonegg/branches/release_<i>XY</i>
$ svn copy https://llvm.org/svn/llvm-project/test-suite/trunk \
https://llvm.org/svn/llvm-project/test-suite/branches/release_<i>XY</i>
$ svn copy https://llvm.org/svn/llvm-project/cfe/trunk \
https://llvm.org/svn/llvm-project/cfe/branches/release_<i>XY</i>
</pre>
</div></li>
@ -182,11 +180,11 @@ $ svn copy https://llvm.org/svn/llvm-project/cfe/trunk \
<pre>
$ svn co https://llvm.org/svn/llvm-project/llvm/branches/release_<i>XY</i> llvm-<i>X.Y</i>
$ svn co https://llvm.org/svn/llvm-project/llvm-gcc-4.2/branches/release_<i>XY</i> llvm-gcc-4.2-<i>X.Y</i>
$ svn co https://llvm.org/svn/llvm-project/cfe/branches/release_<i>XY</i> clang-<i>X.Y</i>
$ svn co https://llvm.org/svn/llvm-project/dragonegg/branches/release_<i>XY</i> dragonegg-<i>X.Y</i>
$ svn co https://llvm.org/svn/llvm-project/test-suite/branches/release_<i>XY</i> test-suite-<i>X.Y</i>
$ svn co https://llvm.org/svn/llvm-project/cfe/branches/release_<i>XY</i> clang-<i>X.Y</i>
</pre>
</div></li>
</ol>
@ -214,10 +212,10 @@ $ svn co https://llvm.org/svn/llvm-project/cfe/branches/release_<i>XY</i> clang-
<div>
<p>Create release candidates for <tt>llvm</tt>, <tt>llvm-gcc</tt>,
<tt>clang</tt>, and the LLVM <tt>test-suite</tt> by tagging the branch with
the respective release candidate number. For instance, to create <b>Release
Candidate 1</b> you would issue the following commands:</p>
<p>Create release candidates for <tt>llvm</tt>, <tt>clang</tt>,
<tt>dragonegg</tt>, and the LLVM <tt>test-suite</tt> by tagging the branch
with the respective release candidate number. For instance, to
create <b>Release Candidate 1</b> you would issue the following commands:</p>
<div class="doc_code">
<pre>
@ -225,17 +223,17 @@ $ svn mkdir https://llvm.org/svn/llvm-project/llvm/tags/RELEASE_<i>XY</i>
$ svn copy https://llvm.org/svn/llvm-project/llvm/branches/release_<i>XY</i> \
https://llvm.org/svn/llvm-project/llvm/tags/RELEASE_<i>XY</i>/rc1
$ svn mkdir https://llvm.org/svn/llvm-project/llvm-gcc-4.2/tags/RELEASE_<i>XY</i>
$ svn copy https://llvm.org/svn/llvm-project/llvm-gcc-4.2/branches/release_<i>XY</i> \
https://llvm.org/svn/llvm-project/llvm-gcc-4.2/tags/RELEASE_<i>XY</i>/rc1
$ svn mkdir https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_<i>XY</i>
$ svn copy https://llvm.org/svn/llvm-project/cfe/branches/release_<i>XY</i> \
https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_<i>XY</i>/rc1
$ svn mkdir https://llvm.org/svn/llvm-project/dragonegg/tags/RELEASE_<i>XY</i>
$ svn copy https://llvm.org/svn/llvm-project/dragonegg/branches/release_<i>XY</i> \
https://llvm.org/svn/llvm-project/dragonegg/tags/RELEASE_<i>XY</i>/rc1
$ svn mkdir https://llvm.org/svn/llvm-project/test-suite/tags/RELEASE_<i>XY</i>
$ svn copy https://llvm.org/svn/llvm-project/test-suite/branches/release_<i>XY</i> \
https://llvm.org/svn/llvm-project/test-suite/tags/RELEASE_<i>XY</i>/rc1
$ svn mkdir https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_<i>XY</i>
$ svn copy https://llvm.org/svn/llvm-project/cfe/branches/release_<i>XY</i> \
https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_<i>XY</i>/rc1
</pre>
</div>
@ -251,14 +249,14 @@ $ svn copy https://llvm.org/svn/llvm-project/cfe/branches/release_<i>XY</i> \
<div class="doc_code">
<pre>
$ svn export https://llvm.org/svn/llvm-project/llvm/tags/RELEASE_<i>XY</i>/rc1 llvm-<i>X.Y</i>rc1
$ svn export https://llvm.org/svn/llvm-project/llvm-gcc-4.2/tags/RELEASE_<i>XY</i>/rc1 llvm-gcc4.2-<i>X.Y</i>rc1
$ svn export https://llvm.org/svn/llvm-project/test-suite/tags/RELEASE_<i>XY</i>/rc1 llvm-test-<i>X.Y</i>rc1
$ svn export https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_<i>XY</i>/rc1 clang-<i>X.Y</i>rc1
$ svn export https://llvm.org/svn/llvm-project/dragonegg/tags/RELEASE_<i>XY</i>/rc1 dragonegg-<i>X.Y</i>rc1
$ svn export https://llvm.org/svn/llvm-project/test-suite/tags/RELEASE_<i>XY</i>/rc1 llvm-test-<i>X.Y</i>rc1
$ tar -cvf - llvm-<i>X.Y</i>rc1 | gzip &gt; llvm-<i>X.Y</i>rc1.src.tar.gz
$ tar -cvf - llvm-test-<i>X.Y</i>rc1 | gzip &gt; llvm-test-<i>X.Y</i>rc1.src.tar.gz
$ tar -cvf - llvm-gcc4.2-<i>X.Y</i>rc1 | gzip &gt; llvm-gcc-4.2-<i>X.Y</i>rc1.src.tar.gz
$ tar -cvf - clang-<i>X.Y</i>rc1 | gzip &gt; clang-<i>X.Y</i>rc1.src.tar.gz
$ tar -cvf - dragonegg-<i>X.Y</i>rc1 | gzip &gt; dragonegg-<i>X.Y</i>rc1.src.tar.gz
$ tar -cvf - llvm-test-<i>X.Y</i>rc1 | gzip &gt; llvm-test-<i>X.Y</i>rc1.src.tar.gz
</pre>
</div>
@ -271,7 +269,7 @@ $ tar -cvf - clang-<i>X.Y</i>rc1 | gzip &gt; clang-<i>X.Y</i>rc1.src.tar.g
<div>
<p>The builds of <tt>llvm</tt>, <tt>llvm-gcc</tt>, and <tt>clang</tt>
<p>The builds of <tt>llvm</tt>, <tt>clang</tt>, and <tt>dragonegg</tt>
<em>must</em> be free of errors and warnings in Debug, Release+Asserts, and
Release builds. If all builds are clean, then the release passes Build
Qualification.</p>
@ -292,35 +290,7 @@ $ tar -cvf - clang-<i>X.Y</i>rc1 | gzip &gt; clang-<i>X.Y</i>rc1.src.tar.g
<p>Build <tt>Debug</tt>, <tt>Release+Asserts</tt>, and <tt>Release</tt> versions
of <tt>llvm</tt> on all supported platforms. Directions to build
<tt>llvm</tt> are
<a href="GettingStarted.html#quickstart">here</a>.</p>
</div>
<!-- ======================================================================= -->
<h4><a name="llvmgccbin">Build the LLVM GCC Binary Distribution</a></h4>
<div>
<p>Creating the <tt>llvm-gcc</tt> binary distribution (Release/Optimized)
requires performing the following steps for each supported platform:</p>
<ol>
<li><p>Build the <tt>llvm-gcc</tt> front-end by following the directions in
the <tt>README.LLVM</tt> file. The front-end must be compiled with C, C++,
Objective-C (Mac only), Objective-C++ (Mac only), and Fortran
support.</p></li>
<li><p>Boostrapping must be enabled.</p></li>
<li><p>Be sure to build with <tt>LLVM_VERSION_INFO=X.Y</tt>, where <tt>X</tt>
is the major and <tt>Y</tt> is the minor release numbers.</p></li>
<li><p>Copy the installation directory to a directory named for the specific
target. For example on Red Hat Enterprise Linux, the directory would be
named <tt>llvm-gcc4.2-2.6-x86-linux-RHEL4</tt>. Archive and compress the
new directory.</p></li>
</ol>
<tt>llvm</tt> are <a href="GettingStarted.html#quickstart">here</a>.</p>
</div>
@ -337,8 +307,8 @@ $ tar -cvf - clang-<i>X.Y</i>rc1 | gzip &gt; clang-<i>X.Y</i>rc1.src.tar.g
<li>Build clang according to the directions
<a href="http://clang.llvm.org/get_started.html">here</a>.</li>
<li>Build both a debug and release version of clang. The binary will be the
release build.</lI>
<li>Build both a Debug and Release version of clang. The binary will be the
Release build.</lI>
<li>Package <tt>clang</tt> (details to follow).</li>
</ol>
@ -351,18 +321,18 @@ $ tar -cvf - clang-<i>X.Y</i>rc1 | gzip &gt; clang-<i>X.Y</i>rc1.src.tar.g
<div>
<p>The table below specifies which compilers are used for each Arch/OS
combination when qualifying the build of <tt>llvm</tt>, <tt>llvm-gcc</tt>,
and <tt>clang</tt>.</p>
combination when qualifying the build of <tt>llvm</tt>, <tt>clang</tt>,
and <tt>dragonegg</tt>.</p>
<table>
<tr><th>Architecture</th><th>OS</th><th>compiler</th></tr>
<tr><td>x86-32</td><td>Mac OS 10.5</td><td>gcc 4.0.1</td></tr>
<tr><td>x86-32</td><td>Linux</td><td>gcc 4.2.X, gcc 4.3.X</td></tr>
<tr><td>x86-32</td><td>FreeBSD</td><td>gcc 4.2.X</td></tr>
<tr><td>x86-32</td><td>mingw</td><td>gcc 3.4.5</td></tr>
<tr><td>x86-64</td><td>Mac OS 10.5</td><td>gcc 4.0.1</td></tr>
<tr><td>x86-64</td><td>Linux</td><td>gcc 4.2.X, gcc 4.3.X</td></tr>
<tr><td>x86-64</td><td>FreeBSD</td><td>gcc 4.2.X</td></tr>
<tr><th>Architecture</th> <th>OS</th> <th>compiler</th></tr>
<tr><td>x86-32</td> <td>Mac OS 10.5</td> <td>gcc 4.0.1</td></tr>
<tr><td>x86-32</td> <td>Linux</td> <td>gcc 4.2.X, gcc 4.3.X</td></tr>
<tr><td>x86-32</td> <td>FreeBSD</td> <td>gcc 4.2.X</td></tr>
<tr><td>x86-32</td> <td>mingw</td> <td>gcc 3.4.5</td></tr>
<tr><td>x86-64</td> <td>Mac OS 10.5</td> <td>gcc 4.0.1</td></tr>
<tr><td>x86-64</td> <td>Linux</td> <td>gcc 4.2.X, gcc 4.3.X</td></tr>
<tr><td>x86-64</td> <td>FreeBSD</td> <td>gcc 4.2.X</td></tr>
</table>
</div>
@ -394,21 +364,8 @@ $ tar -cvf - clang-<i>X.Y</i>rc1 | gzip &gt; clang-<i>X.Y</i>rc1.src.tar.g
<div>
<p>LLVM is qualified when it has a clean test run without a front-end. And it
has no regressions when using either <tt>llvm-gcc</tt> or <tt>clang</tt> with
the <tt>test-suite</tt> from the previous release.</p>
</div>
<!-- ======================================================================= -->
<h4><a name="llvmgcc-qualify">Qualify LLVM-GCC</a></h4>
<div>
<p><tt>LLVM-GCC</tt> is qualified when front-end specific tests in the
<tt>llvm</tt> regression test suite all pass and there are no regressions in
the <tt>test-suite</tt>.</p>
<p>We do not use the GCC DejaGNU test suite as release criteria.</p>
has no regressions when using either <tt>clang</tt> or <tt>dragonegg</tt>
with the <tt>test-suite</tt> from the previous release.</p>
</div>
@ -429,13 +386,13 @@ $ tar -cvf - clang-<i>X.Y</i>rc1 | gzip &gt; clang-<i>X.Y</i>rc1.src.tar.g
<div>
<table>
<tr><th>Architecture</th><th>OS</th><th>llvm-gcc baseline</th><th>clang baseline</th><th>tests</th></tr>
<tr><td>x86-32</td><td>Linux</td><td>last release</td><td>last release</td><td>llvm dejagnu, clang tests, test-suite (including spec)</td></tr>
<tr><td>x86-32</td><td>FreeBSD</td><td>none</td><td>last release</td><td>llvm dejagnu, clang tests, test-suite</td></tr>
<tr><td>x86-32</td><td>mingw</td><td>last release</td><td>none</td><td>QT</td></tr>
<tr><td>x86-64</td><td>Mac OS 10.X</td><td>last release</td><td>last release</td><td>llvm dejagnu, clang tests, test-suite (including spec)</td></tr>
<tr><td>x86-64</td><td>Linux</td><td>last release</td><td>last release</td><td>llvm dejagnu, clang tests, test-suite (including spec)</td></tr>
<tr><td>x86-64</td><td>FreeBSD</td><td>none</td><td>last release</td><td>llvm dejagnu, clang tests, test-suite</td></tr>
<tr><th>Architecture</th> <th>OS</th> <th>clang baseline</th> <th>tests</th></tr>
<tr><td>x86-32</td> <td>Linux</td> <td>last release</td> <td>llvm dejagnu, clang tests, test-suite (including spec)</td></tr>
<tr><td>x86-32</td> <td>FreeBSD</td> <td>last release</td> <td>llvm dejagnu, clang tests, test-suite</td></tr>
<tr><td>x86-32</td> <td>mingw</td> <td>none</td> <td>QT</td></tr>
<tr><td>x86-64</td> <td>Mac OS 10.X</td> <td>last release</td> <td>llvm dejagnu, clang tests, test-suite (including spec)</td></tr>
<tr><td>x86-64</td> <td>Linux</td> <td>last release</td> <td>llvm dejagnu, clang tests, test-suite (including spec)</td></tr>
<tr><td>x86-64</td> <td>FreeBSD</td> <td>last release</td> <td>llvm dejagnu, clang tests, test-suite</td></tr>
</table>
</div>
@ -452,14 +409,12 @@ $ tar -cvf - clang-<i>X.Y</i>rc1 | gzip &gt; clang-<i>X.Y</i>rc1.src.tar.g
<ol>
<li>Download <tt>llvm-<i>X.Y</i></tt>, <tt>llvm-test-<i>X.Y</i></tt>, and the
appropriate <tt>llvm-gcc</tt> and/or <tt>clang</tt> binary. Build
LLVM. Run <tt>make check</tt> and the full LLVM test suite (<tt>make
TEST=nightly report</tt>).</li>
appropriate <tt>clang</tt> binary. Build LLVM. Run <tt>make check</tt> and
the full LLVM test suite (<tt>make TEST=nightly report</tt>).</li>
<li>Download <tt>llvm-<i>X.Y</i></tt>, <tt>llvm-test-<i>X.Y</i></tt>, and the
<tt>llvm-gcc</tt> and/or <tt>clang</tt> source. Compile everything. Run
<tt>make check</tt> and the full LLVM test suite (<tt>make TEST=nightly
report</tt>).</li>
<tt>clang</tt> sources. Compile everything. Run <tt>make check</tt> and
the full LLVM test suite (<tt>make TEST=nightly report</tt>).</li>
</ol>
<p>Ask LLVM developers to submit the test suite report and <tt>make check</tt>
@ -538,14 +493,14 @@ $ tar -cvf - clang-<i>X.Y</i>rc1 | gzip &gt; clang-<i>X.Y</i>rc1.src.tar.g
$ svn copy https://llvm.org/svn/llvm-project/llvm/branches/release_XY \
https://llvm.org/svn/llvm-project/llvm/tags/RELEASE_<i>XY</i>/Final
$ svn copy https://llvm.org/svn/llvm-project/llvm-gcc-4.2/branches/release_XY \
https://llvm.org/svn/llvm-project/llvm-gcc-4.2/tags/RELEASE_<i>XY</i>/Final
$ svn copy https://llvm.org/svn/llvm-project/cfe/branches/release_XY \
https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_<i>XY</i>/Final
$ svn copy https://llvm.org/svn/llvm-project/dragonegg/branches/release_XY \
https://llvm.org/svn/llvm-project/dragonegg/tags/RELEASE_<i>XY</i>/Final
$ svn copy https://llvm.org/svn/llvm-project/test-suite/branches/release_XY \
https://llvm.org/svn/llvm-project/test-suite/tags/RELEASE_<i>XY</i>/Final
$ svn copy https://llvm.org/svn/llvm-project/cfe/branches/release_XY \
https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_<i>XY</i>/Final
</pre>
</div>
@ -559,7 +514,7 @@ $ svn copy https://llvm.org/svn/llvm-project/cfe/branches/release_XY \
<div>
<p>The LLVM demo page must be updated to use the new release. This consists of
using the new <tt>llvm-gcc</tt> binary and building LLVM.</p>
using the new <tt>clang</tt> binary and building LLVM.</p>
<!-- ======================================================================= -->
<h4><a name="webupdates">Update the LLVM Website</a></h4>
@ -574,8 +529,8 @@ $ svn copy https://llvm.org/svn/llvm-project/cfe/branches/release_XY \
<li>Create a new subdirectory <tt>X.Y</tt> in the releases directory.</li>
<li>Commit the <tt>llvm</tt>, <tt>test-suite</tt>, <tt>llvm-gcc</tt> source,
<tt>clang source</tt>, <tt>clang binaries</tt>, and <tt>llvm-gcc</tt>
<li>Commit the <tt>llvm</tt>, <tt>test-suite</tt>, <tt>clang</tt> source,
<tt>clang binaries</tt>, <tt>dragonegg</tt> source, and <tt>dragonegg</tt>
binaries in this new directory.</li>
<li>Copy and commit the <tt>llvm/docs</tt> and <tt>LICENSE.txt</tt> files
@ -619,7 +574,7 @@ $ svn copy https://llvm.org/svn/llvm-project/cfe/branches/release_XY \
src="http://www.w3.org/Icons/valid-html401-blue" alt="Valid HTML 4.01"></a>
<a href="http://llvm.org/">The LLVM Compiler Infrastructure</a>
<br>
Last modified: $Date: 2011-04-23 02:30:22 +0200 (Sat, 23 Apr 2011) $
Last modified: $Date: 2011-10-17 22:32:14 +0200 (Mon, 17 Oct 2011) $
</address>
</body>
</html>

File diff suppressed because it is too large Load Diff

View File

@ -35,6 +35,10 @@
<td><a href="#DSA">DSA</a></td>
<td><a href="#DSE">DSE</a></td>
</tr>
<tr><th colspan="8"><b>- <a href="#F">F</a> -</b></th></tr>
<tr>
<td><a href="#FCA">FCA</a></td>
</tr>
<tr><th colspan="8"><b>- <a href="#G">G</a> -</b></th></tr>
<tr>
<td><a href="#GC">GC</a></td>
@ -137,6 +141,14 @@ href="http://www.program-transformation.org/Transform/BURG">BURG</a> tool.</dd>
</dl>
</div>
<!-- _______________________________________________________________________ -->
<h3><a name="F">- F -</a></h3>
<div>
<dl>
<dt><a name="FCA"><b>FCA</b></a></dt>
<dd>First Class Aggregate</dd>
</dl>
</div>
<!-- _______________________________________________________________________ -->
<h3><a name="G">- G -</a></h3>
<div>
<dl>
@ -272,7 +284,7 @@ href="http://www.program-transformation.org/Transform/BURG">BURG</a> tool.</dd>
src="http://www.w3.org/Icons/valid-html401-blue" alt="Valid HTML 4.01"></a><a
href="http://llvm.org/">The LLVM Team</a><br>
<a href="http://llvm.org/">The LLVM Compiler Infrastructure</a><br>
Last modified: $Date: 2011-04-23 02:30:22 +0200 (Sat, 23 Apr 2011) $
Last modified: $Date: 2011-09-27 20:44:01 +0200 (Tue, 27 Sep 2011) $
</address>
<!-- vim: sw=2
-->

View File

@ -79,7 +79,7 @@ conservative escape analysis.
<p>The following example illustrates the advantages of LTO's integrated
approach and clean interface. This example requires a system linker which
supports LTO through the interface described in this document. Here,
llvm-gcc transparently invokes system linker. </p>
clang transparently invokes system linker. </p>
<ul>
<li> Input source file <tt>a.c</tt> is compiled into LLVM bitcode form.
<li> Input source file <tt>main.c</tt> is compiled into native object code.
@ -89,27 +89,29 @@ conservative escape analysis.
extern int foo1(void);
extern void foo2(void);
extern void foo4(void);
--- a.c ---
#include "a.h"
static signed int i = 0;
void foo2(void) {
i = -1;
i = -1;
}
static int foo3() {
foo4();
return 10;
foo4();
return 10;
}
int foo1(void) {
int data = 0;
int data = 0;
if (i &lt; 0) { data = foo3(); }
if (i &lt; 0)
data = foo3();
data = data + 42;
return data;
data = data + 42;
return data;
}
--- main.c ---
@ -117,30 +119,35 @@ return data;
#include "a.h"
void foo4(void) {
printf ("Hi\n");
printf("Hi\n");
}
int main() {
return foo1();
return foo1();
}
--- command lines ---
$ llvm-gcc --emit-llvm -c a.c -o a.o # &lt;-- a.o is LLVM bitcode file
$ llvm-gcc -c main.c -o main.o # &lt;-- main.o is native object file
$ llvm-gcc a.o main.o -o main # &lt;-- standard link command without any modifications
$ clang -emit-llvm -c a.c -o a.o # &lt;-- a.o is LLVM bitcode file
$ clang -c main.c -o main.o # &lt;-- main.o is native object file
$ clang a.o main.o -o main # &lt;-- standard link command without any modifications
</pre>
<p>In this example, the linker recognizes that <tt>foo2()</tt> is an
externally visible symbol defined in LLVM bitcode file. The linker completes
its usual symbol resolution
pass and finds that <tt>foo2()</tt> is not used anywhere. This information
is used by the LLVM optimizer and it removes <tt>foo2()</tt>. As soon as
<tt>foo2()</tt> is removed, the optimizer recognizes that condition
<tt>i &lt; 0</tt> is always false, which means <tt>foo3()</tt> is never
used. Hence, the optimizer removes <tt>foo3()</tt>, also. And this in turn,
enables linker to remove <tt>foo4()</tt>. This example illustrates the
advantage of tight integration with the linker. Here, the optimizer can not
remove <tt>foo3()</tt> without the linker's input.
</p>
<ul>
<li>In this example, the linker recognizes that <tt>foo2()</tt> is an
externally visible symbol defined in LLVM bitcode file. The linker
completes its usual symbol resolution pass and finds that <tt>foo2()</tt>
is not used anywhere. This information is used by the LLVM optimizer and
it removes <tt>foo2()</tt>.</li>
<li>As soon as <tt>foo2()</tt> is removed, the optimizer recognizes that condition
<tt>i &lt; 0</tt> is always false, which means <tt>foo3()</tt> is never
used. Hence, the optimizer also removes <tt>foo3()</tt>.</li>
<li>And this in turn, enables linker to remove <tt>foo4()</tt>.</li>
</ul>
<p>This example illustrates the advantage of tight integration with the
linker. Here, the optimizer can not remove <tt>foo3()</tt> without the
linker's input.</p>
</div>
<!-- ======================================================================= -->
@ -385,7 +392,7 @@ of the native object files.</p>
Devang Patel and Nick Kledzik<br>
<a href="http://llvm.org/">LLVM Compiler Infrastructure</a><br>
Last modified: $Date: 2011-04-23 02:30:22 +0200 (Sat, 23 Apr 2011) $
Last modified: $Date: 2011-09-18 14:51:05 +0200 (Sun, 18 Sep 2011) $
</address>
</body>

View File

@ -161,7 +161,6 @@ perl -e '$/ = undef; for (split(/\n/, <>)) { s:^ *///? ?::; print " <p>\n" if !
<tr><td><a href="#loop-unswitch">-loop-unswitch</a></td><td>Unswitch loops</td></tr>
<tr><td><a href="#loweratomic">-loweratomic</a></td><td>Lower atomic intrinsics to non-atomic form</td></tr>
<tr><td><a href="#lowerinvoke">-lowerinvoke</a></td><td>Lower invoke and unwind, for unwindless code generators</td></tr>
<tr><td><a href="#lowersetjmp">-lowersetjmp</a></td><td>Lower Set Jump</td></tr>
<tr><td><a href="#lowerswitch">-lowerswitch</a></td><td>Lower SwitchInst's to branches</td></tr>
<tr><td><a href="#mem2reg">-mem2reg</a></td><td>Promote Memory to Register</td></tr>
<tr><td><a href="#memcpyopt">-memcpyopt</a></td><td>MemCpy Optimization</td></tr>
@ -1476,35 +1475,6 @@ if (X &lt; 3) {</pre>
</p>
</div>
<!-------------------------------------------------------------------------- -->
<h3>
<a name="lowersetjmp">-lowersetjmp: Lower Set Jump</a>
</h3>
<div>
<p>
Lowers <tt>setjmp</tt> and <tt>longjmp</tt> to use the LLVM invoke and unwind
instructions as necessary.
</p>
<p>
Lowering of <tt>longjmp</tt> is fairly trivial. We replace the call with a
call to the LLVM library function <tt>__llvm_sjljeh_throw_longjmp()</tt>.
This unwinds the stack for us calling all of the destructors for
objects allocated on the stack.
</p>
<p>
At a <tt>setjmp</tt> call, the basic block is split and the <tt>setjmp</tt>
removed. The calls in a function that have a <tt>setjmp</tt> are converted to
invoke where the except part checks to see if it's a <tt>longjmp</tt>
exception and, if so, if it's handled in the function. If it is, then it gets
the value returned by the <tt>longjmp</tt> and goes to where the basic block
was split. <tt>invoke</tt> instructions are handled in a similar fashion with
the original except block being executed if it isn't a <tt>longjmp</tt>
except that is handled by that function.
</p>
</div>
<!-------------------------------------------------------------------------- -->
<h3>
<a name="lowerswitch">-lowerswitch: Lower SwitchInst's to branches</a>
@ -2071,7 +2041,7 @@ if (X &lt; 3) {</pre>
<a href="mailto:rspencer@x10sys.com">Reid Spencer</a><br>
<a href="http://llvm.org/">LLVM Compiler Infrastructure</a><br>
Last modified: $Date: 2011-04-23 02:30:22 +0200 (Sat, 23 Apr 2011) $
Last modified: $Date: 2011-08-04 00:18:20 +0200 (Thu, 04 Aug 2011) $
</address>
</body>

View File

@ -59,6 +59,7 @@ option</a></li>
<li><a href="#dss_arrayref">llvm/ADT/ArrayRef.h</a></li>
<li><a href="#dss_fixedarrays">Fixed Size Arrays</a></li>
<li><a href="#dss_heaparrays">Heap Allocated Arrays</a></li>
<li><a href="#dss_tinyptrvector">"llvm/ADT/TinyPtrVector.h"</a></li>
<li><a href="#dss_smallvector">"llvm/ADT/SmallVector.h"</a></li>
<li><a href="#dss_vector">&lt;vector&gt;</a></li>
<li><a href="#dss_deque">&lt;deque&gt;</a></li>
@ -67,6 +68,13 @@ option</a></li>
<li><a href="#dss_packedvector">llvm/ADT/PackedVector.h</a></li>
<li><a href="#dss_other">Other Sequential Container Options</a></li>
</ul></li>
<li><a href="#ds_string">String-like containers</a>
<ul>
<li><a href="#dss_stringref">llvm/ADT/StringRef.h</a></li>
<li><a href="#dss_twine">llvm/ADT/Twine.h</a></li>
<li><a href="#dss_smallstring">llvm/ADT/SmallString.h</a></li>
<li><a href="#dss_stdstring">std::string</a></li>
</ul></li>
<li><a href="#ds_set">Set-Like Containers (std::set, SmallSet, SetVector, etc)</a>
<ul>
<li><a href="#dss_sortedvectorset">A sorted 'vector'</a></li>
@ -91,10 +99,6 @@ option</a></li>
<li><a href="#dss_inteqclasses">"llvm/ADT/IntEqClasses.h"</a></li>
<li><a href="#dss_othermap">Other Map-Like Container Options</a></li>
</ul></li>
<li><a href="#ds_string">String-like containers</a>
<!--<ul>
todo
</ul>--></li>
<li><a href="#ds_bit">BitVector-like containers</a>
<ul>
<li><a href="#dss_bitvector">A dense bitvector</a></li>
@ -875,6 +879,9 @@ elements (but could contain many), for example, it's much better to use
. Doing so avoids (relatively) expensive malloc/free calls, which dwarf the
cost of adding the elements to the container. </p>
</div>
<!-- ======================================================================= -->
<h3>
<a name="ds_sequential">Sequential Containers (std::vector, std::list, etc)</a>
@ -883,7 +890,7 @@ cost of adding the elements to the container. </p>
<div>
There are a variety of sequential containers available for you, based on your
needs. Pick the first in this section that will do what you want.
<!-- _______________________________________________________________________ -->
<h4>
<a name="dss_arrayref">llvm/ADT/ArrayRef.h</a>
@ -926,6 +933,22 @@ destructors will be run for every element in the array (re-sizable vectors only
construct those elements actually used).</p>
</div>
<!-- _______________________________________________________________________ -->
<h4>
<a name="dss_tinyptrvector">"llvm/ADT/TinyPtrVector.h"</a>
</h4>
<div>
<p><tt>TinyPtrVector&lt;Type&gt;</tt> is a highly specialized collection class
that is optimized to avoid allocation in the case when a vector has zero or one
elements. It has two major restrictions: 1) it can only hold values of pointer
type, and 2) it cannot hold a null pointer.</p>
<p>Since this container is highly specialized, it is rarely used.</p>
</div>
<!-- _______________________________________________________________________ -->
<h4>
<a name="dss_smallvector">"llvm/ADT/SmallVector.h"</a>
@ -1190,9 +1213,187 @@ std::priority_queue, std::stack, etc. These provide simplified access to an
underlying container but don't affect the cost of the container itself.</p>
</div>
</div>
<!-- ======================================================================= -->
<h3>
<a name="ds_string">String-like containers</a>
</h3>
<div>
<p>
There are a variety of ways to pass around and use strings in C and C++, and
LLVM adds a few new options to choose from. Pick the first option on this list
that will do what you need, they are ordered according to their relative cost.
</p>
<p>
Note that is is generally preferred to <em>not</em> pass strings around as
"<tt>const char*</tt>"'s. These have a number of problems, including the fact
that they cannot represent embedded nul ("\0") characters, and do not have a
length available efficiently. The general replacement for '<tt>const
char*</tt>' is StringRef.
</p>
<p>For more information on choosing string containers for APIs, please see
<a href="#string_apis">Passing strings</a>.</p>
<!-- _______________________________________________________________________ -->
<h4>
<a name="dss_stringref">llvm/ADT/StringRef.h</a>
</h4>
<div>
<p>
The StringRef class is a simple value class that contains a pointer to a
character and a length, and is quite related to the <a
href="#dss_arrayref">ArrayRef</a> class (but specialized for arrays of
characters). Because StringRef carries a length with it, it safely handles
strings with embedded nul characters in it, getting the length does not require
a strlen call, and it even has very convenient APIs for slicing and dicing the
character range that it represents.
</p>
<p>
StringRef is ideal for passing simple strings around that are known to be live,
either because they are C string literals, std::string, a C array, or a
SmallVector. Each of these cases has an efficient implicit conversion to
StringRef, which doesn't result in a dynamic strlen being executed.
</p>
<p>StringRef has a few major limitations which make more powerful string
containers useful:</p>
<ol>
<li>You cannot directly convert a StringRef to a 'const char*' because there is
no way to add a trailing nul (unlike the .c_str() method on various stronger
classes).</li>
<li>StringRef doesn't own or keep alive the underlying string bytes.
As such it can easily lead to dangling pointers, and is not suitable for
embedding in datastructures in most cases (instead, use an std::string or
something like that).</li>
<li>For the same reason, StringRef cannot be used as the return value of a
method if the method "computes" the result string. Instead, use
std::string.</li>
<li>StringRef's do not allow you to mutate the pointed-to string bytes and it
doesn't allow you to insert or remove bytes from the range. For editing
operations like this, it interoperates with the <a
href="#dss_twine">Twine</a> class.</li>
</ol>
<p>Because of its strengths and limitations, it is very common for a function to
take a StringRef and for a method on an object to return a StringRef that
points into some string that it owns.</p>
</div>
<!-- _______________________________________________________________________ -->
<h4>
<a name="dss_twine">llvm/ADT/Twine.h</a>
</h4>
<div>
<p>
The Twine class is used as an intermediary datatype for APIs that want to take
a string that can be constructed inline with a series of concatenations.
Twine works by forming recursive instances of the Twine datatype (a simple
value object) on the stack as temporary objects, linking them together into a
tree which is then linearized when the Twine is consumed. Twine is only safe
to use as the argument to a function, and should always be a const reference,
e.g.:
</p>
<pre>
void foo(const Twine &amp;T);
...
StringRef X = ...
unsigned i = ...
foo(X + "." + Twine(i));
</pre>
<p>This example forms a string like "blarg.42" by concatenating the values
together, and does not form intermediate strings containing "blarg" or
"blarg.".
</p>
<p>Because Twine is constructed with temporary objects on the stack, and
because these instances are destroyed at the end of the current statement,
it is an inherently dangerous API. For example, this simple variant contains
undefined behavior and will probably crash:</p>
<pre>
void foo(const Twine &amp;T);
...
StringRef X = ...
unsigned i = ...
const Twine &amp;Tmp = X + "." + Twine(i);
foo(Tmp);
</pre>
<p>... because the temporaries are destroyed before the call. That said,
Twine's are much more efficient than intermediate std::string temporaries, and
they work really well with StringRef. Just be aware of their limitations.</p>
</div>
<!-- _______________________________________________________________________ -->
<h4>
<a name="dss_smallstring">llvm/ADT/SmallString.h</a>
</h4>
<div>
<p>SmallString is a subclass of <a href="#dss_smallvector">SmallVector</a> that
adds some convenience APIs like += that takes StringRef's. SmallString avoids
allocating memory in the case when the preallocated space is enough to hold its
data, and it calls back to general heap allocation when required. Since it owns
its data, it is very safe to use and supports full mutation of the string.</p>
<p>Like SmallVector's, the big downside to SmallString is their sizeof. While
they are optimized for small strings, they themselves are not particularly
small. This means that they work great for temporary scratch buffers on the
stack, but should not generally be put into the heap: it is very rare to
see a SmallString as the member of a frequently-allocated heap data structure
or returned by-value.
</p>
</div>
<!-- _______________________________________________________________________ -->
<h4>
<a name="dss_stdstring">std::string</a>
</h4>
<div>
<p>The standard C++ std::string class is a very general class that (like
SmallString) owns its underlying data. sizeof(std::string) is very reasonable
so it can be embedded into heap data structures and returned by-value.
On the other hand, std::string is highly inefficient for inline editing (e.g.
concatenating a bunch of stuff together) and because it is provided by the
standard library, its performance characteristics depend a lot of the host
standard library (e.g. libc++ and MSVC provide a highly optimized string
class, GCC contains a really slow implementation).
</p>
<p>The major disadvantage of std::string is that almost every operation that
makes them larger can allocate memory, which is slow. As such, it is better
to use SmallVector or Twine as a scratch buffer, but then use std::string to
persist the result.</p>
</div>
<!-- end of strings -->
</div>
<!-- ======================================================================= -->
<h3>
<a name="ds_set">Set-Like Containers (std::set, SmallSet, SetVector, etc)</a>
@ -1381,12 +1582,13 @@ elements out of (linear time), unless you use it's "pop_back" method, which is
faster.
</p>
<p>SetVector is an adapter class that defaults to using std::vector and std::set
for the underlying containers, so it is quite expensive. However,
<tt>"llvm/ADT/SetVector.h"</tt> also provides a SmallSetVector class, which
defaults to using a SmallVector and SmallSet of a specified size. If you use
this, and if your sets are dynamically smaller than N, you will save a lot of
heap traffic.</p>
<p><tt>SetVector</tt> is an adapter class that defaults to
using <tt>std::vector</tt> and a size 16 <tt>SmallSet</tt> for the underlying
containers, so it is quite expensive. However,
<tt>"llvm/ADT/SetVector.h"</tt> also provides a <tt>SmallSetVector</tt>
class, which defaults to using a <tt>SmallVector</tt> and <tt>SmallSet</tt>
of a specified size. If you use this, and if your sets are dynamically
smaller than <tt>N</tt>, you will save a lot of heap traffic.</p>
</div>
@ -1634,20 +1836,6 @@ always better.</p>
</div>
<!-- ======================================================================= -->
<h3>
<a name="ds_string">String-like containers</a>
</h3>
<div>
<p>
TODO: const char* vs stringref vs smallstring vs std::string. Describe twine,
xref to #string_apis.
</p>
</div>
<!-- ======================================================================= -->
<h3>
<a name="ds_bit">Bit storage containers (BitVector, SparseBitVector)</a>
@ -3867,7 +4055,7 @@ arguments. An argument has a pointer to the parent Function.</p>
<a href="mailto:dhurjati@cs.uiuc.edu">Dinakar Dhurjati</a> and
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
<a href="http://llvm.org/">The LLVM Compiler Infrastructure</a><br>
Last modified: $Date: 2011-07-12 13:37:02 +0200 (Tue, 12 Jul 2011) $
Last modified: $Date: 2011-10-11 08:33:56 +0200 (Tue, 11 Oct 2011) $
</address>
</body>

File diff suppressed because it is too large Load Diff

99
docs/SegmentedStacks.html Normal file
View File

@ -0,0 +1,99 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Segmented Stacks in LLVM</title>
<link rel="stylesheet" href="llvm.css" type="text/css">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<h1>Segmented Stacks in LLVM</h1>
<div class="doc_author">
<p>Written by <a href="mailto:sanjoy@playingwithpointers.com">Sanjoy Das</a></p>
</div>
<ol>
<li><a href="#intro">Introduction</a></li>
<li><a href="#implementation">Implementation Details</a>
<ol>
<li><a href="#morestack">Allocating Stacklets</a></li>
<li><a href="#alloca">Variable Sized Allocas</a></li>
</ol>
</li>
<li><a href="#results">Results</a>
<ol>
<li><a href="#go">Go on LLVM</a></li>
<li><a href="#abi">Runtime ABI</a></li>
</ol>
</li>
</ol>
<h2><a name="intro">Introduction</a></h2>
<div>
<p>
Segmented stack allows stack space to be allocated incrementally than as a monolithic chunk (of some worst case size) at thread initialization. This is done by allocating stack blocks (henceforth called <em>stacklets</em>) and linking them into a doubly linked list. The function prologue is responsible for checking if the current stacklet has enough space for the function to execute; and if not, call into the libgcc runtime to allocate more stack space. Support for segmented stacks on x86 / Linux is currently being worked on.
</p>
<p>
The runtime functionality is <a href="http://gcc.gnu.org/wiki/SplitStacks">already there in libgcc</a>.
</p>
</div>
<h2><a name="implementation">Implementation Details</a></h2>
<div>
<h3><a name="morestack">Allocating Stacklets</a></h3>
<div>
<p>
As mentioned above, the function prologue checks if the current stacklet has enough space. The current approach is to use a slot in the TCB to store the current stack limit (minus the amount of space needed to allocate a new block) - this slot's offset is again dictated by <code>libgcc</code>. The generated assembly looks like this on x86-64:
</p>
<pre>
leaq -8(%rsp), %r10
cmpq %fs:112, %r10
jg .LBB0_2
# More stack space needs to be allocated
movabsq $8, %r10 # The amount of space needed
movabsq $0, %r11 # The total size of arguments passed on stack
callq __morestack
ret # The reason for this extra return is explained below
.LBB0_2:
# Usual prologue continues here
</pre>
<p>
The size of function arguments on the stack needs to be passed to <code> __morestack</code> (this function is implemented in <code>libgcc</code>) since that number of bytes has to be copied from the previous stacklet to the current one. This is so that SP (and FP) relative addressing of function arguments work as expected.
</p>
<p>
The unusual <code>ret</code> is needed to have the function which made a call to <code>__morestack</code> return correctly. <code>__morestack</code>, instead of returning, calls into <code>.LBB0_2</code>. This is possible since both, the size of the <code>ret</code> instruction and the PC of call to <code>__morestack</code> are known. When the function body returns, control is transferred back to <code>__morestack</code>. <code>__morestack</code> then de-allocates the new stacklet, restores the correct SP value, and does a second return, which returns control to the correct caller.
</p>
</div>
<h3><a name="alloca">Variable Sized Allocas</a></h3>
<div>
<p>
The section on <a href="#morestack">allocating stacklets</a> automatically assumes that every stack frame will be of fixed size. However, LLVM allows the use of the <code>llvm.alloca</code> intrinsic to allocate dynamically sized blocks of memory on the stack. When faced with such a variable-sized alloca, code is generated to
</p>
<ul>
<li>Check if the current stacklet has enough space. If yes, just bump the SP, like in the normal case.</li>
<li>If not, generate a call to <code>libgcc</code>, which allocates the memory from the heap.</li>
</ul>
<p>
The memory allocated from the heap is linked into a list in the current stacklet, and freed along with the same. This prevents a memory leak.
</p>
</div>
</div>
<hr>
<address>
<a href="http://jigsaw.w3.org/css-validator/check/referer">
<img src="http://jigsaw.w3.org/css-validator/images/vcss-blue" alt="Valid CSS">
</a>
<a href="http://validator.w3.org/check/referer">
<img src="http://www.w3.org/Icons/valid-html401-blue" alt="Valid HTML 4.01">
</a>
<a href="mailto:sanjoy@playingwithpointers.com">Sanjoy Das</a><br>
<a href="http://llvm.org/">LLVM Compiler Infrastructure</a><br>
Last modified: $Date$
</address>
</body>
</html>

View File

@ -298,8 +298,8 @@ height="369">
of tags are loosely bound to the tag values of DWARF information entries.
However, that does not restrict the use of the information supplied to DWARF
targets. To facilitate versioning of debug information, the tag is augmented
with the current debug version (LLVMDebugVersion = 8 &lt;&lt; 16 or 0x80000 or
524288.)</a></p>
with the current debug version (LLVMDebugVersion = 8 &lt;&lt; 16 or
0x80000 or 524288.)</a></p>
<p>The details of the various descriptors follow.</p>
@ -324,6 +324,10 @@ height="369">
i1, ;; True if this is optimized.
metadata, ;; Flags
i32 ;; Runtime version
metadata ;; List of enums types
metadata ;; List of retained types
metadata ;; List of subprograms
metadata ;; List of global variables
}
</pre>
</div>
@ -337,7 +341,8 @@ height="369">
<p>Compile unit descriptors provide the root context for objects declared in a
specific compilation unit. File descriptors are defined using this context.
These descriptors are collected by a named metadata
<tt>!llvm.dbg.cu</tt>.
<tt>!llvm.dbg.cu</tt>. Compile unit descriptor keeps track of subprograms,
global variables and type information.
</div>
@ -355,7 +360,7 @@ height="369">
;; (DW_TAG_file_type)
metadata, ;; Source file name
metadata, ;; Source file directory (includes trailing slash)
metadata ;; Reference to compile unit where defined
metadata ;; Unused
}
</pre>
</div>
@ -365,8 +370,7 @@ height="369">
provide context for source line correspondence. </p>
<p>Each input file is encoded as a separate file descriptor in LLVM debugging
information output. Each file descriptor would be defined using a
compile unit. </p>
information output. </p>
</div>
@ -434,6 +438,7 @@ global variables are collected by named metadata <tt>!llvm.dbg.gv</tt>.</p>
Function *,;; Pointer to LLVM function
metadata, ;; Lists function template parameters
metadata ;; Function declaration descriptor
metadata ;; List of function variables
}
</pre>
</div>
@ -467,10 +472,23 @@ global variables are collected by named metadata <tt>!llvm.dbg.gv</tt>.</p>
</pre>
</div>
<p>These descriptors provide debug information about nested blocks within a
<p>This descriptor provides debug information about nested blocks within a
subprogram. The line number and column numbers are used to dinstinguish
two lexical blocks at same depth. </p>
<div class="doc_code">
<pre>
!3 = metadata !{
i32, ;; Tag = 11 + <a href="#LLVMDebugVersion">LLVMDebugVersion</a> (DW_TAG_lexical_block)
metadata ;; Reference to the scope we're annotating with a file change
metadata,;; Reference to the file the scope is enclosed in.
}
</pre>
</div>
<p>This descriptor provides a wrapper around a lexical scope to handle file
changes in the middle of a lexical block.</p>
</div>
<!-- ======================================================================= -->
@ -485,7 +503,7 @@ global variables are collected by named metadata <tt>!llvm.dbg.gv</tt>.</p>
!4 = metadata !{
i32, ;; Tag = 36 + <a href="#LLVMDebugVersion">LLVMDebugVersion</a>
;; (DW_TAG_base_type)
metadata, ;; Reference to context (typically a compile unit)
metadata, ;; Reference to context
metadata, ;; Name (may be "" for anonymous types)
metadata, ;; Reference to file where defined (may be NULL)
i32, ;; Line number where defined (may be 0)
@ -500,7 +518,7 @@ global variables are collected by named metadata <tt>!llvm.dbg.gv</tt>.</p>
<p>These descriptors define primitive types used in the code. Example int, bool
and float. The context provides the scope of the type, which is usually the
top level. Since basic types are not usually user defined the compile unit
top level. Since basic types are not usually user defined the context
and line number can be left as NULL and 0. The size, alignment and offset
are expressed in bits and can be 64 bit values. The alignment is used to
round the offset when embedded in a
@ -585,7 +603,7 @@ DW_TAG_restrict_type = 55
the <a href="#format_derived_type">derived type</a>. </p>
<p><a href="#format_derived_type">Derived type</a> location can be determined
from the compile unit and line number. The size, alignment and offset are
from the context and line number. The size, alignment and offset are
expressed in bits and can be 64 bit values. The alignment is used to round
the offset when embedded in a <a href="#format_composite_type">composite
type</a> (example to keep float doubles on 64 bit boundaries.) The offset is
@ -675,7 +693,7 @@ DW_TAG_inheritance = 28
the formal arguments to the subroutine.</p>
<p><a href="#format_composite_type">Composite type</a> location can be
determined from the compile unit and line number. The size, alignment and
determined from the context and line number. The size, alignment and
offset are expressed in bits and can be 64 bit values. The alignment is used
to round the offset when embedded in
a <a href="#format_composite_type">composite type</a> (as an example, to keep
@ -750,7 +768,9 @@ DW_TAG_inheritance = 28
metadata, ;; Reference to file where defined
i32, ;; 24 bit - Line number where defined
;; 8 bit - Argument number. 1 indicates 1st argument.
metadata ;; Type descriptor
metadata, ;; Type descriptor
i32, ;; flags
metadata ;; (optional) Reference to inline location
}
</pre>
</div>
@ -772,7 +792,7 @@ DW_TAG_return_variable = 258
has no source correspondent.</p>
<p>The context is either the subprogram or block where the variable is defined.
Name the source variable name. Compile unit and line indicate where the
Name the source variable name. Context and line indicate where the
variable was defined. Type descriptor defines the declared type of the
variable.</p>
@ -1794,7 +1814,7 @@ enum Trees {
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
<a href="http://llvm.org/">LLVM Compiler Infrastructure</a><br>
Last modified: $Date: 2011-05-31 20:06:14 +0200 (Tue, 31 May 2011) $
Last modified: $Date: 2011-10-12 00:59:11 +0200 (Wed, 12 Oct 2011) $
</address>
</body>

View File

@ -911,7 +911,7 @@ This should highlight the APIs in <tt>TableGen/Record.h</tt>.</p>
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
<a href="http://llvm.org/">LLVM Compiler Infrastructure</a><br>
Last modified: $Date: 2011-04-23 02:30:22 +0200 (Sat, 23 Apr 2011) $
Last modified: $Date: 2011-10-07 20:25:05 +0200 (Fri, 07 Oct 2011) $
</address>
</body>

View File

@ -227,11 +227,13 @@ the pass itself.</p>
<p>Now that we have a way to compile our new pass, we just have to write it.
Start out with:</p>
<div class="doc_code"><pre>
<div class="doc_code">
<pre>
<b>#include</b> "<a href="http://llvm.org/doxygen/Pass_8h-source.html">llvm/Pass.h</a>"
<b>#include</b> "<a href="http://llvm.org/doxygen/Function_8h-source.html">llvm/Function.h</a>"
<b>#include</b> "<a href="http://llvm.org/doxygen/raw__ostream_8h.html">llvm/Support/raw_ostream.h</a>"
</pre></div>
</pre>
</div>
<p>Which are needed because we are writing a <tt><a
href="http://llvm.org/doxygen/classllvm_1_1Pass.html">Pass</a></tt>,
@ -240,53 +242,66 @@ href="http://llvm.org/doxygen/classllvm_1_1Function.html">Function</a></tt>'s,
and we will be doing some printing.</p>
<p>Next we have:</p>
<div class="doc_code"><pre>
<div class="doc_code">
<pre>
<b>using namespace llvm;</b>
</pre></div>
</pre>
</div>
<p>... which is required because the functions from the include files
live in the llvm namespace.
</p>
live in the llvm namespace.</p>
<p>Next we have:</p>
<div class="doc_code"><pre>
<div class="doc_code">
<pre>
<b>namespace</b> {
</pre></div>
</pre>
</div>
<p>... which starts out an anonymous namespace. Anonymous namespaces are to C++
what the "<tt>static</tt>" keyword is to C (at global scope). It makes the
things declared inside of the anonymous namespace only visible to the current
things declared inside of the anonymous namespace visible only to the current
file. If you're not familiar with them, consult a decent C++ book for more
information.</p>
<p>Next, we declare our pass itself:</p>
<div class="doc_code"><pre>
<div class="doc_code">
<pre>
<b>struct</b> Hello : <b>public</b> <a href="#FunctionPass">FunctionPass</a> {
</pre></div><p>
</pre>
</div>
<p>This declares a "<tt>Hello</tt>" class that is a subclass of <tt><a
href="http://llvm.org/doxygen/classllvm_1_1FunctionPass.html">FunctionPass</a></tt>.
The different builtin pass subclasses are described in detail <a
href="#passtype">later</a>, but for now, know that <a
href="#FunctionPass"><tt>FunctionPass</tt></a>'s operate a function at a
href="#FunctionPass"><tt>FunctionPass</tt></a>'s operate on a function at a
time.</p>
<div class="doc_code"><pre>
static char ID;
Hello() : FunctionPass(ID) {}
</pre></div><p>
<div class="doc_code">
<pre>
static char ID;
Hello() : FunctionPass(ID) {}
</pre>
</div>
<p> This declares pass identifier used by LLVM to identify pass. This allows LLVM to
avoid using expensive C++ runtime information.</p>
<p>This declares pass identifier used by LLVM to identify pass. This allows LLVM
to avoid using expensive C++ runtime information.</p>
<div class="doc_code"><pre>
<div class="doc_code">
<pre>
<b>virtual bool</b> <a href="#runOnFunction">runOnFunction</a>(Function &amp;F) {
errs() &lt;&lt; "<i>Hello: </i>" &lt;&lt; F.getName() &lt;&lt; "\n";
errs() &lt;&lt; "<i>Hello: </i>";
errs().write_escaped(F.getName()) &lt;&lt; "\n";
<b>return false</b>;
}
}; <i>// end of struct Hello</i>
</pre></div>
} <i>// end of anonymous namespace</i>
</pre>
</div>
<p>We declare a "<a href="#runOnFunction"><tt>runOnFunction</tt></a>" method,
which overloads an abstract virtual method inherited from <a
@ -294,31 +309,34 @@ href="#FunctionPass"><tt>FunctionPass</tt></a>. This is where we are supposed
to do our thing, so we just print out our message with the name of each
function.</p>
<div class="doc_code"><pre>
char Hello::ID = 0;
</pre></div>
<div class="doc_code">
<pre>
char Hello::ID = 0;
</pre>
</div>
<p> We initialize pass ID here. LLVM uses ID's address to identify pass so
<p>We initialize pass ID here. LLVM uses ID's address to identify a pass, so
initialization value is not important.</p>
<div class="doc_code"><pre>
static RegisterPass&lt;Hello&gt; X("<i>hello</i>", "<i>Hello World Pass</i>",
false /* Only looks at CFG */,
false /* Analysis Pass */);
} <i>// end of anonymous namespace</i>
</pre></div>
<div class="doc_code">
<pre>
static RegisterPass&lt;Hello&gt; X("<i>hello</i>", "<i>Hello World Pass</i>",
false /* Only looks at CFG */,
false /* Analysis Pass */);
</pre>
</div>
<p>Lastly, we <a href="#registration">register our class</a> <tt>Hello</tt>,
giving it a command line
argument "<tt>hello</tt>", and a name "<tt>Hello World Pass</tt>".
Last two arguments describe its behavior.
If a pass walks CFG without modifying it then third argument is set to true.
If a pass is an analysis pass, for example dominator tree pass, then true
is supplied as fourth argument. </p>
<p>Lastly, we <a href="#registration">register our class</a> <tt>Hello</tt>,
giving it a command line argument "<tt>hello</tt>", and a name "<tt>Hello World
Pass</tt>". The last two arguments describe its behavior: if a pass walks CFG
without modifying it then the third argument is set to <tt>true</tt>; if a pass
is an analysis pass, for example dominator tree pass, then <tt>true</tt> is
supplied as the fourth argument.</p>
<p>As a whole, the <tt>.cpp</tt> file looks like:</p>
<div class="doc_code"><pre>
<div class="doc_code">
<pre>
<b>#include</b> "<a href="http://llvm.org/doxygen/Pass_8h-source.html">llvm/Pass.h</a>"
<b>#include</b> "<a href="http://llvm.org/doxygen/Function_8h-source.html">llvm/Function.h</a>"
<b>#include</b> "<a href="http://llvm.org/doxygen/raw__ostream_8h.html">llvm/Support/raw_ostream.h</a>"
@ -332,24 +350,26 @@ is supplied as fourth argument. </p>
Hello() : FunctionPass(ID) {}
<b>virtual bool</b> <a href="#runOnFunction">runOnFunction</a>(Function &amp;F) {
errs() &lt;&lt; "<i>Hello: </i>" &lt;&lt; F.getName() &lt;&lt; "\n";
errs() &lt;&lt; "<i>Hello: </i>";
errs().write_escaped(F.getName()) &lt;&lt; '\n';
<b>return false</b>;
}
};
char Hello::ID = 0;
static RegisterPass&lt;Hello&gt; X("hello", "Hello World Pass", false, false);
}
</pre></div>
};
}
char Hello::ID = 0;
static RegisterPass&lt;Hello&gt; X("hello", "Hello World Pass", false, false);
</pre>
</div>
<p>Now that it's all together, compile the file with a simple "<tt>gmake</tt>"
command in the local directory and you should get a new file
"<tt>Debug+Asserts/lib/Hello.so</tt>" under the top level directory of the LLVM
source tree (not in the local directory). Note that everything in this file is
contained in an anonymous namespace: this reflects the fact that passes are self
contained units that do not need external interfaces (although they can have
them) to be useful.</p>
contained in an anonymous namespace &mdash; this reflects the fact that passes
are self contained units that do not need external interfaces (although they can
have them) to be useful.</p>
</div>
@ -1929,7 +1949,7 @@ Despite that, we have kept the LLVM passes SMP ready, and you should too.</p>
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
<a href="http://llvm.org/">The LLVM Compiler Infrastructure</a><br>
Last modified: $Date: 2011-04-23 02:30:22 +0200 (Sat, 23 Apr 2011) $
Last modified: $Date: 2011-10-11 09:03:52 +0200 (Tue, 11 Oct 2011) $
</address>
</body>

File diff suppressed because it is too large Load Diff

View File

@ -63,6 +63,11 @@ Discusses how to get up and running quickly with the LLVM infrastructure.
Everything from unpacking and compilation of the distribution to execution of
some tools.</li>
<li><a href="CMake.html">LLVM CMake guide</a> - An addendum to the main Getting
Started guide for those using the <a href="http://www.cmake.org/">CMake build
system</a>.
</li>
<li><a href="GettingStartedVS.html">Getting Started with the LLVM System using
Microsoft Visual Studio</a> - An addendum to the main Getting Started guide for
those using Visual Studio on Windows.</li>
@ -87,7 +92,6 @@ Current tools:
<a href="/cmds/opt.html">opt</a>,
<a href="/cmds/llc.html">llc</a>,
<a href="/cmds/lli.html">lli</a>,
<a href="/cmds/llvmc.html">llvmc</a>
<a href="/cmds/llvmgcc.html">llvm-gcc</a>,
<a href="/cmds/llvmgxx.html">llvm-g++</a>,
<a href="/cmds/bugpoint.html">bugpoint</a>,
@ -216,14 +220,6 @@ in LLVM.</li>
<li><a href="Bugpoint.html">Bugpoint</a> - automatic bug finder and test-case
reducer description and usage information.</li>
<li><a href="CompilerDriverTutorial.html">Compiler Driver (llvmc) Tutorial</a>
- This document is a tutorial introduction to the usage and
configuration of the LLVM compiler driver tool, <tt>llvmc</tt>.</li>
<li><a href="CompilerDriver.html">Compiler Driver (llvmc)
Reference</a> - This document describes the design and configuration
of <tt>llvmc</tt> in more detail.</li>
<li><a href="BitCodeFormat.html">LLVM Bitcode File Format</a> - This describes
the file format and encoding used for LLVM "bc" files.</li>
@ -289,7 +285,7 @@ times each day, making it a high volume list.</li>
src="http://www.w3.org/Icons/valid-html401-blue" alt="Valid HTML 4.01"></a>
<a href="http://llvm.org/">LLVM Compiler Infrastructure</a><br>
Last modified: $Date: 2011-07-06 20:31:02 +0200 (Wed, 06 Jul 2011) $
Last modified: $Date: 2011-10-11 18:35:07 +0200 (Tue, 11 Oct 2011) $
</address>
</body></html>

View File

@ -70,6 +70,14 @@ h4, .doc_subsubsection { margin: 2.0em 0.5em 0.5em 0.5em;
display: table;
}
blockquote pre {
padding: 1em 2em 1em 1em;
border: solid 1px gray;
background: #eeeeee;
margin: 0 1em 0 1em;
display: table;
}
h2+div, h2+p {text-align: left; padding-left: 20pt; padding-right: 10pt;}
h3+div, h3+p {text-align: left; padding-left: 20pt; padding-right: 10pt;}
h4+div, h4+p {text-align: left; padding-left: 20pt; padding-right: 10pt;}

View File

@ -801,10 +801,10 @@ course.) To build this, just compile with:</p>
<div class="doc_code">
<pre>
# Compile
g++ -g -O3 toy.cpp
# Run
./a.out
# Compile
clang++ -g -O3 toy.cpp
# Run
./a.out
</pre>
</div>
@ -1225,7 +1225,7 @@ int main() {
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
<a href="http://llvm.org/">The LLVM Compiler Infrastructure</a><br>
Last modified: $Date: 2011-04-23 02:30:22 +0200 (Sat, 23 Apr 2011) $
Last modified: $Date: 2011-10-16 10:07:38 +0200 (Sun, 16 Oct 2011) $
</address>
</body>
</html>

View File

@ -266,7 +266,7 @@ Value *CallExprAST::Codegen() {
if (ArgsV.back() == 0) return 0;
}
return Builder.CreateCall(CalleeF, ArgsV.begin(), ArgsV.end(), "calltmp");
return Builder.CreateCall(CalleeF, ArgsV, "calltmp");
}
</pre>
</div>
@ -308,11 +308,11 @@ bodies and external function declarations. The code starts with:</p>
<pre>
Function *PrototypeAST::Codegen() {
// Make the function type: double(double,double) etc.
std::vector&lt;const Type*&gt; Doubles(Args.size(),
Type::getDoubleTy(getGlobalContext()));
std::vector&lt;Type*&gt; Doubles(Args.size(),
Type::getDoubleTy(getGlobalContext()));
FunctionType *FT = FunctionType::get(Type::getDoubleTy(getGlobalContext()),
Doubles, false);
Function *F = Function::Create(FT, Function::ExternalLinkage, Name, TheModule);
</pre>
</div>
@ -532,9 +532,9 @@ functions. For example:
<pre>
ready> <b>4+5</b>;
Read top-level expression:
define double @""() {
define double @0() {
entry:
ret double 9.000000e+00
ret double 9.000000e+00
}
</pre>
</div>
@ -553,13 +553,13 @@ ready&gt; <b>def foo(a b) a*a + 2*a*b + b*b;</b>
Read function definition:
define double @foo(double %a, double %b) {
entry:
%multmp = fmul double %a, %a
%multmp1 = fmul double 2.000000e+00, %a
%multmp2 = fmul double %multmp1, %b
%addtmp = fadd double %multmp, %multmp2
%multmp3 = fmul double %b, %b
%addtmp4 = fadd double %addtmp, %multmp3
ret double %addtmp4
%multmp = fmul double %a, %a
%multmp1 = fmul double 2.000000e+00, %a
%multmp2 = fmul double %multmp1, %b
%addtmp = fadd double %multmp, %multmp2
%multmp3 = fmul double %b, %b
%addtmp4 = fadd double %addtmp, %multmp3
ret double %addtmp4
}
</pre>
</div>
@ -573,10 +573,10 @@ ready&gt; <b>def bar(a) foo(a, 4.0) + bar(31337);</b>
Read function definition:
define double @bar(double %a) {
entry:
%calltmp = call double @foo(double %a, double 4.000000e+00)
%calltmp1 = call double @bar(double 3.133700e+04)
%addtmp = fadd double %calltmp, %calltmp1
ret double %addtmp
%calltmp = call double @foo(double %a, double 4.000000e+00)
%calltmp1 = call double @bar(double 3.133700e+04)
%addtmp = fadd double %calltmp, %calltmp1
ret double %addtmp
}
</pre>
</div>
@ -593,10 +593,10 @@ declare double @cos(double)
ready&gt; <b>cos(1.234);</b>
Read top-level expression:
define double @""() {
define double @1() {
entry:
%calltmp = call double @cos(double 1.234000e+00)
ret double %calltmp
%calltmp = call double @cos(double 1.234000e+00)
ret double %calltmp
}
</pre>
</div>
@ -609,37 +609,37 @@ entry:
ready&gt; <b>^D</b>
; ModuleID = 'my cool jit'
define double @""() {
define double @0() {
entry:
%addtmp = fadd double 4.000000e+00, 5.000000e+00
ret double %addtmp
%addtmp = fadd double 4.000000e+00, 5.000000e+00
ret double %addtmp
}
define double @foo(double %a, double %b) {
entry:
%multmp = fmul double %a, %a
%multmp1 = fmul double 2.000000e+00, %a
%multmp2 = fmul double %multmp1, %b
%addtmp = fadd double %multmp, %multmp2
%multmp3 = fmul double %b, %b
%addtmp4 = fadd double %addtmp, %multmp3
ret double %addtmp4
%multmp = fmul double %a, %a
%multmp1 = fmul double 2.000000e+00, %a
%multmp2 = fmul double %multmp1, %b
%addtmp = fadd double %multmp, %multmp2
%multmp3 = fmul double %b, %b
%addtmp4 = fadd double %addtmp, %multmp3
ret double %addtmp4
}
define double @bar(double %a) {
entry:
%calltmp = call double @foo(double %a, double 4.000000e+00)
%calltmp1 = call double @bar(double 3.133700e+04)
%addtmp = fadd double %calltmp, %calltmp1
ret double %addtmp
%calltmp = call double @foo(double %a, double 4.000000e+00)
%calltmp1 = call double @bar(double 3.133700e+04)
%addtmp = fadd double %calltmp, %calltmp1
ret double %addtmp
}
declare double @cos(double)
define double @""() {
define double @1() {
entry:
%calltmp = call double @cos(double 1.234000e+00)
ret double %calltmp
%calltmp = call double @cos(double 1.234000e+00)
ret double %calltmp
}
</pre>
</div>
@ -670,10 +670,10 @@ our makefile/command line about which options to use:</p>
<div class="doc_code">
<pre>
# Compile
g++ -g -O3 toy.cpp `llvm-config --cppflags --ldflags --libs core` -o toy
# Run
./toy
# Compile
clang++ -g -O3 toy.cpp `llvm-config --cppflags --ldflags --libs core` -o toy
# Run
./toy
</pre>
</div>
@ -1081,13 +1081,13 @@ Value *CallExprAST::Codegen() {
if (ArgsV.back() == 0) return 0;
}
return Builder.CreateCall(CalleeF, ArgsV.begin(), ArgsV.end(), "calltmp");
return Builder.CreateCall(CalleeF, ArgsV, "calltmp");
}
Function *PrototypeAST::Codegen() {
// Make the function type: double(double,double) etc.
std::vector&lt;const Type*&gt; Doubles(Args.size(),
Type::getDoubleTy(getGlobalContext()));
std::vector&lt;Type*&gt; Doubles(Args.size(),
Type::getDoubleTy(getGlobalContext()));
FunctionType *FT = FunctionType::get(Type::getDoubleTy(getGlobalContext()),
Doubles, false);
@ -1262,7 +1262,7 @@ int main() {
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
<a href="http://llvm.org/">The LLVM Compiler Infrastructure</a><br>
Last modified: $Date: 2011-04-23 02:30:22 +0200 (Sat, 23 Apr 2011) $
Last modified: $Date: 2011-10-16 10:07:38 +0200 (Sun, 16 Oct 2011) $
</address>
</body>
</html>

View File

@ -343,9 +343,10 @@ code that is statically linked into your application.</p>
<div class="doc_code">
<pre>
ready&gt; <b>4+5;</b>
define double @""() {
Read top-level expression:
define double @0() {
entry:
ret double 9.000000e+00
ret double 9.000000e+00
}
<em>Evaluated to 9.000000</em>
@ -363,16 +364,17 @@ ready&gt; <b>def testfunc(x y) x + y*2; </b>
Read function definition:
define double @testfunc(double %x, double %y) {
entry:
%multmp = fmul double %y, 2.000000e+00
%addtmp = fadd double %multmp, %x
ret double %addtmp
%multmp = fmul double %y, 2.000000e+00
%addtmp = fadd double %multmp, %x
ret double %addtmp
}
ready&gt; <b>testfunc(4, 10);</b>
define double @""() {
Read top-level expression:
define double @1() {
entry:
%calltmp = call double @testfunc(double 4.000000e+00, double 1.000000e+01)
ret double %calltmp
%calltmp = call double @testfunc(double 4.000000e+00, double 1.000000e+01)
ret double %calltmp
}
<em>Evaluated to 24.000000</em>
@ -404,21 +406,34 @@ Read extern:
declare double @cos(double)
ready&gt; <b>sin(1.0);</b>
Read top-level expression:
define double @2() {
entry:
ret double 0x3FEAED548F090CEE
}
<em>Evaluated to 0.841471</em>
ready&gt; <b>def foo(x) sin(x)*sin(x) + cos(x)*cos(x);</b>
Read function definition:
define double @foo(double %x) {
entry:
%calltmp = call double @sin(double %x)
%multmp = fmul double %calltmp, %calltmp
%calltmp2 = call double @cos(double %x)
%multmp4 = fmul double %calltmp2, %calltmp2
%addtmp = fadd double %multmp, %multmp4
ret double %addtmp
%calltmp = call double @sin(double %x)
%multmp = fmul double %calltmp, %calltmp
%calltmp2 = call double @cos(double %x)
%multmp4 = fmul double %calltmp2, %calltmp2
%addtmp = fadd double %multmp, %multmp4
ret double %addtmp
}
ready&gt; <b>foo(4.0);</b>
Read top-level expression:
define double @3() {
entry:
%calltmp = call double @foo(double 4.000000e+00)
ret double %calltmp
}
<em>Evaluated to 1.000000</em>
</pre>
</div>
@ -484,10 +499,10 @@ LLVM JIT and optimizer. To build this example, use:
<div class="doc_code">
<pre>
# Compile
g++ -g toy.cpp `llvm-config --cppflags --ldflags --libs core jit native` -O3 -o toy
# Run
./toy
# Compile
clang++ -g toy.cpp `llvm-config --cppflags --ldflags --libs core jit native` -O3 -o toy
# Run
./toy
</pre>
</div>
@ -509,9 +524,9 @@ at runtime.</p>
#include "llvm/Analysis/Verifier.h"
#include "llvm/Analysis/Passes.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetSelect.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Support/IRBuilder.h"
#include "llvm/Support/TargetSelect.h"
#include &lt;cstdio&gt;
#include &lt;string&gt;
#include &lt;map&gt;
@ -905,13 +920,13 @@ Value *CallExprAST::Codegen() {
if (ArgsV.back() == 0) return 0;
}
return Builder.CreateCall(CalleeF, ArgsV.begin(), ArgsV.end(), "calltmp");
return Builder.CreateCall(CalleeF, ArgsV, "calltmp");
}
Function *PrototypeAST::Codegen() {
// Make the function type: double(double,double) etc.
std::vector&lt;const Type*&gt; Doubles(Args.size(),
Type::getDoubleTy(getGlobalContext()));
std::vector&lt;Type*&gt; Doubles(Args.size(),
Type::getDoubleTy(getGlobalContext()));
FunctionType *FT = FunctionType::get(Type::getDoubleTy(getGlobalContext()),
Doubles, false);
@ -1013,6 +1028,9 @@ static void HandleTopLevelExpression() {
// Evaluate a top-level expression into an anonymous function.
if (FunctionAST *F = ParseTopLevelExpr()) {
if (Function *LF = F-&gt;Codegen()) {
fprintf(stderr, "Read top-level expression:");
LF->dump();
// JIT the function, returning a function pointer.
void *FPtr = TheExecutionEngine-&gt;getPointerToFunction(LF);
@ -1076,7 +1094,7 @@ int main() {
// Create the JIT. This takes ownership of the module.
std::string ErrStr;
TheExecutionEngine = EngineBuilder(TheModule).setErrorStr(&amp;ErrStr).create();
TheExecutionEngine = EngineBuilder(TheModule).setErrorStr(&amp;ErrStr).create();
if (!TheExecutionEngine) {
fprintf(stderr, "Could not create ExecutionEngine: %s\n", ErrStr.c_str());
exit(1);
@ -1129,7 +1147,7 @@ TheExecutionEngine = EngineBuilder(TheModule).setErrorStr(&amp;ErrStr).create();
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
<a href="http://llvm.org/">The LLVM Compiler Infrastructure</a><br>
Last modified: $Date: 2011-04-23 02:30:22 +0200 (Sat, 23 Apr 2011) $
Last modified: $Date: 2011-10-16 10:07:38 +0200 (Sun, 16 Oct 2011) $
</address>
</body>
</html>

View File

@ -259,20 +259,20 @@ declare double @bar()
define double @baz(double %x) {
entry:
%ifcond = fcmp one double %x, 0.000000e+00
br i1 %ifcond, label %then, label %else
%ifcond = fcmp one double %x, 0.000000e+00
br i1 %ifcond, label %then, label %else
then: ; preds = %entry
%calltmp = call double @foo()
br label %ifcont
%calltmp = call double @foo()
br label %ifcont
else: ; preds = %entry
%calltmp1 = call double @bar()
br label %ifcont
%calltmp1 = call double @bar()
br label %ifcont
ifcont: ; preds = %else, %then
%iftmp = phi double [ %calltmp, %then ], [ %calltmp1, %else ]
ret double %iftmp
%iftmp = phi double [ %calltmp, %then ], [ %calltmp1, %else ]
ret double %iftmp
}
</pre>
</div>
@ -660,25 +660,25 @@ declare double @putchard(double)
define double @printstar(double %n) {
entry:
; initial value = 1.0 (inlined into phi)
br label %loop
; initial value = 1.0 (inlined into phi)
br label %loop
loop: ; preds = %loop, %entry
%i = phi double [ 1.000000e+00, %entry ], [ %nextvar, %loop ]
; body
%calltmp = call double @putchard(double 4.200000e+01)
; increment
%nextvar = fadd double %i, 1.000000e+00
%i = phi double [ 1.000000e+00, %entry ], [ %nextvar, %loop ]
; body
%calltmp = call double @putchard(double 4.200000e+01)
; increment
%nextvar = fadd double %i, 1.000000e+00
; termination test
%cmptmp = fcmp ult double %i, %n
%booltmp = uitofp i1 %cmptmp to double
%loopcond = fcmp one double %booltmp, 0.000000e+00
br i1 %loopcond, label %loop, label %afterloop
; termination test
%cmptmp = fcmp ult double %i, %n
%booltmp = uitofp i1 %cmptmp to double
%loopcond = fcmp one double %booltmp, 0.000000e+00
br i1 %loopcond, label %loop, label %afterloop
afterloop: ; preds = %loop
; loop always returns 0.0
ret double 0.000000e+00
; loop always returns 0.0
ret double 0.000000e+00
}
</pre>
</div>
@ -829,10 +829,11 @@ statement.</p>
</div>
<p>With the code for the body of the loop complete, we just need to finish up
the control flow for it. This code remembers the end block (for the phi node), then creates the block for the loop exit ("afterloop"). Based on the value of the
exit condition, it creates a conditional branch that chooses between executing
the loop again and exiting the loop. Any future code is emitted in the
"afterloop" block, so it sets the insertion position to it.</p>
the control flow for it. This code remembers the end block (for the phi node),
then creates the block for the loop exit ("afterloop"). Based on the value of
the exit condition, it creates a conditional branch that chooses between
executing the loop again and exiting the loop. Any future code is emitted in
the "afterloop" block, so it sets the insertion position to it.</p>
<div class="doc_code">
<pre>
@ -880,10 +881,10 @@ if/then/else and for expressions.. To build this example, use:
<div class="doc_code">
<pre>
# Compile
g++ -g toy.cpp `llvm-config --cppflags --ldflags --libs core jit native` -O3 -o toy
# Run
./toy
# Compile
clang++ -g toy.cpp `llvm-config --cppflags --ldflags --libs core jit native` -O3 -o toy
# Run
./toy
</pre>
</div>
@ -900,9 +901,9 @@ if/then/else and for expressions.. To build this example, use:
#include "llvm/Analysis/Verifier.h"
#include "llvm/Analysis/Passes.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetSelect.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Support/IRBuilder.h"
#include "llvm/Support/TargetSelect.h"
#include &lt;cstdio&gt;
#include &lt;string&gt;
#include &lt;map&gt;
@ -1397,7 +1398,7 @@ Value *CallExprAST::Codegen() {
if (ArgsV.back() == 0) return 0;
}
return Builder.CreateCall(CalleeF, ArgsV.begin(), ArgsV.end(), "calltmp");
return Builder.CreateCall(CalleeF, ArgsV, "calltmp");
}
Value *IfExprAST::Codegen() {
@ -1546,8 +1547,8 @@ Value *ForExprAST::Codegen() {
Function *PrototypeAST::Codegen() {
// Make the function type: double(double,double) etc.
std::vector&lt;const Type*&gt; Doubles(Args.size(),
Type::getDoubleTy(getGlobalContext()));
std::vector&lt;Type*&gt; Doubles(Args.size(),
Type::getDoubleTy(getGlobalContext()));
FunctionType *FT = FunctionType::get(Type::getDoubleTy(getGlobalContext()),
Doubles, false);
@ -1765,7 +1766,7 @@ int main() {
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
<a href="http://llvm.org/">The LLVM Compiler Infrastructure</a><br>
Last modified: $Date: 2011-04-23 02:30:22 +0200 (Sat, 23 Apr 2011) $
Last modified: $Date: 2011-10-16 10:07:38 +0200 (Sun, 16 Oct 2011) $
</address>
</body>
</html>

View File

@ -293,8 +293,8 @@ Value *BinaryExprAST::Codegen() {
Function *F = TheModule-&gt;getFunction(std::string("binary")+Op);
assert(F &amp;&amp; "binary operator not found!");
Value *Ops[] = { L, R };
return Builder.CreateCall(F, Ops, Ops+2, "binop");</b>
Value *Ops[2] = { L, R };
return Builder.CreateCall(F, Ops, "binop");</b>
}
</pre>
@ -505,7 +505,9 @@ defined to print out the specified value and a newline):</p>
<div class="doc_code">
<pre>
ready&gt; <b>extern printd(x);</b>
Read extern: declare double @printd(double)
Read extern:
declare double @printd(double)
ready&gt; <b>def binary : 1 (x y) 0; # Low-precedence operator that ignores operands.</b>
..
ready&gt; <b>printd(123) : printd(456) : printd(789);</b>
@ -555,6 +557,9 @@ def binary&amp; 6 (LHS RHS)
def binary = 9 (LHS RHS)
!(LHS &lt; RHS | LHS &gt; RHS);
# Define ':' for sequencing: as a low-precedence operator that ignores operands
# and just returns the RHS.
def binary : 1 (x y) y;
</pre>
</div>
@ -579,9 +584,10 @@ def printdensity(d)
else
putchard(42); # '*'</b>
...
ready&gt; <b>printdensity(1): printdensity(2): printdensity(3) :
printdensity(4): printdensity(5): printdensity(9): putchard(10);</b>
*++..
ready&gt; <b>printdensity(1): printdensity(2): printdensity(3):
printdensity(4): printdensity(5): printdensity(9):
putchard(10);</b>
**++.
Evaluated to 0.000000
</pre>
</div>
@ -593,7 +599,7 @@ converge:</p>
<div class="doc_code">
<pre>
# determine whether the specific location diverges.
# Determine whether the specific location diverges.
# Solve for z = z^2 + c in the complex plane.
def mandleconverger(real imag iters creal cimag)
if iters &gt; 255 | (real*real + imag*imag &gt; 4) then
@ -603,25 +609,25 @@ def mandleconverger(real imag iters creal cimag)
2*real*imag + cimag,
iters+1, creal, cimag);
# return the number of iterations required for the iteration to escape
# Return the number of iterations required for the iteration to escape
def mandleconverge(real imag)
mandleconverger(real, imag, 0, real, imag);
</pre>
</div>
<p>This "z = z<sup>2</sup> + c" function is a beautiful little creature that is the basis
for computation of the <a
href="http://en.wikipedia.org/wiki/Mandelbrot_set">Mandelbrot Set</a>. Our
<tt>mandelconverge</tt> function returns the number of iterations that it takes
for a complex orbit to escape, saturating to 255. This is not a very useful
function by itself, but if you plot its value over a two-dimensional plane,
you can see the Mandelbrot set. Given that we are limited to using putchard
here, our amazing graphical output is limited, but we can whip together
<p>This "<code>z = z<sup>2</sup> + c</code>" function is a beautiful little
creature that is the basis for computation of
the <a href="http://en.wikipedia.org/wiki/Mandelbrot_set">Mandelbrot Set</a>.
Our <tt>mandelconverge</tt> function returns the number of iterations that it
takes for a complex orbit to escape, saturating to 255. This is not a very
useful function by itself, but if you plot its value over a two-dimensional
plane, you can see the Mandelbrot set. Given that we are limited to using
putchard here, our amazing graphical output is limited, but we can whip together
something using the density plotter above:</p>
<div class="doc_code">
<pre>
# compute and plot the mandlebrot set with the specified 2 dimensional range
# Compute and plot the mandlebrot set with the specified 2 dimensional range
# info.
def mandelhelp(xmin xmax xstep ymin ymax ystep)
for y = ymin, y &lt; ymax, ystep in (
@ -808,13 +814,19 @@ if/then/else and for expressions.. To build this example, use:
<div class="doc_code">
<pre>
# Compile
g++ -g toy.cpp `llvm-config --cppflags --ldflags --libs core jit native` -O3 -o toy
# Run
./toy
# Compile
clang++ -g toy.cpp `llvm-config --cppflags --ldflags --libs core jit native` -O3 -o toy
# Run
./toy
</pre>
</div>
<p>On some platforms, you will need to specify -rdynamic or -Wl,--export-dynamic
when linking. This ensures that symbols defined in the main executable are
exported to the dynamic linker and so are available for symbol resolution at
run time. This is not needed if you compile your support code into a shared
library, although doing that will cause problems on Windows.</p>
<p>Here is the code:</p>
<div class="doc_code">
@ -828,9 +840,9 @@ if/then/else and for expressions.. To build this example, use:
#include "llvm/Analysis/Verifier.h"
#include "llvm/Analysis/Passes.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetSelect.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Support/IRBuilder.h"
#include "llvm/Support/TargetSelect.h"
#include &lt;cstdio&gt;
#include &lt;string&gt;
#include &lt;map&gt;
@ -1409,8 +1421,8 @@ Value *BinaryExprAST::Codegen() {
Function *F = TheModule-&gt;getFunction(std::string("binary")+Op);
assert(F &amp;&amp; "binary operator not found!");
Value *Ops[] = { L, R };
return Builder.CreateCall(F, Ops, Ops+2, "binop");
Value *Ops[2] = { L, R };
return Builder.CreateCall(F, Ops, "binop");
}
Value *CallExprAST::Codegen() {
@ -1429,7 +1441,7 @@ Value *CallExprAST::Codegen() {
if (ArgsV.back() == 0) return 0;
}
return Builder.CreateCall(CalleeF, ArgsV.begin(), ArgsV.end(), "calltmp");
return Builder.CreateCall(CalleeF, ArgsV, "calltmp");
}
Value *IfExprAST::Codegen() {
@ -1578,8 +1590,8 @@ Value *ForExprAST::Codegen() {
Function *PrototypeAST::Codegen() {
// Make the function type: double(double,double) etc.
std::vector&lt;const Type*&gt; Doubles(Args.size(),
Type::getDoubleTy(getGlobalContext()));
std::vector&lt;Type*&gt; Doubles(Args.size(),
Type::getDoubleTy(getGlobalContext()));
FunctionType *FT = FunctionType::get(Type::getDoubleTy(getGlobalContext()),
Doubles, false);
@ -1811,7 +1823,7 @@ int main() {
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
<a href="http://llvm.org/">The LLVM Compiler Infrastructure</a><br>
Last modified: $Date: 2011-04-23 02:30:22 +0200 (Sat, 23 Apr 2011) $
Last modified: $Date: 2011-10-16 10:07:38 +0200 (Sun, 16 Oct 2011) $
</address>
</body>
</html>

View File

@ -102,19 +102,19 @@ The LLVM IR that we want for this example looks like this:</p>
define i32 @test(i1 %Condition) {
entry:
br i1 %Condition, label %cond_true, label %cond_false
br i1 %Condition, label %cond_true, label %cond_false
cond_true:
%X.0 = load i32* @G
br label %cond_next
%X.0 = load i32* @G
br label %cond_next
cond_false:
%X.1 = load i32* @H
br label %cond_next
%X.1 = load i32* @H
br label %cond_next
cond_next:
%X.2 = phi i32 [ %X.1, %cond_false ], [ %X.0, %cond_true ]
ret i32 %X.2
%X.2 = phi i32 [ %X.1, %cond_false ], [ %X.0, %cond_true ]
ret i32 %X.2
}
</pre>
</div>
@ -174,12 +174,12 @@ being declared with global variable definitions, they are declared with the
<pre>
define i32 @example() {
entry:
%X = alloca i32 ; type of %X is i32*.
...
%tmp = load i32* %X ; load the stack value %X from the stack.
%tmp2 = add i32 %tmp, 1 ; increment it
store i32 %tmp2, i32* %X ; store it back
...
%X = alloca i32 ; type of %X is i32*.
...
%tmp = load i32* %X ; load the stack value %X from the stack.
%tmp2 = add i32 %tmp, 1 ; increment it
store i32 %tmp2, i32* %X ; store it back
...
</pre>
</div>
@ -196,22 +196,22 @@ example to use the alloca technique to avoid using a PHI node:</p>
define i32 @test(i1 %Condition) {
entry:
%X = alloca i32 ; type of %X is i32*.
br i1 %Condition, label %cond_true, label %cond_false
%X = alloca i32 ; type of %X is i32*.
br i1 %Condition, label %cond_true, label %cond_false
cond_true:
%X.0 = load i32* @G
store i32 %X.0, i32* %X ; Update X
br label %cond_next
%X.0 = load i32* @G
store i32 %X.0, i32* %X ; Update X
br label %cond_next
cond_false:
%X.1 = load i32* @H
store i32 %X.1, i32* %X ; Update X
br label %cond_next
%X.1 = load i32* @H
store i32 %X.1, i32* %X ; Update X
br label %cond_next
cond_next:
%X.2 = load i32* %X ; Read X
ret i32 %X.2
%X.2 = load i32* %X ; Read X
ret i32 %X.2
}
</pre>
</div>
@ -242,19 +242,19 @@ $ <b>llvm-as &lt; example.ll | opt -mem2reg | llvm-dis</b>
define i32 @test(i1 %Condition) {
entry:
br i1 %Condition, label %cond_true, label %cond_false
br i1 %Condition, label %cond_true, label %cond_false
cond_true:
%X.0 = load i32* @G
br label %cond_next
%X.0 = load i32* @G
br label %cond_next
cond_false:
%X.1 = load i32* @H
br label %cond_next
%X.1 = load i32* @H
br label %cond_next
cond_next:
%X.01 = phi i32 [ %X.1, %cond_false ], [ %X.0, %cond_true ]
ret i32 %X.01
%X.01 = phi i32 [ %X.1, %cond_false ], [ %X.0, %cond_true ]
ret i32 %X.01
}
</pre>
</div>
@ -542,30 +542,30 @@ recursive fib function. Before the optimization:</p>
<pre>
define double @fib(double %x) {
entry:
<b>%x1 = alloca double
store double %x, double* %x1
%x2 = load double* %x1</b>
%cmptmp = fcmp ult double %x2, 3.000000e+00
%booltmp = uitofp i1 %cmptmp to double
%ifcond = fcmp one double %booltmp, 0.000000e+00
br i1 %ifcond, label %then, label %else
<b>%x1 = alloca double
store double %x, double* %x1
%x2 = load double* %x1</b>
%cmptmp = fcmp ult double %x2, 3.000000e+00
%booltmp = uitofp i1 %cmptmp to double
%ifcond = fcmp one double %booltmp, 0.000000e+00
br i1 %ifcond, label %then, label %else
then: ; preds = %entry
br label %ifcont
br label %ifcont
else: ; preds = %entry
<b>%x3 = load double* %x1</b>
%subtmp = fsub double %x3, 1.000000e+00
%calltmp = call double @fib(double %subtmp)
<b>%x4 = load double* %x1</b>
%subtmp5 = fsub double %x4, 2.000000e+00
%calltmp6 = call double @fib(double %subtmp5)
%addtmp = fadd double %calltmp, %calltmp6
br label %ifcont
<b>%x3 = load double* %x1</b>
%subtmp = fsub double %x3, 1.000000e+00
%calltmp = call double @fib(double %subtmp)
<b>%x4 = load double* %x1</b>
%subtmp5 = fsub double %x4, 2.000000e+00
%calltmp6 = call double @fib(double %subtmp5)
%addtmp = fadd double %calltmp, %calltmp6
br label %ifcont
ifcont: ; preds = %else, %then
%iftmp = phi double [ 1.000000e+00, %then ], [ %addtmp, %else ]
ret double %iftmp
%iftmp = phi double [ 1.000000e+00, %then ], [ %addtmp, %else ]
ret double %iftmp
}
</pre>
</div>
@ -584,25 +584,25 @@ PHI node for it, so we still just make the PHI.</p>
<pre>
define double @fib(double %x) {
entry:
%cmptmp = fcmp ult double <b>%x</b>, 3.000000e+00
%booltmp = uitofp i1 %cmptmp to double
%ifcond = fcmp one double %booltmp, 0.000000e+00
br i1 %ifcond, label %then, label %else
%cmptmp = fcmp ult double <b>%x</b>, 3.000000e+00
%booltmp = uitofp i1 %cmptmp to double
%ifcond = fcmp one double %booltmp, 0.000000e+00
br i1 %ifcond, label %then, label %else
then:
br label %ifcont
br label %ifcont
else:
%subtmp = fsub double <b>%x</b>, 1.000000e+00
%calltmp = call double @fib(double %subtmp)
%subtmp5 = fsub double <b>%x</b>, 2.000000e+00
%calltmp6 = call double @fib(double %subtmp5)
%addtmp = fadd double %calltmp, %calltmp6
br label %ifcont
%subtmp = fsub double <b>%x</b>, 1.000000e+00
%calltmp = call double @fib(double %subtmp)
%subtmp5 = fsub double <b>%x</b>, 2.000000e+00
%calltmp6 = call double @fib(double %subtmp5)
%addtmp = fadd double %calltmp, %calltmp6
br label %ifcont
ifcont: ; preds = %else, %then
%iftmp = phi double [ 1.000000e+00, %then ], [ %addtmp, %else ]
ret double %iftmp
%iftmp = phi double [ 1.000000e+00, %then ], [ %addtmp, %else ]
ret double %iftmp
}
</pre>
</div>
@ -617,21 +617,21 @@ such blatent inefficiencies :).</p>
<pre>
define double @fib(double %x) {
entry:
%cmptmp = fcmp ult double %x, 3.000000e+00
%booltmp = uitofp i1 %cmptmp to double
%ifcond = fcmp ueq double %booltmp, 0.000000e+00
br i1 %ifcond, label %else, label %ifcont
%cmptmp = fcmp ult double %x, 3.000000e+00
%booltmp = uitofp i1 %cmptmp to double
%ifcond = fcmp ueq double %booltmp, 0.000000e+00
br i1 %ifcond, label %else, label %ifcont
else:
%subtmp = fsub double %x, 1.000000e+00
%calltmp = call double @fib(double %subtmp)
%subtmp5 = fsub double %x, 2.000000e+00
%calltmp6 = call double @fib(double %subtmp5)
%addtmp = fadd double %calltmp, %calltmp6
ret double %addtmp
%subtmp = fsub double %x, 1.000000e+00
%calltmp = call double @fib(double %subtmp)
%subtmp5 = fsub double %x, 2.000000e+00
%calltmp6 = call double @fib(double %subtmp5)
%addtmp = fadd double %calltmp, %calltmp6
ret double %addtmp
ifcont:
ret double 1.000000e+00
ret double 1.000000e+00
}
</pre>
</div>
@ -988,10 +988,10 @@ variables and var/in support. To build this example, use:
<div class="doc_code">
<pre>
# Compile
g++ -g toy.cpp `llvm-config --cppflags --ldflags --libs core jit native` -O3 -o toy
# Run
./toy
# Compile
clang++ -g toy.cpp `llvm-config --cppflags --ldflags --libs core jit native` -O3 -o toy
# Run
./toy
</pre>
</div>
@ -1008,9 +1008,9 @@ variables and var/in support. To build this example, use:
#include "llvm/Analysis/Verifier.h"
#include "llvm/Analysis/Passes.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetSelect.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Support/IRBuilder.h"
#include "llvm/Support/TargetSelect.h"
#include &lt;cstdio&gt;
#include &lt;string&gt;
#include &lt;map&gt;
@ -1686,8 +1686,8 @@ Value *BinaryExprAST::Codegen() {
Function *F = TheModule-&gt;getFunction(std::string("binary")+Op);
assert(F &amp;&amp; "binary operator not found!");
Value *Ops[] = { L, R };
return Builder.CreateCall(F, Ops, Ops+2, "binop");
Value *Ops[2] = { L, R };
return Builder.CreateCall(F, Ops, "binop");
}
Value *CallExprAST::Codegen() {
@ -1706,7 +1706,7 @@ Value *CallExprAST::Codegen() {
if (ArgsV.back() == 0) return 0;
}
return Builder.CreateCall(CalleeF, ArgsV.begin(), ArgsV.end(), "calltmp");
return Builder.CreateCall(CalleeF, ArgsV, "calltmp");
}
Value *IfExprAST::Codegen() {
@ -1907,8 +1907,8 @@ Value *VarExprAST::Codegen() {
Function *PrototypeAST::Codegen() {
// Make the function type: double(double,double) etc.
std::vector&lt;const Type*&gt; Doubles(Args.size(),
Type::getDoubleTy(getGlobalContext()));
std::vector&lt;Type*&gt; Doubles(Args.size(),
Type::getDoubleTy(getGlobalContext()));
FunctionType *FT = FunctionType::get(Type::getDoubleTy(getGlobalContext()),
Doubles, false);
@ -2158,7 +2158,7 @@ int main() {
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
<a href="http://llvm.org/">The LLVM Compiler Infrastructure</a><br>
Last modified: $Date: 2011-04-23 02:30:22 +0200 (Sat, 23 Apr 2011) $
Last modified: $Date: 2011-10-16 10:07:38 +0200 (Sun, 16 Oct 2011) $
</address>
</body>
</html>

View File

@ -11,6 +11,7 @@ LEVEL := ../..
include $(LEVEL)/Makefile.common
HTML := $(wildcard $(PROJ_SRC_DIR)/*.html)
PNG := $(wildcard $(PROJ_SRC_DIR)/*.png)
EXTRA_DIST := $(HTML) index.html
HTML_DIR := $(DESTDIR)$(PROJ_docsdir)/html/tutorial
@ -18,6 +19,7 @@ install-local:: $(HTML)
$(Echo) Installing HTML Tutorial Documentation
$(Verb) $(MKDIR) $(HTML_DIR)
$(Verb) $(DataInstall) $(HTML) $(HTML_DIR)
$(Verb) $(DataInstall) $(PNG) $(HTML_DIR)
$(Verb) $(DataInstall) $(PROJ_SRC_DIR)/index.html $(HTML_DIR)
uninstall-local::

View File

@ -80,8 +80,8 @@ void BrainF::header(LLVMContext& C) {
//%arr = malloc i8, i32 %d
ConstantInt *val_mem = ConstantInt::get(C, APInt(32, memtotal));
BasicBlock* BB = builder->GetInsertBlock();
const Type* IntPtrTy = IntegerType::getInt32Ty(C);
const Type* Int8Ty = IntegerType::getInt8Ty(C);
Type* IntPtrTy = IntegerType::getInt32Ty(C);
Type* Int8Ty = IntegerType::getInt8Ty(C);
Constant* allocsize = ConstantExpr::getSizeOf(Int8Ty);
allocsize = ConstantExpr::getTruncOrBitCast(allocsize, IntPtrTy);
ptr_arr = CallInst::CreateMalloc(BB, IntPtrTy, Int8Ty, allocsize, val_mem,
@ -162,8 +162,7 @@ void BrainF::header(LLVMContext& C) {
};
Constant *msgptr = ConstantExpr::
getGetElementPtr(aberrormsg, gep_params,
array_lengthof(gep_params));
getGetElementPtr(aberrormsg, gep_params);
Value *puts_params[] = {
msgptr

View File

@ -31,9 +31,9 @@
#include "llvm/Bitcode/ReaderWriter.h"
#include "llvm/ExecutionEngine/GenericValue.h"
#include "llvm/ExecutionEngine/JIT.h"
#include "llvm/Target/TargetSelect.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/raw_ostream.h"
#include <iostream>
#include <fstream>

View File

@ -40,7 +40,8 @@
//
// Cases -1 and 7 are caught by a C++ test harness where the validity of
// of a C++ catch(...) clause catching a generated exception with a
// type info type of 7 is questionable.
// type info type of 7 is explained by: example in rules 1.6.4 in
// http://sourcery.mentor.com/public/cxx-abi/abi-eh.html (v1.22)
//
// This code uses code from the llvm compiler-rt project and the llvm
// Kaleidoscope project.
@ -56,11 +57,16 @@
#include "llvm/Intrinsics.h"
#include "llvm/Analysis/Verifier.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetSelect.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Support/IRBuilder.h"
#include "llvm/Support/Dwarf.h"
#include "llvm/Support/TargetSelect.h"
#ifdef OLD_EXC_SYSTEM
// See use of UpgradeExceptionHandling(...) below
#include "llvm/AutoUpgrade.h"
#endif
// FIXME: Although all systems tested with (Linux, OS X), do not need this
// header file included. A user on ubuntu reported, undefined symbols
@ -81,7 +87,7 @@
#endif
// System C++ ABI unwind types from:
// http://refspecs.freestandards.org/abi-eh-1.21.html
// http://sourcery.mentor.com/public/cxx-abi/abi-eh.html (v1.22)
extern "C" {
@ -182,6 +188,9 @@ static std::vector<std::string> ourTypeInfoNames;
static std::map<int, std::string> ourTypeInfoNamesIndex;
static llvm::StructType *ourTypeInfoType;
#ifndef OLD_EXC_SYSTEM
static llvm::StructType *ourCaughtResultType;
#endif
static llvm::StructType *ourExceptionType;
static llvm::StructType *ourUnwindExceptionType;
@ -209,7 +218,7 @@ typedef std::vector<llvm::Type*> ArgTypes;
/// @param isVarArg function uses vararg arguments
/// @returns function instance
llvm::Function *createFunction(llvm::Module &module,
const llvm::Type *retType,
llvm::Type *retType,
const ArgTypes &theArgTypes,
const ArgNames &theArgNames,
const std::string &functName,
@ -246,7 +255,7 @@ llvm::Function *createFunction(llvm::Module &module,
/// @returns AllocaInst instance
static llvm::AllocaInst *createEntryBlockAlloca(llvm::Function &function,
const std::string &varName,
const llvm::Type *type,
llvm::Type *type,
llvm::Constant *initWith = 0) {
llvm::BasicBlock &block = function.getEntryBlock();
llvm::IRBuilder<> tmp(&block, block.begin());
@ -893,9 +902,8 @@ void generateStringPrint(llvm::LLVMContext &context,
builder.CreateStore(stringConstant, stringVar);
}
llvm::Value *cast =
builder.CreatePointerCast(stringVar,
builder.getInt8PtrTy());
llvm::Value *cast = builder.CreatePointerCast(stringVar,
builder.getInt8PtrTy());
builder.CreateCall(printFunct, cast);
}
@ -937,9 +945,8 @@ void generateIntegerPrint(llvm::LLVMContext &context,
builder.CreateStore(stringConstant, stringVar);
}
llvm::Value *cast =
builder.CreateBitCast(stringVar,
builder.getInt8PtrTy());
llvm::Value *cast = builder.CreateBitCast(stringVar,
builder.getInt8PtrTy());
builder.CreateCall2(&printFunct, &toPrint, cast);
}
@ -962,6 +969,9 @@ void generateIntegerPrint(llvm::LLVMContext &context,
/// @param unwindResumeBlock unwind resume block
/// @param exceptionCaughtFlag reference exception caught/thrown status storage
/// @param exceptionStorage reference to exception pointer storage
#ifndef OLD_EXC_SYSTEM
/// @param caughtResultStorage reference to landingpad result storage
#endif
/// @returns newly created block
static llvm::BasicBlock *createFinallyBlock(llvm::LLVMContext &context,
llvm::Module &module,
@ -972,28 +982,42 @@ static llvm::BasicBlock *createFinallyBlock(llvm::LLVMContext &context,
llvm::BasicBlock &terminatorBlock,
llvm::BasicBlock &unwindResumeBlock,
llvm::Value **exceptionCaughtFlag,
llvm::Value **exceptionStorage) {
llvm::Value **exceptionStorage
#ifndef OLD_EXC_SYSTEM
,llvm::Value **caughtResultStorage
#endif
) {
assert(exceptionCaughtFlag &&
"ExceptionDemo::createFinallyBlock(...):exceptionCaughtFlag "
"is NULL");
assert(exceptionStorage &&
"ExceptionDemo::createFinallyBlock(...):exceptionStorage "
"is NULL");
#ifndef OLD_EXC_SYSTEM
assert(caughtResultStorage &&
"ExceptionDemo::createFinallyBlock(...):caughtResultStorage "
"is NULL");
#endif
*exceptionCaughtFlag =
createEntryBlockAlloca(toAddTo,
"exceptionCaught",
ourExceptionNotThrownState->getType(),
ourExceptionNotThrownState);
*exceptionCaughtFlag = createEntryBlockAlloca(toAddTo,
"exceptionCaught",
ourExceptionNotThrownState->getType(),
ourExceptionNotThrownState);
const llvm::PointerType *exceptionStorageType =
builder.getInt8PtrTy();
*exceptionStorage =
createEntryBlockAlloca(toAddTo,
"exceptionStorage",
exceptionStorageType,
llvm::ConstantPointerNull::get(
exceptionStorageType));
llvm::PointerType *exceptionStorageType = builder.getInt8PtrTy();
*exceptionStorage = createEntryBlockAlloca(toAddTo,
"exceptionStorage",
exceptionStorageType,
llvm::ConstantPointerNull::get(
exceptionStorageType));
#ifndef OLD_EXC_SYSTEM
*caughtResultStorage = createEntryBlockAlloca(toAddTo,
"caughtResultStorage",
ourCaughtResultType,
llvm::ConstantAggregateZero::get(
ourCaughtResultType));
#endif
llvm::BasicBlock *ret = llvm::BasicBlock::Create(context,
blockName,
@ -1010,10 +1034,10 @@ static llvm::BasicBlock *createFinallyBlock(llvm::LLVMContext &context,
bufferToPrint.str(),
USE_GLOBAL_STR_CONSTS);
llvm::SwitchInst *theSwitch =
builder.CreateSwitch(builder.CreateLoad(*exceptionCaughtFlag),
&terminatorBlock,
2);
llvm::SwitchInst *theSwitch = builder.CreateSwitch(builder.CreateLoad(
*exceptionCaughtFlag),
&terminatorBlock,
2);
theSwitch->addCase(ourExceptionCaughtState, &terminatorBlock);
theSwitch->addCase(ourExceptionThrownState, &unwindResumeBlock);
@ -1121,29 +1145,35 @@ llvm::Function *createCatchWrappedInvokeFunction(llvm::Module &module,
"normal",
ret);
// Unwind block for invoke
llvm::BasicBlock *exceptionBlock =
llvm::BasicBlock::Create(context, "exception", ret);
llvm::BasicBlock *exceptionBlock = llvm::BasicBlock::Create(context,
"exception",
ret);
// Block which routes exception to correct catch handler block
llvm::BasicBlock *exceptionRouteBlock =
llvm::BasicBlock::Create(context, "exceptionRoute", ret);
llvm::BasicBlock *exceptionRouteBlock = llvm::BasicBlock::Create(context,
"exceptionRoute",
ret);
// Foreign exception handler
llvm::BasicBlock *externalExceptionBlock =
llvm::BasicBlock::Create(context, "externalException", ret);
llvm::BasicBlock *externalExceptionBlock = llvm::BasicBlock::Create(context,
"externalException",
ret);
// Block which calls _Unwind_Resume
llvm::BasicBlock *unwindResumeBlock =
llvm::BasicBlock::Create(context, "unwindResume", ret);
llvm::BasicBlock *unwindResumeBlock = llvm::BasicBlock::Create(context,
"unwindResume",
ret);
// Clean up block which delete exception if needed
llvm::BasicBlock *endBlock =
llvm::BasicBlock::Create(context, "end", ret);
llvm::BasicBlock *endBlock = llvm::BasicBlock::Create(context, "end", ret);
std::string nextName;
std::vector<llvm::BasicBlock*> catchBlocks(numExceptionsToCatch);
llvm::Value *exceptionCaughtFlag = NULL;
llvm::Value *exceptionStorage = NULL;
#ifndef OLD_EXC_SYSTEM
llvm::Value *caughtResultStorage = NULL;
#endif
// Finally block which will branch to unwindResumeBlock if
// exception is not caught. Initializes/allocates stack locations.
@ -1156,7 +1186,11 @@ llvm::Function *createCatchWrappedInvokeFunction(llvm::Module &module,
*endBlock,
*unwindResumeBlock,
&exceptionCaughtFlag,
&exceptionStorage);
&exceptionStorage
#ifndef OLD_EXC_SYSTEM
,&caughtResultStorage
#endif
);
for (unsigned i = 0; i < numExceptionsToCatch; ++i) {
nextName = ourTypeInfoNames[exceptionTypesToCatch[i]];
@ -1181,8 +1215,7 @@ llvm::Function *createCatchWrappedInvokeFunction(llvm::Module &module,
builder.CreateInvoke(&toInvoke,
normalBlock,
exceptionBlock,
args.begin(),
args.end());
args);
// End Block
@ -1193,8 +1226,7 @@ llvm::Function *createCatchWrappedInvokeFunction(llvm::Module &module,
builder,
"Gen: In end block: exiting in " + ourId + ".\n",
USE_GLOBAL_STR_CONSTS);
llvm::Function *deleteOurException =
module.getFunction("deleteOurException");
llvm::Function *deleteOurException = module.getFunction("deleteOurException");
// Note: function handles NULL exceptions
builder.CreateCall(deleteOurException,
@ -1218,28 +1250,57 @@ llvm::Function *createCatchWrappedInvokeFunction(llvm::Module &module,
builder.SetInsertPoint(unwindResumeBlock);
llvm::Function *resumeOurException =
module.getFunction("_Unwind_Resume");
#ifndef OLD_EXC_SYSTEM
builder.CreateResume(builder.CreateLoad(caughtResultStorage));
#else
llvm::Function *resumeOurException = module.getFunction("_Unwind_Resume");
builder.CreateCall(resumeOurException,
builder.CreateLoad(exceptionStorage));
builder.CreateUnreachable();
#endif
// Exception Block
builder.SetInsertPoint(exceptionBlock);
llvm::Function *ehException = module.getFunction("llvm.eh.exception");
llvm::Function *personality = module.getFunction("ourPersonality");
#ifndef OLD_EXC_SYSTEM
llvm::LandingPadInst *caughtResult =
builder.CreateLandingPad(ourCaughtResultType,
personality,
numExceptionsToCatch,
"landingPad");
caughtResult->setCleanup(true);
for (unsigned i = 0; i < numExceptionsToCatch; ++i) {
// Set up type infos to be caught
caughtResult->addClause(module.getGlobalVariable(
ourTypeInfoNames[exceptionTypesToCatch[i]]));
}
llvm::Value *unwindException = builder.CreateExtractValue(caughtResult, 0);
llvm::Value *retTypeInfoIndex = builder.CreateExtractValue(caughtResult, 1);
// FIXME: Redundant storage which, beyond utilizing value of
// caughtResultStore for unwindException storage, may be alleviated
// alltogether with a block rearrangement
builder.CreateStore(caughtResult, caughtResultStorage);
builder.CreateStore(unwindException, exceptionStorage);
builder.CreateStore(ourExceptionThrownState, exceptionCaughtFlag);
#else
llvm::Function *ehException = module.getFunction("llvm.eh.exception");
// Retrieve thrown exception
llvm::Value *unwindException = builder.CreateCall(ehException);
// Store exception and flag
builder.CreateStore(unwindException, exceptionStorage);
builder.CreateStore(ourExceptionThrownState, exceptionCaughtFlag);
llvm::Function *personality = module.getFunction("ourPersonality");
llvm::Value *functPtr =
builder.CreatePointerCast(personality,
builder.getInt8PtrTy());
llvm::Value *functPtr = builder.CreatePointerCast(personality,
builder.getInt8PtrTy());
args.clear();
args.push_back(unwindException);
@ -1263,9 +1324,8 @@ llvm::Function *createCatchWrappedInvokeFunction(llvm::Module &module,
// handles this call. This landing pad (this exception block), will be
// called either because it nees to cleanup (call finally) or a type
// info was found which matched the thrown exception.
llvm::Value *retTypeInfoIndex = builder.CreateCall(ehSelector,
args.begin(),
args.end());
llvm::Value *retTypeInfoIndex = builder.CreateCall(ehSelector, args);
#endif
// Retrieve exception_class member from thrown exception
// (_Unwind_Exception instance). This member tells us whether or not
@ -1305,10 +1365,10 @@ llvm::Function *createCatchWrappedInvokeFunction(llvm::Module &module,
// (OurException instance).
//
// Note: ourBaseFromUnwindOffset is usually negative
llvm::Value *typeInfoThrown =
builder.CreatePointerCast(builder.CreateConstGEP1_64(unwindException,
llvm::Value *typeInfoThrown = builder.CreatePointerCast(
builder.CreateConstGEP1_64(unwindException,
ourBaseFromUnwindOffset),
ourExceptionType->getPointerTo());
ourExceptionType->getPointerTo());
// Retrieve thrown exception type info type
//
@ -1331,10 +1391,9 @@ llvm::Function *createCatchWrappedInvokeFunction(llvm::Module &module,
USE_GLOBAL_STR_CONSTS);
// Route to matched type info catch block or run cleanup finally block
llvm::SwitchInst *switchToCatchBlock =
builder.CreateSwitch(retTypeInfoIndex,
finallyBlock,
numExceptionsToCatch);
llvm::SwitchInst *switchToCatchBlock = builder.CreateSwitch(retTypeInfoIndex,
finallyBlock,
numExceptionsToCatch);
unsigned nextTypeToCatch;
@ -1344,6 +1403,12 @@ llvm::Function *createCatchWrappedInvokeFunction(llvm::Module &module,
llvm::Type::getInt32Ty(context), i),
catchBlocks[nextTypeToCatch]);
}
#ifdef OLD_EXC_SYSTEM
// Must be run before verifier
UpgradeExceptionHandling(&module);
#endif
llvm::verifyFunction(*ret);
fpm.run(*ret);
@ -1395,15 +1460,13 @@ llvm::Function *createThrowExceptionFunction(llvm::Module &module,
"entry",
ret);
// Throws a foreign exception
llvm::BasicBlock *nativeThrowBlock =
llvm::BasicBlock::Create(context,
"nativeThrow",
ret);
llvm::BasicBlock *nativeThrowBlock = llvm::BasicBlock::Create(context,
"nativeThrow",
ret);
// Throws one of our Exceptions
llvm::BasicBlock *generatedThrowBlock =
llvm::BasicBlock::Create(context,
"generatedThrow",
ret);
llvm::BasicBlock *generatedThrowBlock = llvm::BasicBlock::Create(context,
"generatedThrow",
ret);
// Retrieved runtime type info type to throw
llvm::Value *exceptionType = namedValues["exceptTypeToThrow"];
@ -1445,15 +1508,13 @@ llvm::Function *createThrowExceptionFunction(llvm::Module &module,
builder.SetInsertPoint(generatedThrowBlock);
llvm::Function *createOurException =
module.getFunction("createOurException");
llvm::Function *raiseOurException =
module.getFunction("_Unwind_RaiseException");
llvm::Function *createOurException = module.getFunction("createOurException");
llvm::Function *raiseOurException = module.getFunction(
"_Unwind_RaiseException");
// Creates exception to throw with runtime type info type.
llvm::Value *exception =
builder.CreateCall(createOurException,
namedValues["exceptTypeToThrow"]);
llvm::Value *exception = builder.CreateCall(createOurException,
namedValues["exceptTypeToThrow"]);
// Throw generated Exception
builder.CreateCall(raiseOurException, exception);
@ -1501,32 +1562,29 @@ llvm::Function *createUnwindExceptionTest(llvm::Module &module,
createStandardUtilityFunctions(numTypeInfos,
module,
builder);
llvm::Function *nativeThrowFunct =
module.getFunction(nativeThrowFunctName);
llvm::Function *nativeThrowFunct = module.getFunction(nativeThrowFunctName);
// Create exception throw function using the value ~0 to cause
// foreign exceptions to be thrown.
llvm::Function *throwFunct =
createThrowExceptionFunction(module,
builder,
fpm,
"throwFunct",
~0,
*nativeThrowFunct);
llvm::Function *throwFunct = createThrowExceptionFunction(module,
builder,
fpm,
"throwFunct",
~0,
*nativeThrowFunct);
// Inner function will catch even type infos
unsigned innerExceptionTypesToCatch[] = {6, 2, 4};
size_t numExceptionTypesToCatch = sizeof(innerExceptionTypesToCatch) /
sizeof(unsigned);
sizeof(unsigned);
// Generate inner function.
llvm::Function *innerCatchFunct =
createCatchWrappedInvokeFunction(module,
builder,
fpm,
*throwFunct,
"innerCatchFunct",
numExceptionTypesToCatch,
innerExceptionTypesToCatch);
llvm::Function *innerCatchFunct = createCatchWrappedInvokeFunction(module,
builder,
fpm,
*throwFunct,
"innerCatchFunct",
numExceptionTypesToCatch,
innerExceptionTypesToCatch);
// Outer function will catch odd type infos
unsigned outerExceptionTypesToCatch[] = {3, 1, 5};
@ -1534,14 +1592,13 @@ llvm::Function *createUnwindExceptionTest(llvm::Module &module,
sizeof(unsigned);
// Generate outer function
llvm::Function *outerCatchFunct =
createCatchWrappedInvokeFunction(module,
builder,
fpm,
*innerCatchFunct,
"outerCatchFunct",
numExceptionTypesToCatch,
outerExceptionTypesToCatch);
llvm::Function *outerCatchFunct = createCatchWrappedInvokeFunction(module,
builder,
fpm,
*innerCatchFunct,
"outerCatchFunct",
numExceptionTypesToCatch,
outerExceptionTypesToCatch);
// Return outer function to run
return(outerCatchFunct);
@ -1607,12 +1664,12 @@ void runExceptionThrow(llvm::ExecutionEngine *engine,
exc.what());
}
catch (...) {
// Catch all exceptions including our generated ones. I'm not sure
// why this latter functionality should work, as it seems that
// our exceptions should be foreign to C++ (the _Unwind_Exception::
// exception_class should be different from the one used by C++), and
// therefore C++ should ignore the generated exceptions.
// Catch all exceptions including our generated ones. This latter
// functionality works according to the example in rules 1.6.4 of
// http://sourcery.mentor.com/public/cxx-abi/abi-eh.html (v1.22),
// given that these will be exceptions foreign to C++
// (the _Unwind_Exception::exception_class should be different from
// the one used by C++).
fprintf(stderr,
"\nrunExceptionThrow(...):In C++ catch all.\n");
}
@ -1640,17 +1697,31 @@ static void createStandardUtilityFunctions(unsigned numTypeInfos,
// Setup exception catch state
ourExceptionNotThrownState =
llvm::ConstantInt::get(llvm::Type::getInt8Ty(context), 0),
llvm::ConstantInt::get(llvm::Type::getInt8Ty(context), 0),
ourExceptionThrownState =
llvm::ConstantInt::get(llvm::Type::getInt8Ty(context), 1),
llvm::ConstantInt::get(llvm::Type::getInt8Ty(context), 1),
ourExceptionCaughtState =
llvm::ConstantInt::get(llvm::Type::getInt8Ty(context), 2),
llvm::ConstantInt::get(llvm::Type::getInt8Ty(context), 2),
// Create our type info type
ourTypeInfoType = llvm::StructType::get(context,
TypeArray(builder.getInt32Ty()));
TypeArray(builder.getInt32Ty()));
#ifndef OLD_EXC_SYSTEM
llvm::Type *caughtResultFieldTypes[] = {
builder.getInt8PtrTy(),
builder.getInt32Ty()
};
// Create our landingpad result type
ourCaughtResultType = llvm::StructType::get(context,
TypeArray(caughtResultFieldTypes));
#endif
// Create OurException type
ourExceptionType = llvm::StructType::get(context,
TypeArray(ourTypeInfoType));
@ -1667,7 +1738,7 @@ static void createStandardUtilityFunctions(unsigned numTypeInfos,
// Calculate offset of OurException::unwindException member.
ourBaseFromUnwindOffset = ((uintptr_t) &dummyException) -
((uintptr_t) &(dummyException.unwindException));
((uintptr_t) &(dummyException.unwindException));
#ifdef DEBUG
fprintf(stderr,
@ -1724,7 +1795,7 @@ static void createStandardUtilityFunctions(unsigned numTypeInfos,
// print32Int
const llvm::Type *retType = builder.getVoidTy();
llvm::Type *retType = builder.getVoidTy();
argTypes.clear();
argTypes.push_back(builder.getInt32Ty());

View File

@ -33,7 +33,7 @@
#include "llvm/ExecutionEngine/Interpreter.h"
#include "llvm/ExecutionEngine/GenericValue.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetSelect.h"
#include "llvm/Support/TargetSelect.h"
using namespace llvm;
static Function *CreateFibFunction(Module *M, LLVMContext &Context) {

View File

@ -42,7 +42,7 @@
#include "llvm/ExecutionEngine/JIT.h"
#include "llvm/ExecutionEngine/Interpreter.h"
#include "llvm/ExecutionEngine/GenericValue.h"
#include "llvm/Target/TargetSelect.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/IRBuilder.h"

View File

@ -7,9 +7,9 @@
#include "llvm/Analysis/Verifier.h"
#include "llvm/Analysis/Passes.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetSelect.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Support/IRBuilder.h"
#include "llvm/Support/TargetSelect.h"
#include <cstdio>
#include <string>
#include <map>

View File

@ -7,9 +7,9 @@
#include "llvm/Analysis/Verifier.h"
#include "llvm/Analysis/Passes.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetSelect.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Support/IRBuilder.h"
#include "llvm/Support/TargetSelect.h"
#include <cstdio>
#include <string>
#include <map>

View File

@ -7,9 +7,9 @@
#include "llvm/Analysis/Verifier.h"
#include "llvm/Analysis/Passes.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetSelect.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Support/IRBuilder.h"
#include "llvm/Support/TargetSelect.h"
#include <cstdio>
#include <string>
#include <map>

View File

@ -7,9 +7,9 @@
#include "llvm/Analysis/Verifier.h"
#include "llvm/Analysis/Passes.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetSelect.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Support/IRBuilder.h"
#include "llvm/Support/TargetSelect.h"
#include <cstdio>
#include <string>
#include <map>

View File

@ -26,7 +26,7 @@
#include "llvm/ExecutionEngine/JIT.h"
#include "llvm/ExecutionEngine/Interpreter.h"
#include "llvm/ExecutionEngine/GenericValue.h"
#include "llvm/Target/TargetSelect.h"
#include "llvm/Support/TargetSelect.h"
#include <iostream>
using namespace llvm;

View File

@ -115,7 +115,10 @@ typedef enum {
LLVMNoImplicitFloatAttribute = 1<<23,
LLVMNakedAttribute = 1<<24,
LLVMInlineHintAttribute = 1<<25,
LLVMStackAlignment = 7<<26
LLVMStackAlignment = 7<<26,
LLVMReturnsTwice = 1 << 29,
LLVMUWTable = 1 << 30,
LLVMNonLazyBind = 1 << 31
} LLVMAttribute;
typedef enum {
@ -125,7 +128,7 @@ typedef enum {
LLVMSwitch = 3,
LLVMIndirectBr = 4,
LLVMInvoke = 5,
LLVMUnwind = 6,
/* removed 6 due to API changes */
LLVMUnreachable = 7,
/* Standard Binary Operators */
@ -176,14 +179,26 @@ typedef enum {
LLVMPHI = 44,
LLVMCall = 45,
LLVMSelect = 46,
/* UserOp1 */
/* UserOp2 */
LLVMUserOp1 = 47,
LLVMUserOp2 = 48,
LLVMVAArg = 49,
LLVMExtractElement = 50,
LLVMInsertElement = 51,
LLVMShuffleVector = 52,
LLVMExtractValue = 53,
LLVMInsertValue = 54
LLVMInsertValue = 54,
/* Atomic operators */
LLVMFence = 55,
LLVMAtomicCmpXchg = 56,
LLVMAtomicRMW = 57,
/* Exception Handling Operators */
LLVMResume = 58,
LLVMLandingPad = 59,
LLVMUnwind = 60
} LLVMOpcode;
typedef enum {
@ -274,6 +289,11 @@ typedef enum {
LLVMRealPredicateTrue /**< Always true (always folded) */
} LLVMRealPredicate;
typedef enum {
LLVMLandingPadCatch, /**< A catch clause */
LLVMLandingPadFilter /**< A filter clause */
} LLVMLandingPadClauseTy;
void LLVMInitializeCore(LLVMPassRegistryRef R);
@ -340,6 +360,7 @@ LLVMContextRef LLVMGetModuleContext(LLVMModuleRef M);
/** See llvm::LLVMTypeKind::getTypeID. */
LLVMTypeKind LLVMGetTypeKind(LLVMTypeRef Ty);
LLVMBool LLVMTypeIsSized(LLVMTypeRef Ty);
/** See llvm::LLVMType::getContext. */
LLVMContextRef LLVMGetTypeContext(LLVMTypeRef Ty);
@ -388,6 +409,7 @@ LLVMTypeRef LLVMStructTypeInContext(LLVMContextRef C, LLVMTypeRef *ElementTypes,
LLVMTypeRef LLVMStructType(LLVMTypeRef *ElementTypes, unsigned ElementCount,
LLVMBool Packed);
LLVMTypeRef LLVMStructCreateNamed(LLVMContextRef C, const char *Name);
const char *LLVMGetStructName(LLVMTypeRef Ty);
void LLVMStructSetBody(LLVMTypeRef StructTy, LLVMTypeRef *ElementTypes,
unsigned ElementCount, LLVMBool Packed);
@ -427,8 +449,11 @@ LLVMTypeRef LLVMX86MMXType(void);
macro(Argument) \
macro(BasicBlock) \
macro(InlineAsm) \
macro(MDNode) \
macro(MDString) \
macro(User) \
macro(Constant) \
macro(BlockAddress) \
macro(ConstantAggregateZero) \
macro(ConstantArray) \
macro(ConstantExpr) \
@ -448,29 +473,32 @@ LLVMTypeRef LLVMX86MMXType(void);
macro(IntrinsicInst) \
macro(DbgInfoIntrinsic) \
macro(DbgDeclareInst) \
macro(EHExceptionInst) \
macro(EHSelectorInst) \
macro(MemIntrinsic) \
macro(MemCpyInst) \
macro(MemMoveInst) \
macro(MemSetInst) \
macro(CmpInst) \
macro(FCmpInst) \
macro(ICmpInst) \
macro(FCmpInst) \
macro(ICmpInst) \
macro(ExtractElementInst) \
macro(GetElementPtrInst) \
macro(InsertElementInst) \
macro(InsertValueInst) \
macro(LandingPadInst) \
macro(PHINode) \
macro(SelectInst) \
macro(ShuffleVectorInst) \
macro(StoreInst) \
macro(TerminatorInst) \
macro(BranchInst) \
macro(IndirectBrInst) \
macro(InvokeInst) \
macro(ReturnInst) \
macro(SwitchInst) \
macro(UnreachableInst) \
macro(UnwindInst) \
macro(ResumeInst) \
macro(UnaryInstruction) \
macro(AllocaInst) \
macro(CastInst) \
@ -533,6 +561,11 @@ LLVMValueRef LLVMMDString(const char *Str, unsigned SLen);
LLVMValueRef LLVMMDNodeInContext(LLVMContextRef C, LLVMValueRef *Vals,
unsigned Count);
LLVMValueRef LLVMMDNode(LLVMValueRef *Vals, unsigned Count);
const char *LLVMGetMDString(LLVMValueRef V, unsigned* Len);
int LLVMGetMDNodeNumOperands(LLVMValueRef V);
LLVMValueRef *LLVMGetMDNodeOperand(LLVMValueRef V, unsigned i);
unsigned LLVMGetNamedMetadataNumOperands(LLVMModuleRef M, const char* name);
void LLVMGetNamedMetadataOperands(LLVMModuleRef M, const char* name, LLVMValueRef *Dest);
/* Operations on scalar constants */
LLVMValueRef LLVMConstInt(LLVMTypeRef IntTy, unsigned long long N,
@ -728,6 +761,7 @@ LLVMValueRef LLVMBasicBlockAsValue(LLVMBasicBlockRef BB);
LLVMBool LLVMValueIsBasicBlock(LLVMValueRef Val);
LLVMBasicBlockRef LLVMValueAsBasicBlock(LLVMValueRef Val);
LLVMValueRef LLVMGetBasicBlockParent(LLVMBasicBlockRef BB);
LLVMValueRef LLVMGetBasicBlockTerminator(LLVMBasicBlockRef BB);
unsigned LLVMCountBasicBlocks(LLVMValueRef Fn);
void LLVMGetBasicBlocks(LLVMValueRef Fn, LLVMBasicBlockRef *BasicBlocks);
LLVMBasicBlockRef LLVMGetFirstBasicBlock(LLVMValueRef Fn);
@ -747,16 +781,21 @@ LLVMBasicBlockRef LLVMAppendBasicBlock(LLVMValueRef Fn, const char *Name);
LLVMBasicBlockRef LLVMInsertBasicBlock(LLVMBasicBlockRef InsertBeforeBB,
const char *Name);
void LLVMDeleteBasicBlock(LLVMBasicBlockRef BB);
void LLVMRemoveBasicBlockFromParent(LLVMBasicBlockRef BB);
void LLVMMoveBasicBlockBefore(LLVMBasicBlockRef BB, LLVMBasicBlockRef MovePos);
void LLVMMoveBasicBlockAfter(LLVMBasicBlockRef BB, LLVMBasicBlockRef MovePos);
/* Operations on instructions */
LLVMBasicBlockRef LLVMGetInstructionParent(LLVMValueRef Inst);
LLVMValueRef LLVMGetFirstInstruction(LLVMBasicBlockRef BB);
LLVMValueRef LLVMGetLastInstruction(LLVMBasicBlockRef BB);
/* Operations on instructions */
LLVMBasicBlockRef LLVMGetInstructionParent(LLVMValueRef Inst);
LLVMValueRef LLVMGetNextInstruction(LLVMValueRef Inst);
LLVMValueRef LLVMGetPreviousInstruction(LLVMValueRef Inst);
void LLVMInstructionEraseFromParent(LLVMValueRef Inst);
LLVMOpcode LLVMGetInstructionOpcode(LLVMValueRef Inst);
LLVMIntPredicate LLVMGetICmpPredicate(LLVMValueRef Inst);
/* Operations on call sites */
void LLVMSetInstructionCallConv(LLVMValueRef Instr, unsigned CC);
@ -771,6 +810,9 @@ void LLVMSetInstrParamAlignment(LLVMValueRef Instr, unsigned index,
LLVMBool LLVMIsTailCall(LLVMValueRef CallInst);
void LLVMSetTailCall(LLVMValueRef CallInst, LLVMBool IsTailCall);
/* Operations on switch instructions (only) */
LLVMBasicBlockRef LLVMGetSwitchDefaultDest(LLVMValueRef SwitchInstr);
/* Operations on phi nodes */
void LLVMAddIncoming(LLVMValueRef PhiNode, LLVMValueRef *IncomingValues,
LLVMBasicBlockRef *IncomingBlocks, unsigned Count);
@ -818,7 +860,10 @@ LLVMValueRef LLVMBuildInvoke(LLVMBuilderRef, LLVMValueRef Fn,
LLVMValueRef *Args, unsigned NumArgs,
LLVMBasicBlockRef Then, LLVMBasicBlockRef Catch,
const char *Name);
LLVMValueRef LLVMBuildUnwind(LLVMBuilderRef);
LLVMValueRef LLVMBuildLandingPad(LLVMBuilderRef B, LLVMTypeRef Ty,
LLVMValueRef PersFn, unsigned NumClauses,
const char *Name);
LLVMValueRef LLVMBuildResume(LLVMBuilderRef B, LLVMValueRef Exn);
LLVMValueRef LLVMBuildUnreachable(LLVMBuilderRef);
/* Add a case to the switch instruction */
@ -828,6 +873,12 @@ void LLVMAddCase(LLVMValueRef Switch, LLVMValueRef OnVal,
/* Add a destination to the indirectbr instruction */
void LLVMAddDestination(LLVMValueRef IndirectBr, LLVMBasicBlockRef Dest);
/* Add a catch or filter clause to the landingpad instruction */
void LLVMAddClause(LLVMValueRef LandingPad, LLVMValueRef ClauseVal);
/* Set the 'cleanup' flag in the landingpad instruction */
void LLVMSetCleanup(LLVMValueRef LandingPad, LLVMBool Val);
/* Arithmetic */
LLVMValueRef LLVMBuildAdd(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
const char *Name);
@ -1136,7 +1187,7 @@ namespace llvm {
return reinterpret_cast<Type**>(Tys);
}
inline LLVMTypeRef *wrap(const Type **Tys) {
inline LLVMTypeRef *wrap(Type **Tys) {
return reinterpret_cast<LLVMTypeRef*>(const_cast<Type**>(Tys));
}

View File

@ -66,7 +66,7 @@ typedef int (*LLVMOpInfoCallback)(void *DisInfo, uint64_t PC,
*/
struct LLVMOpInfoSymbol1 {
uint64_t Present; /* 1 if this symbol is present */
char *Name; /* symbol name if not NULL */
const char *Name; /* symbol name if not NULL */
uint64_t Value; /* symbol value if name is NULL */
};
@ -93,11 +93,35 @@ struct LLVMOpInfo1 {
* disassembler for things like adding a comment for a PC plus a constant
* offset load instruction to use a symbol name instead of a load address value.
* It is passed the block information is saved when the disassembler context is
* created and a value of a symbol to look up. If no symbol is found NULL is
* returned.
* created and the ReferenceValue to look up as a symbol. If no symbol is found
* for the ReferenceValue NULL is returned. The ReferenceType of the
* instruction is passed indirectly as is the PC of the instruction in
* ReferencePC. If the output reference can be determined its type is returned
* indirectly in ReferenceType along with ReferenceName if any, or that is set
* to NULL.
*/
typedef const char *(*LLVMSymbolLookupCallback)(void *DisInfo,
uint64_t SymbolValue);
uint64_t ReferenceValue,
uint64_t *ReferenceType,
uint64_t ReferencePC,
const char **ReferenceName);
/**
* The reference types on input and output.
*/
/* No input reference type or no output reference type. */
#define LLVMDisassembler_ReferenceType_InOut_None 0
/* The input reference is from a branch instruction. */
#define LLVMDisassembler_ReferenceType_In_Branch 1
/* The input reference is from a PC relative load instruction. */
#define LLVMDisassembler_ReferenceType_In_PCrel_Load 2
/* The output reference is to as symbol stub. */
#define LLVMDisassembler_ReferenceType_Out_SymbolStub 1
/* The output reference is to a symbol address in a literal pool. */
#define LLVMDisassembler_ReferenceType_Out_LitPool_SymAddr 2
/* The output reference is to a cstring address in a literal pool. */
#define LLVMDisassembler_ReferenceType_Out_LitPool_CstrAddr 3
#ifdef __cplusplus
extern "C" {

View File

@ -59,14 +59,14 @@ namespace llvm {
return reinterpret_cast<LLVMObjectFileRef>(const_cast<ObjectFile*>(OF));
}
inline ObjectFile::section_iterator *unwrap(LLVMSectionIteratorRef SI) {
return reinterpret_cast<ObjectFile::section_iterator*>(SI);
inline section_iterator *unwrap(LLVMSectionIteratorRef SI) {
return reinterpret_cast<section_iterator*>(SI);
}
inline LLVMSectionIteratorRef
wrap(const ObjectFile::section_iterator *SI) {
wrap(const section_iterator *SI) {
return reinterpret_cast<LLVMSectionIteratorRef>
(const_cast<ObjectFile::section_iterator*>(SI));
(const_cast<section_iterator*>(SI));
}
}
}

View File

@ -29,6 +29,7 @@ extern "C" {
enum LLVMByteOrdering { LLVMBigEndian, LLVMLittleEndian };
typedef struct LLVMOpaqueTargetData *LLVMTargetDataRef;
typedef struct LLVMOpaqueTargetLibraryInfotData *LLVMTargetLibraryInfoRef;
typedef struct LLVMStructLayout *LLVMStructLayoutRef;
/* Declare all of the target-initialization functions that are available. */
@ -42,7 +43,7 @@ typedef struct LLVMStructLayout *LLVMStructLayoutRef;
#undef LLVM_TARGET /* Explicit undef to make SWIG happier */
#define LLVM_TARGET(TargetName) \
void LLVMInitialize##TargetName##MCAsmInfo(void);
void LLVMInitialize##TargetName##TargetMC(void);
#include "llvm/Config/Targets.def"
#undef LLVM_TARGET /* Explicit undef to make SWIG happier */
@ -72,7 +73,7 @@ static inline LLVMBool LLVMInitializeNativeTarget(void) {
#ifdef LLVM_NATIVE_TARGET
LLVM_NATIVE_TARGETINFO();
LLVM_NATIVE_TARGET();
LLVM_NATIVE_MCASMINFO();
LLVM_NATIVE_TARGETMC();
return 0;
#else
return 1;
@ -90,6 +91,11 @@ LLVMTargetDataRef LLVMCreateTargetData(const char *StringRep);
See the method llvm::PassManagerBase::add. */
void LLVMAddTargetData(LLVMTargetDataRef, LLVMPassManagerRef);
/** Adds target library information to a pass manager. This does not take
ownership of the target library info.
See the method llvm::PassManagerBase::add. */
void LLVMAddTargetLibraryInfo(LLVMTargetLibraryInfoRef, LLVMPassManagerRef);
/** Converts target data to a target layout string. The string must be disposed
with LLVMDisposeMessage.
See the constructor llvm::TargetData::TargetData. */
@ -157,6 +163,7 @@ void LLVMDisposeTargetData(LLVMTargetDataRef);
namespace llvm {
class TargetData;
class TargetLibraryInfo;
inline TargetData *unwrap(LLVMTargetDataRef P) {
return reinterpret_cast<TargetData*>(P);
@ -165,6 +172,15 @@ namespace llvm {
inline LLVMTargetDataRef wrap(const TargetData *P) {
return reinterpret_cast<LLVMTargetDataRef>(const_cast<TargetData*>(P));
}
inline TargetLibraryInfo *unwrap(LLVMTargetLibraryInfoRef P) {
return reinterpret_cast<TargetLibraryInfo*>(P);
}
inline LLVMTargetLibraryInfoRef wrap(const TargetLibraryInfo *P) {
TargetLibraryInfo *X = const_cast<TargetLibraryInfo*>(P);
return reinterpret_cast<LLVMTargetLibraryInfoRef>(X);
}
}
#endif /* defined(__cplusplus) */

View File

@ -36,6 +36,9 @@ void LLVMAddFunctionAttrsPass(LLVMPassManagerRef PM);
/** See llvm::createFunctionInliningPass function. */
void LLVMAddFunctionInliningPass(LLVMPassManagerRef PM);
/** See llvm::createAlwaysInlinerPass function. */
void LLVMAddAlwaysInlinerPass(LLVMPassManagerRef PM);
/** See llvm::createGlobalDCEPass function. */
void LLVMAddGlobalDCEPass(LLVMPassManagerRef PM);
@ -45,9 +48,6 @@ void LLVMAddGlobalOptimizerPass(LLVMPassManagerRef PM);
/** See llvm::createIPConstantPropagationPass function. */
void LLVMAddIPConstantPropagationPass(LLVMPassManagerRef PM);
/** See llvm::createLowerSetJmpPass function. */
void LLVMAddLowerSetJmpPass(LLVMPassManagerRef PM);
/** See llvm::createPruneEHPass function. */
void LLVMAddPruneEHPass(LLVMPassManagerRef PM);
@ -57,9 +57,6 @@ void LLVMAddIPSCCPPass(LLVMPassManagerRef PM);
/** See llvm::createInternalizePass function. */
void LLVMAddInternalizePass(LLVMPassManagerRef, unsigned AllButMain);
// FIXME: Remove in LLVM 3.0.
void LLVMAddRaiseAllocationsPass(LLVMPassManagerRef PM);
/** See llvm::createStripDeadPrototypesPass function. */
void LLVMAddStripDeadPrototypesPass(LLVMPassManagerRef PM);

View File

@ -0,0 +1,90 @@
/*===-- llvm-c/Transform/PassManagerBuilder.h - PMB C Interface ---*- C -*-===*\
|* *|
|* The LLVM Compiler Infrastructure *|
|* *|
|* This file is distributed under the University of Illinois Open Source *|
|* License. See LICENSE.TXT for details. *|
|* *|
|*===----------------------------------------------------------------------===*|
|* *|
|* This header declares the C interface to the PassManagerBuilder class. *|
|* *|
\*===----------------------------------------------------------------------===*/
#ifndef LLVM_C_PASSMANAGERBUILDER
#define LLVM_C_PASSMANAGERBUILDER
#include "llvm-c/Core.h"
typedef struct LLVMOpaquePassManagerBuilder *LLVMPassManagerBuilderRef;
#ifdef __cplusplus
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
extern "C" {
#endif
/** See llvm::PassManagerBuilder. */
LLVMPassManagerBuilderRef LLVMPassManagerBuilderCreate(void);
void LLVMPassManagerBuilderDispose(LLVMPassManagerBuilderRef PMB);
/** See llvm::PassManagerBuilder::OptLevel. */
void
LLVMPassManagerBuilderSetOptLevel(LLVMPassManagerBuilderRef PMB,
unsigned OptLevel);
/** See llvm::PassManagerBuilder::SizeLevel. */
void
LLVMPassManagerBuilderSetSizeLevel(LLVMPassManagerBuilderRef PMB,
unsigned SizeLevel);
/** See llvm::PassManagerBuilder::DisableUnitAtATime. */
void
LLVMPassManagerBuilderSetDisableUnitAtATime(LLVMPassManagerBuilderRef PMB,
LLVMBool Value);
/** See llvm::PassManagerBuilder::DisableUnrollLoops. */
void
LLVMPassManagerBuilderSetDisableUnrollLoops(LLVMPassManagerBuilderRef PMB,
LLVMBool Value);
/** See llvm::PassManagerBuilder::DisableSimplifyLibCalls */
void
LLVMPassManagerBuilderSetDisableSimplifyLibCalls(LLVMPassManagerBuilderRef PMB,
LLVMBool Value);
/** See llvm::PassManagerBuilder::Inliner. */
void
LLVMPassManagerBuilderUseInlinerWithThreshold(LLVMPassManagerBuilderRef PMB,
unsigned Threshold);
/** See llvm::PassManagerBuilder::populateFunctionPassManager. */
void
LLVMPassManagerBuilderPopulateFunctionPassManager(LLVMPassManagerBuilderRef PMB,
LLVMPassManagerRef PM);
/** See llvm::PassManagerBuilder::populateModulePassManager. */
void
LLVMPassManagerBuilderPopulateModulePassManager(LLVMPassManagerBuilderRef PMB,
LLVMPassManagerRef PM);
/** See llvm::PassManagerBuilder::populateLTOPassManager. */
void LLVMPassManagerBuilderPopulateLTOPassManager(LLVMPassManagerBuilderRef PMB,
LLVMPassManagerRef PM,
bool Internalize,
bool RunInliner);
#ifdef __cplusplus
}
namespace llvm {
inline PassManagerBuilder *unwrap(LLVMPassManagerBuilderRef P) {
return reinterpret_cast<PassManagerBuilder*>(P);
}
inline LLVMPassManagerBuilderRef wrap(PassManagerBuilder *P) {
return reinterpret_cast<LLVMPassManagerBuilderRef>(P);
}
}
#endif
#endif

View File

@ -107,6 +107,9 @@ void LLVMAddCorrelatedValuePropagationPass(LLVMPassManagerRef PM);
/** See llvm::createEarlyCSEPass function */
void LLVMAddEarlyCSEPass(LLVMPassManagerRef PM);
/** See llvm::createLowerExpectIntrinsicPass function */
void LLVMAddLowerExpectIntrinsicPass(LLVMPassManagerRef PM);
/** See llvm::createTypeBasedAliasAnalysisPass function */
void LLVMAddTypeBasedAliasAnalysisPass(LLVMPassManagerRef PM);

View File

@ -15,6 +15,7 @@
#ifndef LLVM_APINT_H
#define LLVM_APINT_H
#include "llvm/ADT/ArrayRef.h"
#include "llvm/Support/MathExtras.h"
#include <cassert>
#include <climits>
@ -160,7 +161,7 @@ class APInt {
/// not assume that the string is well-formed and (2) grows the
/// result to hold the input.
///
/// @param radix 2, 8, 10, or 16
/// @param radix 2, 8, 10, 16, or 36
/// @brief Convert a char array into an APInt
void fromString(unsigned numBits, StringRef str, uint8_t radix);
@ -176,6 +177,9 @@ class APInt {
/// out-of-line slow case for inline constructor
void initSlowCase(unsigned numBits, uint64_t val, bool isSigned);
/// shared code between two array constructors
void initFromArray(ArrayRef<uint64_t> array);
/// out-of-line slow case for inline copy constructor
void initSlowCase(const APInt& that);
@ -230,19 +234,26 @@ class APInt {
clearUnusedBits();
}
/// Note that numWords can be smaller or larger than the corresponding bit
/// width but any extraneous bits will be dropped.
/// Note that bigVal.size() can be smaller or larger than the corresponding
/// bit width but any extraneous bits will be dropped.
/// @param numBits the bit width of the constructed APInt
/// @param numWords the number of words in bigVal
/// @param bigVal a sequence of words to form the initial value of the APInt
/// @brief Construct an APInt of numBits width, initialized as bigVal[].
APInt(unsigned numBits, ArrayRef<uint64_t> bigVal);
/// Equivalent to APInt(numBits, ArrayRef<uint64_t>(bigVal, numWords)), but
/// deprecated because this constructor is prone to ambiguity with the
/// APInt(unsigned, uint64_t, bool) constructor.
///
/// If this overload is ever deleted, care should be taken to prevent calls
/// from being incorrectly captured by the APInt(unsigned, uint64_t, bool)
/// constructor.
APInt(unsigned numBits, unsigned numWords, const uint64_t bigVal[]);
/// This constructor interprets the string \arg str in the given radix. The
/// interpretation stops when the first character that is not suitable for the
/// radix is encountered, or the end of the string. Acceptable radix values
/// are 2, 8, 10 and 16. It is an error for the value implied by the string to
/// require more bits than numBits.
/// are 2, 8, 10, 16, and 36. It is an error for the value implied by the
/// string to require more bits than numBits.
///
/// @param numBits the bit width of the constructed APInt
/// @param str the string to be interpreted
@ -342,7 +353,8 @@ class APInt {
if (isSingleWord())
return isUIntN(N, VAL);
return APInt(N, getNumWords(), pVal).zext(getBitWidth()) == (*this);
return APInt(N, makeArrayRef(pVal, getNumWords())).zext(getBitWidth())
== (*this);
}
/// @brief Check if this APInt has an N-bits signed integer value.
@ -1245,13 +1257,13 @@ class APInt {
bool formatAsCLiteral = false) const;
/// Considers the APInt to be unsigned and converts it into a string in the
/// radix given. The radix can be 2, 8, 10 or 16.
/// radix given. The radix can be 2, 8, 10 16, or 36.
void toStringUnsigned(SmallVectorImpl<char> &Str, unsigned Radix = 10) const {
toString(Str, Radix, false, false);
}
/// Considers the APInt to be signed and converts it into a string in the
/// radix given. The radix can be 2, 8, 10 or 16.
/// radix given. The radix can be 2, 8, 10, 16, or 36.
void toStringSigned(SmallVectorImpl<char> &Str, unsigned Radix = 10) const {
toString(Str, Radix, true, false);
}

View File

@ -147,7 +147,53 @@ namespace llvm {
/// @}
};
/// @name ArrayRef Convenience constructors
/// @{
/// Construct an ArrayRef from a single element.
template<typename T>
ArrayRef<T> makeArrayRef(const T &OneElt) {
return OneElt;
}
/// Construct an ArrayRef from a pointer and length.
template<typename T>
ArrayRef<T> makeArrayRef(const T *data, size_t length) {
return ArrayRef<T>(data, length);
}
/// Construct an ArrayRef from a range.
template<typename T>
ArrayRef<T> makeArrayRef(const T *begin, const T *end) {
return ArrayRef<T>(begin, end);
}
/// Construct an ArrayRef from a SmallVector.
template <typename T>
ArrayRef<T> makeArrayRef(const SmallVectorImpl<T> &Vec) {
return Vec;
}
/// Construct an ArrayRef from a SmallVector.
template <typename T, unsigned N>
ArrayRef<T> makeArrayRef(const SmallVector<T, N> &Vec) {
return Vec;
}
/// Construct an ArrayRef from a std::vector.
template<typename T>
ArrayRef<T> makeArrayRef(const std::vector<T> &Vec) {
return Vec;
}
/// Construct an ArrayRef from a C array.
template<typename T, size_t N>
ArrayRef<T> makeArrayRef(const T (&Arr)[N]) {
return ArrayRef<T>(Arr);
}
/// @}
/// @name ArrayRef Comparison Operators
/// @{

View File

@ -540,6 +540,12 @@ class DenseMapIterator {
++Ptr;
}
};
template<typename KeyT, typename ValueT, typename KeyInfoT, typename ValueInfoT>
static inline size_t
capacity_in_bytes(const DenseMap<KeyT, ValueT, KeyInfoT, ValueInfoT> &X) {
return X.getMemorySize();
}
} // end namespace llvm

View File

@ -51,7 +51,7 @@ struct DenseMapInfo<T*> {
template<> struct DenseMapInfo<char> {
static inline char getEmptyKey() { return ~0; }
static inline char getTombstoneKey() { return ~0 - 1; }
static unsigned getHashValue(const char& Val) { return Val * 37; }
static unsigned getHashValue(const char& Val) { return Val * 37U; }
static bool isEqual(const char &LHS, const char &RHS) {
return LHS == RHS;
}
@ -61,7 +61,7 @@ template<> struct DenseMapInfo<char> {
template<> struct DenseMapInfo<unsigned> {
static inline unsigned getEmptyKey() { return ~0; }
static inline unsigned getTombstoneKey() { return ~0U - 1; }
static unsigned getHashValue(const unsigned& Val) { return Val * 37; }
static unsigned getHashValue(const unsigned& Val) { return Val * 37U; }
static bool isEqual(const unsigned& LHS, const unsigned& RHS) {
return LHS == RHS;
}
@ -96,7 +96,7 @@ template<> struct DenseMapInfo<unsigned long long> {
template<> struct DenseMapInfo<int> {
static inline int getEmptyKey() { return 0x7fffffff; }
static inline int getTombstoneKey() { return -0x7fffffff - 1; }
static unsigned getHashValue(const int& Val) { return (unsigned)(Val * 37); }
static unsigned getHashValue(const int& Val) { return (unsigned)(Val * 37U); }
static bool isEqual(const int& LHS, const int& RHS) {
return LHS == RHS;
}
@ -109,7 +109,7 @@ template<> struct DenseMapInfo<long> {
}
static inline long getTombstoneKey() { return getEmptyKey() - 1L; }
static unsigned getHashValue(const long& Val) {
return (unsigned)(Val * 37L);
return (unsigned)(Val * 37UL);
}
static bool isEqual(const long& LHS, const long& RHS) {
return LHS == RHS;
@ -121,7 +121,7 @@ template<> struct DenseMapInfo<long long> {
static inline long long getEmptyKey() { return 0x7fffffffffffffffLL; }
static inline long long getTombstoneKey() { return -0x7fffffffffffffffLL-1; }
static unsigned getHashValue(const long long& Val) {
return (unsigned)(Val * 37LL);
return (unsigned)(Val * 37ULL);
}
static bool isEqual(const long long& LHS,
const long long& RHS) {
@ -142,7 +142,7 @@ struct DenseMapInfo<std::pair<T, U> > {
}
static inline Pair getTombstoneKey() {
return std::make_pair(FirstInfo::getTombstoneKey(),
SecondInfo::getEmptyKey());
SecondInfo::getTombstoneKey());
}
static unsigned getHashValue(const Pair& PairVal) {
uint64_t key = (uint64_t)FirstInfo::getHashValue(PairVal.first) << 32
@ -158,7 +158,7 @@ struct DenseMapInfo<std::pair<T, U> > {
return (unsigned)key;
}
static bool isEqual(const Pair &LHS, const Pair &RHS) {
return FirstInfo::isEqual(LHS.first, RHS.first) &&
return FirstInfo::isEqual(LHS.first, RHS.first) &&
SecondInfo::isEqual(LHS.second, RHS.second);
}
};

View File

@ -28,7 +28,7 @@ class DenseSet {
MapTy TheMap;
public:
DenseSet(const DenseSet &Other) : TheMap(Other.TheMap) {}
explicit DenseSet(unsigned NumInitBuckets = 64) : TheMap(NumInitBuckets) {}
explicit DenseSet(unsigned NumInitBuckets = 0) : TheMap(NumInitBuckets) {}
bool empty() const { return TheMap.empty(); }
unsigned size() const { return TheMap.size(); }

Some files were not shown because too many files have changed in this diff Show More