Update LLVM to 97654.
This commit is contained in:
parent
6fe5c7aa32
commit
67a71b3184
@ -335,3 +335,8 @@ D: Bunches of stuff
|
||||
N: Bob Wilson
|
||||
E: bob.wilson@acm.org
|
||||
D: Advanced SIMD (NEON) support in the ARM backend
|
||||
|
||||
N: Wesley Peck
|
||||
E: peckw@wesleypeck.com
|
||||
W: http://wesleypeck.com/
|
||||
D: MicroBlaze backend
|
||||
|
13
Makefile
13
Makefile
@ -30,8 +30,8 @@ ifeq ($(BUILD_DIRS_ONLY),1)
|
||||
DIRS := lib/System lib/Support utils
|
||||
OPTIONAL_DIRS :=
|
||||
else
|
||||
DIRS := lib/System lib/Support utils lib/VMCore lib tools/llvm-config \
|
||||
tools runtime docs unittests
|
||||
DIRS := lib/System lib/Support utils lib/VMCore lib tools/llvm-shlib \
|
||||
tools/llvm-config tools runtime docs unittests
|
||||
OPTIONAL_DIRS := projects bindings
|
||||
endif
|
||||
|
||||
@ -43,12 +43,9 @@ EXTRA_DIST := test unittests llvm.spec include win32 Xcode
|
||||
|
||||
include $(LEVEL)/Makefile.config
|
||||
|
||||
# llvm-gcc4 doesn't need runtime libs. llvm-gcc4 is the only supported one.
|
||||
# FIXME: Remove runtime entirely once we have an understanding of where
|
||||
# libprofile etc should go.
|
||||
#ifeq ($(LLVMGCC_MAJVERS),4)
|
||||
# DIRS := $(filter-out runtime, $(DIRS))
|
||||
#endif
|
||||
ifneq ($(ENABLE_SHARED),1)
|
||||
DIRS := $(filter-out tools/llvm-shlib, $(DIRS))
|
||||
endif
|
||||
|
||||
ifeq ($(MAKECMDGOALS),libs-only)
|
||||
DIRS := $(filter-out tools runtime docs, $(DIRS))
|
||||
|
@ -183,25 +183,21 @@ TARGETS_TO_BUILD=@TARGETS_TO_BUILD@
|
||||
# want to override the value set by configure.
|
||||
LLVMGCCDIR := @LLVMGCCDIR@
|
||||
|
||||
# Determine the target for which LLVM should generate code.
|
||||
ifeq (@LLVMGCC_MAJVERS@,3)
|
||||
LLVMGCCARCH := @target@/3.4-llvm
|
||||
else
|
||||
LLVMGCCARCH := @target@/@LLVMGCC_VERSION@
|
||||
endif
|
||||
|
||||
# Determine the path where the library executables are
|
||||
LLVMGCCLIBEXEC := @LLVMGCCLIBEXEC@
|
||||
|
||||
# Full pathnames of LLVM C/C++ front-end 'cc1' and 'cc1plus' binaries:
|
||||
LLVMGCC := @LLVMGCC@
|
||||
LLVMGXX := @LLVMGXX@
|
||||
LLVMCC1 := @LLVMCC1@
|
||||
LLVMCC1PLUS := @LLVMCC1PLUS@
|
||||
LLVMGCC_VERSION := @LLVMGCC_VERSION@
|
||||
LLVMGCC_MAJVERS := @LLVMGCC_MAJVERS@
|
||||
LLVMGCC_LANGS := @LLVMGCC_LANGS@
|
||||
|
||||
# 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@
|
||||
|
||||
# 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.
|
||||
@ -266,6 +262,9 @@ ENABLE_THREADS := @ENABLE_THREADS@
|
||||
# Do we want to build with position independent code?
|
||||
ENABLE_PIC := @ENABLE_PIC@
|
||||
|
||||
# Do we want to build a shared library and link the tools with it?
|
||||
ENABLE_SHARED := @ENABLE_SHARED@
|
||||
|
||||
# Use -fvisibility-inlines-hidden?
|
||||
ENABLE_VISIBILITY_INLINES_HIDDEN := @ENABLE_VISIBILITY_INLINES_HIDDEN@
|
||||
|
||||
@ -276,6 +275,9 @@ ENABLE_VISIBILITY_INLINES_HIDDEN := @ENABLE_VISIBILITY_INLINES_HIDDEN@
|
||||
# Enable JIT for this platform
|
||||
TARGET_HAS_JIT = @TARGET_HAS_JIT@
|
||||
|
||||
# Environment variable to set to change the runtime shared library search path.
|
||||
SHLIBPATH_VAR = @SHLIBPATH_VAR@
|
||||
|
||||
# Shared library extension for host platform.
|
||||
SHLIBEXT = @SHLIBEXT@
|
||||
|
||||
|
@ -493,7 +493,27 @@ ExmplDir := $(PROJ_OBJ_ROOT)/$(BuildMode)/examples
|
||||
LLVMLibDir := $(LLVM_OBJ_ROOT)/$(BuildMode)/lib
|
||||
LLVMToolDir := $(LLVM_OBJ_ROOT)/$(BuildMode)/bin
|
||||
LLVMExmplDir:= $(LLVM_OBJ_ROOT)/$(BuildMode)/examples
|
||||
CFERuntimeLibDir := $(LLVMGCCDIR)/lib
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
# LLVM Capable Compiler
|
||||
#--------------------------------------------------------------------
|
||||
|
||||
ifeq ($(LLVMCC_OPTION),llvm-gcc)
|
||||
LLVMCC := $(LLVMGCC)
|
||||
LLVMCXX := $(LLVMGXX)
|
||||
else
|
||||
ifeq ($(LLVMCC_OPTION),clang)
|
||||
ifneq ($(CLANGPATH),)
|
||||
LLVMCC := $(CLANGPATH)
|
||||
LLVMCXX := $(CLANGXXPATH)
|
||||
else
|
||||
ifeq ($(ENABLE_BUILT_CLANG),1)
|
||||
LLVMCC := $(LLVMToolDir)/clang
|
||||
LLVMCXX := $(LLVMToolDir)/clang++
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
# Full Paths To Compiled Tools and Utilities
|
||||
@ -529,16 +549,6 @@ endif
|
||||
ifndef LBUGPOINT
|
||||
LBUGPOINT := $(LLVMToolDir)/bugpoint$(EXEEXT)
|
||||
endif
|
||||
ifndef LUPGRADE
|
||||
LUPGRADE := $(LLVMToolDir)/llvm-upgrade$(EXEEXT)
|
||||
endif
|
||||
ifeq ($(LLVMGCC_MAJVERS),3)
|
||||
LLVMGCCWITHPATH := PATH="$(LLVMToolDir):$(PATH)" $(LLVMGCC)
|
||||
LLVMGXXWITHPATH := PATH="$(LLVMToolDir):$(PATH)" $(LLVMGXX)
|
||||
else
|
||||
LLVMGCCWITHPATH := $(LLVMGCC)
|
||||
LLVMGXXWITHPATH := $(LLVMGXX)
|
||||
endif
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
# Adjust to user's request
|
||||
@ -613,11 +623,12 @@ endif
|
||||
ifneq ($(HOST_OS),Darwin)
|
||||
ifneq ($(DARWIN_MAJVERS),4)
|
||||
ifdef TOOLNAME
|
||||
ifdef EXAMPLE_TOOL
|
||||
LD.Flags += $(RPATH) -Wl,$(ExmplDir) $(RDYNAMIC)
|
||||
else
|
||||
LD.Flags += $(RPATH) -Wl,$(ToolDir) $(RDYNAMIC)
|
||||
endif
|
||||
LD.Flags += $(RPATH) -Wl,'$$ORIGIN/../lib'
|
||||
ifdef EXAMPLE_TOOL
|
||||
LD.Flags += $(RPATH) -Wl,$(ExmplDir) $(RDYNAMIC)
|
||||
else
|
||||
LD.Flags += $(RPATH) -Wl,$(ToolDir) $(RDYNAMIC)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
@ -710,14 +721,12 @@ else
|
||||
$(TargetCommonOpts) $(CompileCommonOpts) $(LD.Flags) $(Strip)
|
||||
endif
|
||||
|
||||
BCCompile.C = $(LLVMGCCWITHPATH) $(CPP.Flags) $(C.Flags) $(CFLAGS) \
|
||||
$(CPPFLAGS) \
|
||||
BCCompile.C = $(LLVMCC) $(CPP.Flags) $(C.Flags) $(CFLAGS) $(CPPFLAGS) \
|
||||
$(TargetCommonOpts) $(CompileCommonOpts)
|
||||
Preprocess.C = $(CC) $(CPP.Flags) $(C.Flags) $(CPPFLAGS) \
|
||||
$(TargetCommonOpts) $(CompileCommonOpts) -E
|
||||
|
||||
BCCompile.CXX = $(LLVMGXXWITHPATH) $(CPP.Flags) $(CXX.Flags) $(CXXFLAGS) \
|
||||
$(CPPFLAGS) \
|
||||
BCCompile.CXX = $(LLVMCXX) $(CPP.Flags) $(CXX.Flags) $(CXXFLAGS) $(CPPFLAGS) \
|
||||
$(TargetCommonOpts) $(CompileCommonOpts)
|
||||
|
||||
ProgInstall = $(INSTALL) $(Install.StripFlag) -m 0755
|
||||
@ -952,11 +961,16 @@ $(LLVM_CONFIG):
|
||||
|
||||
$(ToolDir)/$(strip $(TOOLNAME))$(EXEEXT): $(LLVM_CONFIG)
|
||||
|
||||
ifeq ($(ENABLE_SHARED), 1)
|
||||
LLVMLibsOptions += -lLLVM-$(LLVMVersion)
|
||||
LLVMLibsPaths += $(LibDir)/libLLVM-$(LLVMVersion)$(SHLIBEXT)
|
||||
else
|
||||
LLVMLibsOptions += $(shell $(LLVM_CONFIG) --libs $(LINK_COMPONENTS))
|
||||
LLVMLibsPaths += $(LLVM_CONFIG) \
|
||||
$(shell $(LLVM_CONFIG) --libfiles $(LINK_COMPONENTS))
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
###############################################################################
|
||||
# Library Build Rules: Four ways to build a library
|
||||
@ -971,12 +985,12 @@ endif
|
||||
#---------------------------------------------------------
|
||||
|
||||
ifdef MODULE_NAME
|
||||
ifeq ($(strip $(LLVMGCC)),)
|
||||
$(warning Modules require llvm-gcc but no llvm-gcc is available ****)
|
||||
ifeq ($(strip $(LLVMCC)),)
|
||||
$(warning Modules require LLVM capable compiler but none is available ****)
|
||||
else
|
||||
|
||||
Module := $(LibDir)/$(MODULE_NAME).bc
|
||||
LinkModule := $(LLVMLD) -L$(CFERuntimeLibDir) -r
|
||||
LinkModule := $(LLVMLD) -r
|
||||
|
||||
|
||||
ifdef EXPORTED_SYMBOL_FILE
|
||||
@ -1097,15 +1111,14 @@ endif
|
||||
# targets for building them.
|
||||
#---------------------------------------------------------
|
||||
ifdef BYTECODE_LIBRARY
|
||||
ifeq ($(strip $(LLVMGCC)),)
|
||||
$(warning Bytecode libraries require llvm-gcc which could not be found ****)
|
||||
ifeq ($(strip $(LLVMCC)),)
|
||||
$(warning Bytecode libraries require LLVM capable compiler but none is available ****)
|
||||
else
|
||||
|
||||
all-local:: $(LibName.BCA)
|
||||
|
||||
ifdef EXPORTED_SYMBOL_FILE
|
||||
BCLinkLib = $(LLVMLD) -L$(CFERuntimeLibDir) \
|
||||
-internalize-public-api-file=$(EXPORTED_SYMBOL_FILE)
|
||||
BCLinkLib = $(LLVMLD) -internalize-public-api-file=$(EXPORTED_SYMBOL_FILE)
|
||||
|
||||
$(LibName.BCA): $(ObjectsBC) $(LibDir)/.dir $(LLVMLD) \
|
||||
$(LLVMToolDir)/llvm-ar
|
||||
@ -1162,11 +1175,13 @@ endif
|
||||
# If neither BUILD_ARCHIVE or LOADABLE_MODULE are specified, default to
|
||||
# building an archive.
|
||||
#---------------------------------------------------------
|
||||
ifndef NO_BUILD_ARCHIVE
|
||||
ifndef BUILD_ARCHIVE
|
||||
ifndef LOADABLE_MODULE
|
||||
BUILD_ARCHIVE = 1
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
#---------------------------------------------------------
|
||||
# Archive Library Targets:
|
||||
@ -1382,19 +1397,19 @@ BC_DEPEND_OPTIONS = -MMD -MP -MF "$(ObjDir)/$*.bc.d.tmp" \
|
||||
BC_DEPEND_MOVEFILE = then $(MV) -f "$(ObjDir)/$*.bc.d.tmp" "$(ObjDir)/$*.bc.d"; \
|
||||
else $(RM) "$(ObjDir)/$*.bc.d.tmp"; exit 1; fi
|
||||
|
||||
$(ObjDir)/%.ll: %.cpp $(ObjDir)/.dir $(BUILT_SOURCES) $(LLVMGXX)
|
||||
$(ObjDir)/%.ll: %.cpp $(ObjDir)/.dir $(BUILT_SOURCES) $(LLVMCXX)
|
||||
$(Echo) "Compiling $*.cpp for $(BuildMode) build (bytecode)"
|
||||
$(Verb) if $(BCCompile.CXX) $(BC_DEPEND_OPTIONS) \
|
||||
$< -o $(ObjDir)/$*.ll -S -emit-llvm ; \
|
||||
$(BC_DEPEND_MOVEFILE)
|
||||
|
||||
$(ObjDir)/%.ll: %.cc $(ObjDir)/.dir $(BUILT_SOURCES) $(LLVMGXX)
|
||||
$(ObjDir)/%.ll: %.cc $(ObjDir)/.dir $(BUILT_SOURCES) $(LLVMCXX)
|
||||
$(Echo) "Compiling $*.cc for $(BuildMode) build (bytecode)"
|
||||
$(Verb) if $(BCCompile.CXX) $(BC_DEPEND_OPTIONS) \
|
||||
$< -o $(ObjDir)/$*.ll -S -emit-llvm ; \
|
||||
$(BC_DEPEND_MOVEFILE)
|
||||
|
||||
$(ObjDir)/%.ll: %.c $(ObjDir)/.dir $(BUILT_SOURCES) $(LLVMGCC)
|
||||
$(ObjDir)/%.ll: %.c $(ObjDir)/.dir $(BUILT_SOURCES) $(LLVMCC)
|
||||
$(Echo) "Compiling $*.c for $(BuildMode) build (bytecode)"
|
||||
$(Verb) if $(BCCompile.C) $(BC_DEPEND_OPTIONS) \
|
||||
$< -o $(ObjDir)/$*.ll -S -emit-llvm ; \
|
||||
@ -1415,15 +1430,15 @@ $(ObjDir)/%.o: %.c $(ObjDir)/.dir $(BUILT_SOURCES)
|
||||
$(Echo) "Compiling $*.c for $(BuildMode) build" $(PIC_FLAG)
|
||||
$(Compile.C) $< -o $@
|
||||
|
||||
$(ObjDir)/%.ll: %.cpp $(ObjDir)/.dir $(BUILT_SOURCES) $(LLVMGXX)
|
||||
$(ObjDir)/%.ll: %.cpp $(ObjDir)/.dir $(BUILT_SOURCES) $(LLVMCXX)
|
||||
$(Echo) "Compiling $*.cpp for $(BuildMode) build (bytecode)"
|
||||
$(BCCompile.CXX) $< -o $@ -S -emit-llvm
|
||||
|
||||
$(ObjDir)/%.ll: %.cc $(ObjDir)/.dir $(BUILT_SOURCES) $(LLVMGXX)
|
||||
$(ObjDir)/%.ll: %.cc $(ObjDir)/.dir $(BUILT_SOURCES) $(LLVMCXX)
|
||||
$(Echo) "Compiling $*.cc for $(BuildMode) build (bytecode)"
|
||||
$(BCCompile.CXX) $< -o $@ -S -emit-llvm
|
||||
|
||||
$(ObjDir)/%.ll: %.c $(ObjDir)/.dir $(BUILT_SOURCES) $(LLVMGCC)
|
||||
$(ObjDir)/%.ll: %.c $(ObjDir)/.dir $(BUILT_SOURCES) $(LLVMCC)
|
||||
$(Echo) "Compiling $*.c for $(BuildMode) build (bytecode)"
|
||||
$(BCCompile.C) $< -o $@ -S -emit-llvm
|
||||
|
||||
|
@ -10,3 +10,6 @@ the license agreement found in LICENSE.txt.
|
||||
|
||||
Please see the HTML documentation provided in docs/index.html for further
|
||||
assistance with LLVM.
|
||||
|
||||
If you're writing a package for LLVM, see docs/Packaging.html for our
|
||||
suggestions.
|
||||
|
@ -1,4 +1,7 @@
|
||||
{
|
||||
global: main;
|
||||
__progname;
|
||||
environ;
|
||||
|
||||
local: *;
|
||||
};
|
||||
|
@ -80,6 +80,7 @@ do
|
||||
llvm-tv) AC_CONFIG_SUBDIRS([projects/llvm-tv]) ;;
|
||||
llvm-poolalloc) AC_CONFIG_SUBDIRS([projects/llvm-poolalloc]) ;;
|
||||
poolalloc) AC_CONFIG_SUBDIRS([projects/poolalloc]) ;;
|
||||
safecode) AC_CONFIG_SUBDIRS([projects/safecode]) ;;
|
||||
llvm-kernel) AC_CONFIG_SUBDIRS([projects/llvm-kernel]) ;;
|
||||
*)
|
||||
AC_MSG_WARN([Unknown project (${i}) won't be configured automatically])
|
||||
@ -184,7 +185,7 @@ AC_CACHE_CHECK([type of operating system we're going to host on],
|
||||
llvm_cv_link_all_option="-Wl,--whole-archive"
|
||||
llvm_cv_no_link_all_option="-Wl,--no-whole-archive"
|
||||
llvm_cv_os_type="Haiku"
|
||||
llvm_cv_platform_type="Unix" ;;
|
||||
llvm_cv_platform_type="Unix" ;;
|
||||
*-unknown-eabi*)
|
||||
llvm_cv_link_all_option="-Wl,--whole-archive"
|
||||
llvm_cv_no_link_all_option="-Wl,--no-whole-archive"
|
||||
@ -236,7 +237,7 @@ AC_CACHE_CHECK([type of operating system we're going to target],
|
||||
*-*-mingw*)
|
||||
llvm_cv_target_os_type="MingW" ;;
|
||||
*-*-haiku*)
|
||||
llvm_cv_target_os_type="Haiku" ;;
|
||||
llvm_cv_target_os_type="Haiku" ;;
|
||||
*-unknown-eabi*)
|
||||
llvm_cv_target_os_type="Freestanding" ;;
|
||||
*)
|
||||
@ -291,6 +292,7 @@ AC_CACHE_CHECK([target architecture],[llvm_cv_target_arch],
|
||||
msp430-*) llvm_cv_target_arch="MSP430" ;;
|
||||
s390x-*) llvm_cv_target_arch="SystemZ" ;;
|
||||
bfin-*) llvm_cv_target_arch="Blackfin" ;;
|
||||
mblaze-*) llvm_cv_target_arch="MBlaze" ;;
|
||||
*) llvm_cv_target_arch="Unknown" ;;
|
||||
esac])
|
||||
|
||||
@ -427,6 +429,7 @@ else
|
||||
MSP430) AC_SUBST(TARGET_HAS_JIT,0) ;;
|
||||
SystemZ) AC_SUBST(TARGET_HAS_JIT,0) ;;
|
||||
Blackfin) AC_SUBST(TARGET_HAS_JIT,0) ;;
|
||||
MBlaze) AC_SUBST(TARGET_HAS_JIT,0) ;;
|
||||
*) AC_SUBST(TARGET_HAS_JIT,0) ;;
|
||||
esac
|
||||
fi
|
||||
@ -470,6 +473,18 @@ esac
|
||||
AC_DEFINE_UNQUOTED([ENABLE_PIC],$ENABLE_PIC,
|
||||
[Define if position independent code is enabled])
|
||||
|
||||
dnl Allow building a shared library and linking tools against it.
|
||||
AC_ARG_ENABLE(shared,
|
||||
AS_HELP_STRING([--enable-shared],
|
||||
[Build a shared library and link tools against it (default is NO)]),,
|
||||
enableval=default)
|
||||
case "$enableval" in
|
||||
yes) AC_SUBST(ENABLE_SHARED,[1]) ;;
|
||||
no) AC_SUBST(ENABLE_SHARED,[0]) ;;
|
||||
default) AC_SUBST(ENABLE_SHARED,[0]) ;;
|
||||
*) AC_MSG_ERROR([Invalid setting for --enable-shared. Use "yes" or "no"]) ;;
|
||||
esac
|
||||
|
||||
dnl Allow specific targets to be specified for building (or not)
|
||||
TARGETS_TO_BUILD=""
|
||||
AC_ARG_ENABLE([targets],AS_HELP_STRING([--enable-targets],
|
||||
@ -481,7 +496,7 @@ if test "$enableval" = host-only ; then
|
||||
enableval=host
|
||||
fi
|
||||
case "$enableval" in
|
||||
all) TARGETS_TO_BUILD="X86 Sparc PowerPC Alpha ARM Mips CellSPU PIC16 XCore MSP430 SystemZ Blackfin CBackend MSIL CppBackend" ;;
|
||||
all) TARGETS_TO_BUILD="X86 Sparc PowerPC Alpha ARM Mips CellSPU PIC16 XCore MSP430 SystemZ Blackfin CBackend MSIL CppBackend MBlaze" ;;
|
||||
*)for a_target in `echo $enableval|sed -e 's/,/ /g' ` ; do
|
||||
case "$a_target" in
|
||||
x86) TARGETS_TO_BUILD="X86 $TARGETS_TO_BUILD" ;;
|
||||
@ -500,6 +515,7 @@ case "$enableval" in
|
||||
cbe) TARGETS_TO_BUILD="CBackend $TARGETS_TO_BUILD" ;;
|
||||
msil) TARGETS_TO_BUILD="MSIL $TARGETS_TO_BUILD" ;;
|
||||
cpp) TARGETS_TO_BUILD="CppBackend $TARGETS_TO_BUILD" ;;
|
||||
mblaze) TARGETS_TO_BUILD="MBlaze $TARGETS_TO_BUILD" ;;
|
||||
host) case "$llvm_cv_target_arch" in
|
||||
x86) TARGETS_TO_BUILD="X86 $TARGETS_TO_BUILD" ;;
|
||||
x86_64) TARGETS_TO_BUILD="X86 $TARGETS_TO_BUILD" ;;
|
||||
@ -508,6 +524,7 @@ case "$enableval" in
|
||||
Alpha) TARGETS_TO_BUILD="Alpha $TARGETS_TO_BUILD" ;;
|
||||
ARM) TARGETS_TO_BUILD="ARM $TARGETS_TO_BUILD" ;;
|
||||
Mips) TARGETS_TO_BUILD="Mips $TARGETS_TO_BUILD" ;;
|
||||
MBlaze) TARGETS_TO_BUILD="MBlaze $TARGETS_TO_BUILD" ;;
|
||||
CellSPU|SPU) TARGETS_TO_BUILD="CellSPU $TARGETS_TO_BUILD" ;;
|
||||
PIC16) TARGETS_TO_BUILD="PIC16 $TARGETS_TO_BUILD" ;;
|
||||
XCore) TARGETS_TO_BUILD="XCore $TARGETS_TO_BUILD" ;;
|
||||
@ -612,6 +629,56 @@ 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],
|
||||
@ -946,6 +1013,29 @@ else
|
||||
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])
|
||||
|
||||
@ -994,7 +1084,7 @@ fi
|
||||
dnl Tool compatibility is okay if we make it here.
|
||||
AC_MSG_RESULT([ok])
|
||||
|
||||
dnl Check optional compiler flags.
|
||||
dnl Check optional compiler flags.
|
||||
AC_MSG_CHECKING([optional compiler flags])
|
||||
CXX_FLAG_CHECK(NO_VARIADIC_MACROS, [-Wno-variadic-macros])
|
||||
CXX_FLAG_CHECK(NO_MISSING_FIELD_INITIALIZERS, [-Wno-missing-field-initializers])
|
||||
@ -1250,12 +1340,6 @@ if test "$llvm_cv_llvmgcc_sanity" = "yes" ; then
|
||||
AC_SUBST(LLVMCC1PLUS,$llvmcc1pluspath)
|
||||
llvmgccdir=`echo "$llvmcc1path" | sed 's,/libexec/.*,,'`
|
||||
AC_SUBST(LLVMGCCDIR,$llvmgccdir)
|
||||
llvmgcclibexec=`echo "$llvmcc1path" | sed 's,/cc1,,'`
|
||||
AC_SUBST(LLVMGCCLIBEXEC,$llvmgcclibexec)
|
||||
llvmgccversion=[`"$LLVMGCC" -dumpversion 2>&1 | sed 's/^\([0-9.]*\).*/\1/'`]
|
||||
llvmgccmajvers=[`echo $llvmgccversion | sed 's/^\([0-9]\).*/\1/'`]
|
||||
AC_SUBST(LLVMGCC_VERSION,$llvmgccversion)
|
||||
AC_SUBST(LLVMGCC_MAJVERS,$llvmgccmajvers)
|
||||
llvmgcclangs=[`"$LLVMGCC" -v --help 2>&1 | grep '^Configured with:' | sed 's/^.*--enable-languages=\([^ ]*\).*/\1/'`]
|
||||
AC_SUBST(LLVMGCC_LANGS,$llvmgcclangs)
|
||||
AC_MSG_RESULT([ok])
|
||||
@ -1265,6 +1349,10 @@ 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)
|
||||
|
||||
dnl Propagate the run-time library path variable that the libltdl
|
||||
dnl checks found to the Makefiles so we can use it there too
|
||||
AC_SUBST(SHLIBPATH_VAR,$libltdl_cv_shlibpath_var)
|
||||
|
||||
# Translate the various configuration directories and other basic
|
||||
# information into substitutions that will end up in Makefile.config.in
|
||||
# that these configured values can be used by the makefiles
|
||||
@ -1275,7 +1363,7 @@ eval LLVM_PREFIX="${prefix}";
|
||||
eval LLVM_BINDIR="${prefix}/bin";
|
||||
eval LLVM_LIBDIR="${prefix}/lib";
|
||||
eval LLVM_DATADIR="${prefix}/share/llvm";
|
||||
eval LLVM_DOCSDIR="${prefix}/docs/llvm";
|
||||
eval LLVM_DOCSDIR="${prefix}/share/doc/llvm";
|
||||
eval LLVM_ETCDIR="${prefix}/etc/llvm";
|
||||
eval LLVM_INCLUDEDIR="${prefix}/include";
|
||||
eval LLVM_INFODIR="${prefix}/info";
|
||||
|
2
autoconf/m4/cxx_flag_check.m4
Normal file
2
autoconf/m4/cxx_flag_check.m4
Normal file
@ -0,0 +1,2 @@
|
||||
AC_DEFUN([CXX_FLAG_CHECK],
|
||||
[AC_SUBST($1, `$CXX $2 -fsyntax-only -xc /dev/null 2>/dev/null && echo $2`)])
|
@ -5,6 +5,7 @@
|
||||
AC_DEFUN([AC_HUGE_VAL_CHECK],[
|
||||
AC_CACHE_CHECK([for HUGE_VAL sanity], [ac_cv_huge_val_sanity],[
|
||||
AC_LANG_PUSH([C++])
|
||||
ac_save_CXXFLAGS=$CXXFLAGS
|
||||
CXXFLAGS=-pedantic
|
||||
AC_RUN_IFELSE(
|
||||
AC_LANG_PROGRAM(
|
||||
@ -12,6 +13,7 @@ AC_DEFUN([AC_HUGE_VAL_CHECK],[
|
||||
[double x = HUGE_VAL; return x != x; ]),
|
||||
[ac_cv_huge_val_sanity=yes],[ac_cv_huge_val_sanity=no],
|
||||
[ac_cv_huge_val_sanity=yes])
|
||||
CXXFLAGS=$ac_save_CXXFLAGS
|
||||
AC_LANG_POP([C++])
|
||||
])
|
||||
AC_SUBST(HUGE_VAL_SANITY,$ac_cv_huge_val_sanity)
|
||||
|
@ -46,17 +46,16 @@ static void llvm_raise(value Prototype, char *Message) {
|
||||
/*===-- Modules -----------------------------------------------------------===*/
|
||||
|
||||
/* Llvm.llcontext -> Llvm.llmemorybuffer -> Llvm.llmodule */
|
||||
CAMLprim value llvm_get_module_provider(LLVMContextRef C,
|
||||
LLVMMemoryBufferRef MemBuf) {
|
||||
CAMLprim value llvm_get_module(LLVMContextRef C, LLVMMemoryBufferRef MemBuf) {
|
||||
CAMLparam0();
|
||||
CAMLlocal2(Variant, MessageVal);
|
||||
char *Message;
|
||||
|
||||
LLVMModuleProviderRef MP;
|
||||
if (LLVMGetBitcodeModuleProviderInContext(C, MemBuf, &MP, &Message))
|
||||
LLVMModuleRef M;
|
||||
if (LLVMGetBitcodeModuleInContext(C, MemBuf, &M, &Message))
|
||||
llvm_raise(llvm_bitreader_error_exn, Message);
|
||||
|
||||
CAMLreturn((value) MemBuf);
|
||||
CAMLreturn((value) M);
|
||||
}
|
||||
|
||||
/* Llvm.llcontext -> Llvm.llmemorybuffer -> Llvm.llmodule */
|
||||
|
@ -13,9 +13,8 @@ exception Error of string
|
||||
external register_exns : exn -> unit = "llvm_register_bitreader_exns"
|
||||
let _ = register_exns (Error "")
|
||||
|
||||
external get_module_provider : Llvm.llcontext -> Llvm.llmemorybuffer ->
|
||||
Llvm.llmoduleprovider
|
||||
= "llvm_get_module_provider"
|
||||
external get_module : Llvm.llcontext -> Llvm.llmemorybuffer -> Llvm.llmodule
|
||||
= "llvm_get_module"
|
||||
|
||||
external parse_bitcode : Llvm.llcontext -> Llvm.llmemorybuffer -> Llvm.llmodule
|
||||
= "llvm_parse_bitcode"
|
||||
|
@ -14,14 +14,12 @@
|
||||
|
||||
exception Error of string
|
||||
|
||||
(** [get_module_provider context mb] reads the bitcode for a new
|
||||
module provider [m] from the memory buffer [mb] in the context [context].
|
||||
Returns [m] if successful, or raises [Error msg] otherwise, where [msg] is a
|
||||
description of the error encountered. See the function
|
||||
[llvm::getBitcodeModuleProvider]. *)
|
||||
external get_module_provider : Llvm.llcontext -> Llvm.llmemorybuffer ->
|
||||
Llvm.llmoduleprovider
|
||||
= "llvm_get_module_provider"
|
||||
(** [get_module context mb] reads the bitcode for a new module [m] from the
|
||||
memory buffer [mb] in the context [context]. Returns [m] if successful, or
|
||||
raises [Error msg] otherwise, where [msg] is a description of the error
|
||||
encountered. See the function [llvm::getBitcodeModule]. *)
|
||||
external get_module : Llvm.llcontext -> Llvm.llmemorybuffer -> Llvm.llmodule
|
||||
= "llvm_get_module"
|
||||
|
||||
(** [parse_bitcode context mb] parses the bitcode for a new module [m] from the
|
||||
memory buffer [mb] in the context [context]. Returns [m] if successful, or
|
||||
|
@ -168,41 +168,31 @@ CAMLprim value llvm_genericvalue_as_nativeint(value GenVal) {
|
||||
|
||||
/*--... Operations on execution engines ....................................--*/
|
||||
|
||||
/* llmoduleprovider -> ExecutionEngine.t */
|
||||
CAMLprim LLVMExecutionEngineRef llvm_ee_create(LLVMModuleProviderRef MP) {
|
||||
/* llmodule -> ExecutionEngine.t */
|
||||
CAMLprim LLVMExecutionEngineRef llvm_ee_create(LLVMModuleRef M) {
|
||||
LLVMExecutionEngineRef Interp;
|
||||
char *Error;
|
||||
if (LLVMCreateExecutionEngine(&Interp, MP, &Error))
|
||||
if (LLVMCreateExecutionEngineForModule(&Interp, M, &Error))
|
||||
llvm_raise(llvm_ee_error_exn, Error);
|
||||
return Interp;
|
||||
}
|
||||
|
||||
/* llmoduleprovider -> ExecutionEngine.t */
|
||||
/* llmodule -> ExecutionEngine.t */
|
||||
CAMLprim LLVMExecutionEngineRef
|
||||
llvm_ee_create_interpreter(LLVMModuleProviderRef MP) {
|
||||
llvm_ee_create_interpreter(LLVMModuleRef M) {
|
||||
LLVMExecutionEngineRef Interp;
|
||||
char *Error;
|
||||
if (LLVMCreateInterpreter(&Interp, MP, &Error))
|
||||
if (LLVMCreateInterpreterForModule(&Interp, M, &Error))
|
||||
llvm_raise(llvm_ee_error_exn, Error);
|
||||
return Interp;
|
||||
}
|
||||
|
||||
/* llmoduleprovider -> ExecutionEngine.t */
|
||||
/* llmodule -> int -> ExecutionEngine.t */
|
||||
CAMLprim LLVMExecutionEngineRef
|
||||
llvm_ee_create_jit(LLVMModuleProviderRef MP) {
|
||||
llvm_ee_create_jit(LLVMModuleRef M, value OptLevel) {
|
||||
LLVMExecutionEngineRef JIT;
|
||||
char *Error;
|
||||
if (LLVMCreateJITCompiler(&JIT, MP, 3, &Error))
|
||||
llvm_raise(llvm_ee_error_exn, Error);
|
||||
return JIT;
|
||||
}
|
||||
|
||||
/* llmoduleprovider -> ExecutionEngine.t */
|
||||
CAMLprim LLVMExecutionEngineRef
|
||||
llvm_ee_create_fast_jit(LLVMModuleProviderRef MP) {
|
||||
LLVMExecutionEngineRef JIT;
|
||||
char *Error;
|
||||
if (LLVMCreateJITCompiler(&JIT, MP, 0, &Error))
|
||||
if (LLVMCreateJITCompilerForModule(&JIT, M, Int_val(OptLevel), &Error))
|
||||
llvm_raise(llvm_ee_error_exn, Error);
|
||||
return JIT;
|
||||
}
|
||||
@ -213,19 +203,18 @@ CAMLprim value llvm_ee_dispose(LLVMExecutionEngineRef EE) {
|
||||
return Val_unit;
|
||||
}
|
||||
|
||||
/* llmoduleprovider -> ExecutionEngine.t -> unit */
|
||||
CAMLprim value llvm_ee_add_mp(LLVMModuleProviderRef MP,
|
||||
LLVMExecutionEngineRef EE) {
|
||||
LLVMAddModuleProvider(EE, MP);
|
||||
/* llmodule -> ExecutionEngine.t -> unit */
|
||||
CAMLprim value llvm_ee_add_mp(LLVMModuleRef M, LLVMExecutionEngineRef EE) {
|
||||
LLVMAddModule(EE, M);
|
||||
return Val_unit;
|
||||
}
|
||||
|
||||
/* llmoduleprovider -> ExecutionEngine.t -> llmodule */
|
||||
CAMLprim LLVMModuleRef llvm_ee_remove_mp(LLVMModuleProviderRef MP,
|
||||
/* llmodule -> ExecutionEngine.t -> llmodule */
|
||||
CAMLprim LLVMModuleRef llvm_ee_remove_mp(LLVMModuleRef M,
|
||||
LLVMExecutionEngineRef EE) {
|
||||
LLVMModuleRef RemovedModule;
|
||||
char *Error;
|
||||
if (LLVMRemoveModuleProvider(EE, MP, &RemovedModule, &Error))
|
||||
if (LLVMRemoveModule(EE, M, &RemovedModule, &Error))
|
||||
llvm_raise(llvm_ee_error_exn, Error);
|
||||
return RemovedModule;
|
||||
}
|
||||
@ -237,7 +226,7 @@ CAMLprim value llvm_ee_find_function(value Name, LLVMExecutionEngineRef EE) {
|
||||
LLVMValueRef Found;
|
||||
if (LLVMFindFunction(EE, String_val(Name), &Found))
|
||||
CAMLreturn(Val_unit);
|
||||
Option = alloc(1, 1);
|
||||
Option = alloc(1, 0);
|
||||
Field(Option, 0) = Val_op(Found);
|
||||
CAMLreturn(Option);
|
||||
}
|
||||
|
@ -56,19 +56,17 @@ module ExecutionEngine = struct
|
||||
call into LLVM. *)
|
||||
let _ = register_exns (Error "")
|
||||
|
||||
external create: Llvm.llmoduleprovider -> t
|
||||
external create: Llvm.llmodule -> t
|
||||
= "llvm_ee_create"
|
||||
external create_interpreter: Llvm.llmoduleprovider -> t
|
||||
external create_interpreter: Llvm.llmodule -> t
|
||||
= "llvm_ee_create_interpreter"
|
||||
external create_jit: Llvm.llmoduleprovider -> t
|
||||
external create_jit: Llvm.llmodule -> int -> t
|
||||
= "llvm_ee_create_jit"
|
||||
external create_fast_jit: Llvm.llmoduleprovider -> t
|
||||
= "llvm_ee_create_fast_jit"
|
||||
external dispose: t -> unit
|
||||
= "llvm_ee_dispose"
|
||||
external add_module_provider: Llvm.llmoduleprovider -> t -> unit
|
||||
external add_module: Llvm.llmodule -> t -> unit
|
||||
= "llvm_ee_add_mp"
|
||||
external remove_module_provider: Llvm.llmoduleprovider -> t -> Llvm.llmodule
|
||||
external remove_module: Llvm.llmodule -> t -> Llvm.llmodule
|
||||
= "llvm_ee_remove_mp"
|
||||
external find_function: string -> t -> Llvm.llvalue option
|
||||
= "llvm_ee_find_function"
|
||||
|
@ -85,48 +85,38 @@ module ExecutionEngine: sig
|
||||
invoking a static compiler and generating a native executable. *)
|
||||
type t
|
||||
|
||||
(** [create mp] creates a new execution engine, taking ownership of the
|
||||
module provider [mp] if successful. Creates a JIT if possible, else falls
|
||||
back to an interpreter. Raises [Error msg] if an error occurrs. The
|
||||
(** [create m] creates a new execution engine, taking ownership of the
|
||||
module [m] if successful. Creates a JIT if possible, else falls back to an
|
||||
interpreter. Raises [Error msg] if an error occurrs. The execution engine
|
||||
is not garbage collected and must be destroyed with [dispose ee].
|
||||
See the function [llvm::EngineBuilder::create]. *)
|
||||
val create: Llvm.llmodule -> t
|
||||
|
||||
(** [create_interpreter m] creates a new interpreter, taking ownership of the
|
||||
module [m] if successful. Raises [Error msg] if an error occurrs. The
|
||||
execution engine is not garbage collected and must be destroyed with
|
||||
[dispose ee]. See the function [llvm::EngineBuilder::create]. *)
|
||||
val create: Llvm.llmoduleprovider -> t
|
||||
|
||||
(** [create_interpreter mp] creates a new interpreter, taking ownership of the
|
||||
module provider [mp] if successful. Raises [Error msg] if an error
|
||||
occurrs. The execution engine is not garbage collected and must be
|
||||
destroyed with [dispose ee].
|
||||
[dispose ee].
|
||||
See the function [llvm::EngineBuilder::create]. *)
|
||||
val create_interpreter: Llvm.llmoduleprovider -> t
|
||||
val create_interpreter: Llvm.llmodule -> t
|
||||
|
||||
(** [create_jit mp] creates a new JIT (just-in-time compiler), taking
|
||||
ownership of the module provider [mp] if successful. This function creates
|
||||
a JIT which favors code quality over compilation speed. Raises [Error msg]
|
||||
if an error occurrs. The execution engine is not garbage collected and
|
||||
must be destroyed with [dispose ee].
|
||||
(** [create_jit m optlevel] creates a new JIT (just-in-time compiler), taking
|
||||
ownership of the module [m] if successful with the desired optimization
|
||||
level [optlevel]. Raises [Error msg] if an error occurrs. The execution
|
||||
engine is not garbage collected and must be destroyed with [dispose ee].
|
||||
See the function [llvm::EngineBuilder::create]. *)
|
||||
val create_jit: Llvm.llmoduleprovider -> t
|
||||
|
||||
(** [create_fast_jit mp] creates a new JIT (just-in-time compiler) which
|
||||
favors compilation speed over code quality. It takes ownership of the
|
||||
module provider [mp] if successful. Raises [Error msg] if an error
|
||||
occurrs. The execution engine is not garbage collected and must be
|
||||
destroyed with [dispose ee].
|
||||
See the function [llvm::EngineBuilder::create]. *)
|
||||
val create_fast_jit: Llvm.llmoduleprovider -> t
|
||||
|
||||
val create_jit : Llvm.llmodule -> int -> t
|
||||
|
||||
(** [dispose ee] releases the memory used by the execution engine and must be
|
||||
invoked to avoid memory leaks. *)
|
||||
val dispose: t -> unit
|
||||
|
||||
(** [add_module_provider mp ee] adds the module provider [mp] to the execution
|
||||
engine [ee]. *)
|
||||
val add_module_provider: Llvm.llmoduleprovider -> t -> unit
|
||||
(** [add_module m ee] adds the module [m] to the execution engine [ee]. *)
|
||||
val add_module: Llvm.llmodule -> t -> unit
|
||||
|
||||
(** [remove_module_provider mp ee] removes the module provider [mp] from the
|
||||
execution engine [ee], disposing of [mp] and the module referenced by
|
||||
[mp]. Raises [Error msg] if an error occurs. *)
|
||||
val remove_module_provider: Llvm.llmoduleprovider -> t -> Llvm.llmodule
|
||||
(** [remove_module m ee] removes the module [m] from the execution engine
|
||||
[ee], disposing of [m] and the module referenced by [mp]. Raises
|
||||
[Error msg] if an error occurs. *)
|
||||
val remove_module: Llvm.llmodule -> t -> Llvm.llmodule
|
||||
|
||||
(** [find_function n ee] finds the function named [n] defined in any of the
|
||||
modules owned by the execution engine [ee]. Returns [None] if the function
|
||||
|
@ -13,9 +13,9 @@ type llmodule
|
||||
type lltype
|
||||
type lltypehandle
|
||||
type llvalue
|
||||
type lluse
|
||||
type llbasicblock
|
||||
type llbuilder
|
||||
type llmoduleprovider
|
||||
type llmemorybuffer
|
||||
|
||||
module TypeKind = struct
|
||||
@ -35,6 +35,7 @@ module TypeKind = struct
|
||||
| Opaque
|
||||
| Vector
|
||||
| Metadata
|
||||
| Union
|
||||
end
|
||||
|
||||
module Linkage = struct
|
||||
@ -147,6 +148,7 @@ type ('a, 'b) llrev_pos =
|
||||
external create_context : unit -> llcontext = "llvm_create_context"
|
||||
external dispose_context : llcontext -> unit = "llvm_dispose_context"
|
||||
external global_context : unit -> llcontext = "llvm_global_context"
|
||||
external mdkind_id : llcontext -> string -> int = "llvm_mdkind_id"
|
||||
|
||||
(*===-- Modules -----------------------------------------------------------===*)
|
||||
external create_module : llcontext -> string -> llmodule = "llvm_create_module"
|
||||
@ -163,6 +165,8 @@ external define_type_name : string -> lltype -> llmodule -> bool
|
||||
= "llvm_add_type_name"
|
||||
external delete_type_name : string -> llmodule -> unit
|
||||
= "llvm_delete_type_name"
|
||||
external type_by_name : llmodule -> string -> lltype option
|
||||
= "llvm_type_by_name"
|
||||
external dump_module : llmodule -> unit = "llvm_dump_module"
|
||||
|
||||
(*===-- Types -------------------------------------------------------------===*)
|
||||
@ -198,9 +202,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 element_types : lltype -> lltype array = "llvm_element_types"
|
||||
external struct_element_types : lltype -> lltype array
|
||||
= "llvm_struct_element_types"
|
||||
external is_packed : lltype -> bool = "llvm_is_packed"
|
||||
|
||||
(*--... Operations on union types ..........................................--*)
|
||||
external union_type : llcontext -> lltype array -> lltype = "llvm_union_type"
|
||||
external union_element_types : lltype -> lltype array
|
||||
= "llvm_union_element_types"
|
||||
|
||||
(*--... Operations on pointer, vector, and array types .....................--*)
|
||||
external array_type : lltype -> int -> lltype = "llvm_array_type"
|
||||
external pointer_type : lltype -> lltype = "llvm_pointer_type"
|
||||
@ -229,15 +239,63 @@ external type_of : llvalue -> lltype = "llvm_type_of"
|
||||
external value_name : llvalue -> string = "llvm_value_name"
|
||||
external set_value_name : string -> llvalue -> unit = "llvm_set_value_name"
|
||||
external dump_value : llvalue -> unit = "llvm_dump_value"
|
||||
external replace_all_uses_with : llvalue -> llvalue -> unit
|
||||
= "LLVMReplaceAllUsesWith"
|
||||
|
||||
(*--... Operations on uses .................................................--*)
|
||||
external use_begin : llvalue -> lluse option = "llvm_use_begin"
|
||||
external use_succ : lluse -> lluse option = "llvm_use_succ"
|
||||
external user : lluse -> llvalue = "llvm_user"
|
||||
external used_value : lluse -> llvalue = "llvm_used_value"
|
||||
|
||||
let iter_uses f v =
|
||||
let rec aux = function
|
||||
| None -> ()
|
||||
| Some u ->
|
||||
f u;
|
||||
aux (use_succ u)
|
||||
in
|
||||
aux (use_begin v)
|
||||
|
||||
let fold_left_uses f init v =
|
||||
let rec aux init u =
|
||||
match u with
|
||||
| None -> init
|
||||
| Some u -> aux (f init u) (use_succ u)
|
||||
in
|
||||
aux init (use_begin v)
|
||||
|
||||
let fold_right_uses f v init =
|
||||
let rec aux u init =
|
||||
match u with
|
||||
| None -> init
|
||||
| Some u -> f u (aux (use_succ u) init)
|
||||
in
|
||||
aux (use_begin v) init
|
||||
|
||||
|
||||
(*--... Operations on users ................................................--*)
|
||||
external operand : llvalue -> int -> llvalue = "llvm_operand"
|
||||
|
||||
(*--... Operations on constants of (mostly) any type .......................--*)
|
||||
external is_constant : llvalue -> bool = "llvm_is_constant"
|
||||
external const_null : lltype -> llvalue = "LLVMConstNull"
|
||||
external const_all_ones : (*int|vec*)lltype -> llvalue = "LLVMConstAllOnes"
|
||||
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"
|
||||
|
||||
(*--... Operations on instructions .........................................--*)
|
||||
external has_metadata : llvalue -> bool = "llvm_has_metadata"
|
||||
external metadata : llvalue -> int -> llvalue option = "llvm_metadata"
|
||||
external set_metadata : llvalue -> int -> llvalue -> unit = "llvm_set_metadata"
|
||||
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"
|
||||
|
||||
(*--... Operations on scalar constants .....................................--*)
|
||||
external const_int : lltype -> int -> llvalue = "llvm_const_int"
|
||||
external const_of_int64 : lltype -> Int64.t -> bool -> llvalue
|
||||
@ -257,19 +315,27 @@ external const_struct : llcontext -> llvalue array -> llvalue
|
||||
external const_packed_struct : llcontext -> llvalue array -> llvalue
|
||||
= "llvm_const_packed_struct"
|
||||
external const_vector : llvalue array -> llvalue = "llvm_const_vector"
|
||||
external const_union : lltype -> llvalue -> llvalue = "LLVMConstUnion"
|
||||
|
||||
(*--... Constant expressions ...............................................--*)
|
||||
external align_of : lltype -> llvalue = "LLVMAlignOf"
|
||||
external size_of : lltype -> llvalue = "LLVMSizeOf"
|
||||
external const_neg : llvalue -> llvalue = "LLVMConstNeg"
|
||||
external const_nsw_neg : llvalue -> llvalue = "LLVMConstNSWNeg"
|
||||
external const_nuw_neg : llvalue -> llvalue = "LLVMConstNUWNeg"
|
||||
external const_fneg : llvalue -> llvalue = "LLVMConstFNeg"
|
||||
external const_not : llvalue -> llvalue = "LLVMConstNot"
|
||||
external const_add : llvalue -> llvalue -> llvalue = "LLVMConstAdd"
|
||||
external const_nsw_add : llvalue -> llvalue -> llvalue = "LLVMConstNSWAdd"
|
||||
external const_nuw_add : llvalue -> llvalue -> llvalue = "LLVMConstNUWAdd"
|
||||
external const_fadd : llvalue -> llvalue -> llvalue = "LLVMConstFAdd"
|
||||
external const_sub : llvalue -> llvalue -> llvalue = "LLVMConstSub"
|
||||
external const_nsw_sub : llvalue -> llvalue -> llvalue = "LLVMConstNSWSub"
|
||||
external const_nuw_sub : llvalue -> llvalue -> llvalue = "LLVMConstNUWSub"
|
||||
external const_fsub : llvalue -> llvalue -> llvalue = "LLVMConstFSub"
|
||||
external const_mul : llvalue -> llvalue -> llvalue = "LLVMConstMul"
|
||||
external const_nsw_mul : llvalue -> llvalue -> llvalue = "LLVMConstNSWMul"
|
||||
external const_nuw_mul : llvalue -> llvalue -> llvalue = "LLVMConstNUWMul"
|
||||
external const_fmul : llvalue -> llvalue -> llvalue = "LLVMConstFMul"
|
||||
external const_udiv : llvalue -> llvalue -> llvalue = "LLVMConstUDiv"
|
||||
external const_sdiv : llvalue -> llvalue -> llvalue = "LLVMConstSDiv"
|
||||
@ -325,6 +391,10 @@ external const_extractvalue : llvalue -> int array -> llvalue
|
||||
= "llvm_const_extractvalue"
|
||||
external const_insertvalue : llvalue -> llvalue -> int array -> llvalue
|
||||
= "llvm_const_insertvalue"
|
||||
external const_inline_asm : lltype -> string -> string -> bool -> bool ->
|
||||
llvalue
|
||||
= "llvm_const_inline_asm"
|
||||
external block_address : llvalue -> llbasicblock -> llvalue = "LLVMBlockAddress"
|
||||
|
||||
(*--... Operations on global variables, functions, and aliases (globals) ...--*)
|
||||
external global_parent : llvalue -> llmodule = "LLVMGetGlobalParent"
|
||||
@ -344,8 +414,14 @@ external set_global_constant : bool -> llvalue -> unit
|
||||
(*--... Operations on global variables .....................................--*)
|
||||
external declare_global : lltype -> string -> llmodule -> llvalue
|
||||
= "llvm_declare_global"
|
||||
external declare_qualified_global : lltype -> string -> int -> llmodule ->
|
||||
llvalue
|
||||
= "llvm_declare_qualified_global"
|
||||
external define_global : string -> llvalue -> llmodule -> llvalue
|
||||
= "llvm_define_global"
|
||||
external define_qualified_global : string -> llvalue -> int -> llmodule ->
|
||||
llvalue
|
||||
= "llvm_define_qualified_global"
|
||||
external lookup_global : string -> llmodule -> llvalue option
|
||||
= "llvm_lookup_global"
|
||||
external delete_global : llvalue -> unit = "llvm_delete_global"
|
||||
@ -403,6 +479,10 @@ let rec fold_right_global_range f i e init =
|
||||
let fold_right_globals f m init =
|
||||
fold_right_global_range f (global_end m) (At_start m) init
|
||||
|
||||
(*--... Operations on aliases ..............................................--*)
|
||||
external add_alias : llmodule -> lltype -> llvalue -> string -> llvalue
|
||||
= "llvm_add_alias"
|
||||
|
||||
(*--... Operations on functions ............................................--*)
|
||||
external declare_function : string -> lltype -> llmodule -> llvalue
|
||||
= "llvm_declare_function"
|
||||
@ -680,6 +760,17 @@ let position_before i = position_builder (Before i)
|
||||
let position_at_end bb = position_builder (At_end bb)
|
||||
|
||||
|
||||
(*--... Metadata ...........................................................--*)
|
||||
external set_current_debug_location : llbuilder -> llvalue -> unit
|
||||
= "llvm_set_current_debug_location"
|
||||
external clear_current_debug_location : llbuilder -> unit
|
||||
= "llvm_clear_current_debug_location"
|
||||
external current_debug_location : llbuilder -> llvalue option
|
||||
= "llvm_current_debug_location"
|
||||
external set_inst_debug_location : llbuilder -> llvalue -> unit
|
||||
= "llvm_set_inst_debug_location"
|
||||
|
||||
|
||||
(*--... Terminators ........................................................--*)
|
||||
external build_ret_void : llbuilder -> llvalue = "llvm_build_ret_void"
|
||||
external build_ret : llvalue -> llbuilder -> llvalue = "llvm_build_ret"
|
||||
@ -692,6 +783,10 @@ external build_switch : llvalue -> llbasicblock -> int -> llbuilder -> llvalue
|
||||
= "llvm_build_switch"
|
||||
external add_case : llvalue -> llvalue -> llbasicblock -> unit
|
||||
= "llvm_add_case"
|
||||
external build_indirect_br : llvalue -> int -> llbuilder -> llvalue
|
||||
= "llvm_build_indirect_br"
|
||||
external add_destination : llvalue -> llbasicblock -> unit
|
||||
= "llvm_add_destination"
|
||||
external build_invoke : llvalue -> llvalue array -> llbasicblock ->
|
||||
llbasicblock -> string -> llbuilder -> llvalue
|
||||
= "llvm_build_invoke_bc" "llvm_build_invoke_nat"
|
||||
@ -703,14 +798,24 @@ external build_add : llvalue -> llvalue -> string -> llbuilder -> llvalue
|
||||
= "llvm_build_add"
|
||||
external build_nsw_add : llvalue -> llvalue -> string -> llbuilder -> llvalue
|
||||
= "llvm_build_nsw_add"
|
||||
external build_nuw_add : llvalue -> llvalue -> string -> llbuilder -> llvalue
|
||||
= "llvm_build_nuw_add"
|
||||
external build_fadd : llvalue -> llvalue -> string -> llbuilder -> llvalue
|
||||
= "llvm_build_fadd"
|
||||
external build_sub : llvalue -> llvalue -> string -> llbuilder -> llvalue
|
||||
= "llvm_build_sub"
|
||||
external build_nsw_sub : llvalue -> llvalue -> string -> llbuilder -> llvalue
|
||||
= "llvm_build_nsw_sub"
|
||||
external build_nuw_sub : llvalue -> llvalue -> string -> llbuilder -> llvalue
|
||||
= "llvm_build_nuw_sub"
|
||||
external build_fsub : llvalue -> llvalue -> string -> llbuilder -> llvalue
|
||||
= "llvm_build_fsub"
|
||||
external build_mul : llvalue -> llvalue -> string -> llbuilder -> llvalue
|
||||
= "llvm_build_mul"
|
||||
external build_nsw_mul : llvalue -> llvalue -> string -> llbuilder -> llvalue
|
||||
= "llvm_build_nsw_mul"
|
||||
external build_nuw_mul : llvalue -> llvalue -> string -> llbuilder -> llvalue
|
||||
= "llvm_build_nuw_mul"
|
||||
external build_fmul : llvalue -> llvalue -> string -> llbuilder -> llvalue
|
||||
= "llvm_build_fmul"
|
||||
external build_udiv : llvalue -> llvalue -> string -> llbuilder -> llvalue
|
||||
@ -741,19 +846,20 @@ external build_xor : llvalue -> llvalue -> string -> llbuilder -> llvalue
|
||||
= "llvm_build_xor"
|
||||
external build_neg : llvalue -> string -> llbuilder -> llvalue
|
||||
= "llvm_build_neg"
|
||||
external build_nsw_neg : llvalue -> string -> llbuilder -> llvalue
|
||||
= "llvm_build_nsw_neg"
|
||||
external build_nuw_neg : llvalue -> string -> llbuilder -> llvalue
|
||||
= "llvm_build_nuw_neg"
|
||||
external build_fneg : llvalue -> string -> llbuilder -> llvalue
|
||||
= "llvm_build_fneg"
|
||||
external build_not : llvalue -> string -> llbuilder -> llvalue
|
||||
= "llvm_build_not"
|
||||
|
||||
(*--... Memory .............................................................--*)
|
||||
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_alloca : lltype -> string -> llbuilder -> llvalue
|
||||
= "llvm_build_alloca"
|
||||
external build_array_alloca : lltype -> llvalue -> string -> llbuilder ->
|
||||
llvalue = "llvm_build_array_alloca"
|
||||
external build_free : llvalue -> llbuilder -> llvalue = "llvm_build_free"
|
||||
external build_load : llvalue -> string -> llbuilder -> llvalue
|
||||
= "llvm_build_load"
|
||||
external build_store : llvalue -> llvalue -> llbuilder -> llvalue
|
||||
@ -841,14 +947,6 @@ external build_is_not_null : llvalue -> string -> llbuilder -> llvalue
|
||||
external build_ptrdiff : llvalue -> llvalue -> string -> llbuilder -> llvalue
|
||||
= "llvm_build_ptrdiff"
|
||||
|
||||
(*===-- Module providers --------------------------------------------------===*)
|
||||
|
||||
module ModuleProvider = struct
|
||||
external create : llmodule -> llmoduleprovider
|
||||
= "LLVMCreateModuleProviderForExistingModule"
|
||||
external dispose : llmoduleprovider -> unit = "llvm_dispose_module_provider"
|
||||
end
|
||||
|
||||
|
||||
(*===-- Memory buffers ----------------------------------------------------===*)
|
||||
|
||||
@ -865,7 +963,7 @@ module PassManager = struct
|
||||
type 'a t
|
||||
type any = [ `Module | `Function ]
|
||||
external create : unit -> [ `Module ] t = "llvm_passmanager_create"
|
||||
external create_function : llmoduleprovider -> [ `Function ] t
|
||||
external create_function : llmodule -> [ `Function ] t
|
||||
= "LLVMCreateFunctionPassManager"
|
||||
external run_module : llmodule -> [ `Module ] t -> bool
|
||||
= "llvm_passmanager_run_module"
|
||||
@ -897,11 +995,14 @@ let rec string_of_lltype ty =
|
||||
| TypeKind.Pointer -> (string_of_lltype (element_type ty)) ^ "*"
|
||||
| TypeKind.Struct ->
|
||||
let s = "{ " ^ (concat2 ", " (
|
||||
Array.map string_of_lltype (element_types ty)
|
||||
Array.map string_of_lltype (struct_element_types ty)
|
||||
)) ^ " }" in
|
||||
if is_packed ty
|
||||
then "<" ^ s ^ ">"
|
||||
else s
|
||||
| TypeKind.Union -> "union { " ^ (concat2 ", " (
|
||||
Array.map string_of_lltype (union_element_types ty)
|
||||
)) ^ " }"
|
||||
| TypeKind.Array -> "[" ^ (string_of_int (array_length ty)) ^
|
||||
" x " ^ (string_of_lltype (element_type ty)) ^ "]"
|
||||
| TypeKind.Vector -> "<" ^ (string_of_int (vector_size ty)) ^
|
||||
|
@ -39,6 +39,9 @@ type lltypehandle
|
||||
This type covers a wide range of subclasses. *)
|
||||
type llvalue
|
||||
|
||||
(** Used to store users and usees of values. See the [llvm::Use] class. *)
|
||||
type lluse
|
||||
|
||||
(** A basic block in LLVM IR. See the [llvm::BasicBlock] class. *)
|
||||
type llbasicblock
|
||||
|
||||
@ -46,10 +49,6 @@ type llbasicblock
|
||||
class. *)
|
||||
type llbuilder
|
||||
|
||||
(** Used to provide a module to JIT or interpreter.
|
||||
See the [llvm::ModuleProvider] class. *)
|
||||
type llmoduleprovider
|
||||
|
||||
(** Used to efficiently handle large buffers of read-only binary data.
|
||||
See the [llvm::MemoryBuffer] class. *)
|
||||
type llmemorybuffer
|
||||
@ -73,6 +72,7 @@ module TypeKind : sig
|
||||
| Opaque
|
||||
| Vector
|
||||
| Metadata
|
||||
| Union
|
||||
end
|
||||
|
||||
(** The linkage of a global value, accessed with {!linkage} and
|
||||
@ -220,6 +220,11 @@ external dispose_context : llcontext -> unit = "llvm_dispose_context"
|
||||
(** See the function [llvm::getGlobalContext]. *)
|
||||
external global_context : unit -> llcontext = "llvm_global_context"
|
||||
|
||||
(** [mdkind_id context name] returns the MDKind ID that corresponds to the
|
||||
name [name] in the context [context]. See the function
|
||||
[llvm::LLVMContext::getMDKindID]. *)
|
||||
external mdkind_id : llcontext -> string -> int = "llvm_mdkind_id"
|
||||
|
||||
|
||||
(** {6 Modules} *)
|
||||
|
||||
@ -268,6 +273,11 @@ external define_type_name : string -> lltype -> llmodule -> bool
|
||||
external delete_type_name : string -> llmodule -> unit
|
||||
= "llvm_delete_type_name"
|
||||
|
||||
(** [type_by_name m n] returns the type in the module [m] named [n], or [None]
|
||||
if it does not exist. See the method [llvm::Module::getTypeByName]. *)
|
||||
external type_by_name : llmodule -> string -> lltype option
|
||||
= "llvm_type_by_name"
|
||||
|
||||
(** [dump_module m] prints the .ll representation of the module [m] to standard
|
||||
error. See the method [llvm::Module::dump]. *)
|
||||
external dump_module : llmodule -> unit = "llvm_dump_module"
|
||||
@ -381,15 +391,29 @@ external struct_type : llcontext -> lltype array -> lltype
|
||||
external packed_struct_type : llcontext -> lltype array -> lltype
|
||||
= "llvm_packed_struct_type"
|
||||
|
||||
(** [element_types sty] returns the constituent types of the struct type [sty].
|
||||
See the method [llvm::StructType::getElementType]. *)
|
||||
external element_types : lltype -> lltype array = "llvm_element_types"
|
||||
(** [struct_element_types sty] returns the constituent types of the struct type
|
||||
[sty]. See the method [llvm::StructType::getElementType]. *)
|
||||
external struct_element_types : lltype -> lltype array
|
||||
= "llvm_struct_element_types"
|
||||
|
||||
(** [is_packed sty] returns [true] if the structure type [sty] is packed,
|
||||
[false] otherwise. See the method [llvm::StructType::isPacked]. *)
|
||||
external is_packed : lltype -> bool = "llvm_is_packed"
|
||||
|
||||
|
||||
(** {7 Operations on union types} *)
|
||||
|
||||
(** [union_type context tys] returns the union type in the context [context]
|
||||
containing the types in the array [tys]. See the method
|
||||
[llvm::UnionType::get] *)
|
||||
external union_type : llcontext -> lltype array -> lltype = "llvm_union_type"
|
||||
|
||||
(** [union_element_types uty] returns the constituent types of the union type
|
||||
[uty]. See the method [llvm::UnionType::getElementType]. *)
|
||||
external union_element_types : lltype -> lltype array
|
||||
= "llvm_union_element_types"
|
||||
|
||||
|
||||
(** {7 Operations on pointer, vector, and array types} *)
|
||||
|
||||
(** [array_type ty n] returns the array type containing [n] elements of type
|
||||
@ -482,6 +506,50 @@ external set_value_name : string -> llvalue -> unit = "llvm_set_value_name"
|
||||
error. See the method [llvm::Value::dump]. *)
|
||||
external dump_value : llvalue -> unit = "llvm_dump_value"
|
||||
|
||||
(** [replace_all_uses_with old new] replaces all uses of the value [old]
|
||||
* with the value [new]. See the method [llvm::Value::replaceAllUsesWith]. *)
|
||||
external replace_all_uses_with : llvalue -> llvalue -> unit
|
||||
= "LLVMReplaceAllUsesWith"
|
||||
|
||||
|
||||
(* {6 Uses} *)
|
||||
|
||||
(** [use_begin v] returns the first position in the use list for the value [v].
|
||||
[use_begin] and [use_succ] can e used to iterate over the use list in order.
|
||||
See the method [llvm::Value::use_begin]. *)
|
||||
external use_begin : llvalue -> lluse option = "llvm_use_begin"
|
||||
|
||||
(** [use_succ u] returns the use list position succeeding [u].
|
||||
See the method [llvm::use_value_iterator::operator++]. *)
|
||||
external use_succ : lluse -> lluse option = "llvm_use_succ"
|
||||
|
||||
(** [user u] returns the user of the use [u].
|
||||
See the method [llvm::Use::getUser]. *)
|
||||
external user : lluse -> llvalue = "llvm_user"
|
||||
|
||||
(** [used_value u] returns the usee of the use [u].
|
||||
See the method [llvm::Use::getUsedValue]. *)
|
||||
external used_value : lluse -> llvalue = "llvm_used_value"
|
||||
|
||||
(** [iter_uses f v] applies function [f] to each of the users of the value [v]
|
||||
in order. Tail recursive. *)
|
||||
val iter_uses : (lluse -> unit) -> llvalue -> unit
|
||||
|
||||
(** [fold_left_uses f init v] is [f (... (f init u1) ...) uN] where
|
||||
[u1,...,uN] are the users of the value [v]. Tail recursive. *)
|
||||
val fold_left_uses : ('a -> lluse -> 'a) -> 'a -> llvalue -> 'a
|
||||
|
||||
(** [fold_right_uses f v init] is [f u1 (... (f uN init) ...)] where
|
||||
[u1,...,uN] are the users of the value [v]. Not tail recursive. *)
|
||||
val fold_right_uses : (lluse -> 'a -> 'a) -> llvalue -> 'a -> 'a
|
||||
|
||||
|
||||
(* {6 Users} *)
|
||||
|
||||
(** [operand v i] returns the operand at index [i] for the value [v]. See the
|
||||
method [llvm::User::getOperand]. *)
|
||||
external operand : llvalue -> int -> llvalue = "llvm_operand"
|
||||
|
||||
|
||||
(** {7 Operations on constants of (mostly) any type} *)
|
||||
|
||||
@ -497,6 +565,10 @@ external const_null : lltype -> llvalue = "LLVMConstNull"
|
||||
[ty]. See the method [llvm::Constant::getAllOnesValue]. *)
|
||||
external const_all_ones : (*int|vec*)lltype -> llvalue = "LLVMConstAllOnes"
|
||||
|
||||
(** [const_pointer_null ty] returns the constant null (zero) pointer of the type
|
||||
[ty]. See the method [llvm::ConstantPointerNull::get]. *)
|
||||
external const_pointer_null : lltype -> llvalue = "LLVMConstPointerNull"
|
||||
|
||||
(** [undef ty] returns the undefined value of the type [ty].
|
||||
See the method [llvm::UndefValue::get]. *)
|
||||
external undef : lltype -> llvalue = "LLVMGetUndef"
|
||||
@ -510,6 +582,39 @@ external is_null : llvalue -> bool = "llvm_is_null"
|
||||
external is_undef : llvalue -> bool = "llvm_is_undef"
|
||||
|
||||
|
||||
(** {7 Operations on instructions} *)
|
||||
|
||||
(** [has_metadata i] returns whether or not the instruction [i] has any
|
||||
metadata attached to it. See the function
|
||||
[llvm::Instruction::hasMetadata]. *)
|
||||
external has_metadata : llvalue -> bool = "llvm_has_metadata"
|
||||
|
||||
(** [metadata i kind] optionally returns the metadata associated with the
|
||||
kind [kind] in the instruction [i] See the function
|
||||
[llvm::Instruction::getMetadata]. *)
|
||||
external metadata : llvalue -> int -> llvalue option = "llvm_metadata"
|
||||
|
||||
(** [set_metadata i kind md] sets the metadata [md] of kind [kind] in the
|
||||
instruction [i]. See the function [llvm::Instruction::setMetadata]. *)
|
||||
external set_metadata : llvalue -> int -> llvalue -> unit = "llvm_set_metadata"
|
||||
|
||||
(** [clear_metadata i kind] clears the metadata of kind [kind] in the
|
||||
instruction [i]. See the function [llvm::Instruction::setMetadata]. *)
|
||||
external clear_metadata : llvalue -> int -> unit = "llvm_clear_metadata"
|
||||
|
||||
|
||||
(** {7 Operations on metadata} *)
|
||||
|
||||
(** [mdstring c s] returns the MDString of the string [s] in the context [c].
|
||||
See the method [llvm::MDNode::get]. *)
|
||||
external mdstring : llcontext -> string -> llvalue = "llvm_mdstring"
|
||||
|
||||
(** [mdnode c elts] returns the MDNode containing the values [elts] in the
|
||||
context [c].
|
||||
See the method [llvm::MDNode::get]. *)
|
||||
external mdnode : llcontext -> llvalue array -> llvalue = "llvm_mdnode"
|
||||
|
||||
|
||||
(** {7 Operations on scalar constants} *)
|
||||
|
||||
(** [const_int ty i] returns the integer constant of type [ty] and value [i].
|
||||
@ -577,6 +682,10 @@ external const_packed_struct : llcontext -> llvalue array -> llvalue
|
||||
values [elts]. See the method [llvm::ConstantVector::get]. *)
|
||||
external const_vector : llvalue array -> llvalue = "llvm_const_vector"
|
||||
|
||||
(** [const_union ty v] returns the union constant of type [union_type tys] and
|
||||
containing the value [v]. See the method [llvm::ConstantUnion::get]. *)
|
||||
external const_union : lltype -> llvalue -> llvalue = "LLVMConstUnion"
|
||||
|
||||
|
||||
(** {7 Constant expressions} *)
|
||||
|
||||
@ -596,6 +705,16 @@ external size_of : lltype -> llvalue = "LLVMSizeOf"
|
||||
See the method [llvm::ConstantExpr::getNeg]. *)
|
||||
external const_neg : llvalue -> llvalue = "LLVMConstNeg"
|
||||
|
||||
(** [const_nsw_neg c] returns the arithmetic negation of the constant [c] with
|
||||
no signed wrapping. The result is undefined if the negation overflows.
|
||||
See the method [llvm::ConstantExpr::getNSWNeg]. *)
|
||||
external const_nsw_neg : llvalue -> llvalue = "LLVMConstNSWNeg"
|
||||
|
||||
(** [const_nuw_neg c] returns the arithmetic negation of the constant [c] with
|
||||
no unsigned wrapping. The result is undefined if the negation overflows.
|
||||
See the method [llvm::ConstantExpr::getNUWNeg]. *)
|
||||
external const_nuw_neg : llvalue -> llvalue = "LLVMConstNUWNeg"
|
||||
|
||||
(** [const_fneg c] returns the arithmetic negation of the constant float [c].
|
||||
See the method [llvm::ConstantExpr::getFNeg]. *)
|
||||
external const_fneg : llvalue -> llvalue = "LLVMConstFNeg"
|
||||
@ -613,6 +732,11 @@ external const_add : llvalue -> llvalue -> llvalue = "LLVMConstAdd"
|
||||
See the method [llvm::ConstantExpr::getNSWAdd]. *)
|
||||
external const_nsw_add : llvalue -> llvalue -> llvalue = "LLVMConstNSWAdd"
|
||||
|
||||
(** [const_nuw_add c1 c2] returns the constant sum of two constants with no
|
||||
unsigned wrapping. The result is undefined if the sum overflows.
|
||||
See the method [llvm::ConstantExpr::getNSWAdd]. *)
|
||||
external const_nuw_add : llvalue -> llvalue -> llvalue = "LLVMConstNUWAdd"
|
||||
|
||||
(** [const_fadd c1 c2] returns the constant sum of two constant floats.
|
||||
See the method [llvm::ConstantExpr::getFAdd]. *)
|
||||
external const_fadd : llvalue -> llvalue -> llvalue = "LLVMConstFAdd"
|
||||
@ -621,6 +745,16 @@ external const_fadd : llvalue -> llvalue -> llvalue = "LLVMConstFAdd"
|
||||
constants. See the method [llvm::ConstantExpr::getSub]. *)
|
||||
external const_sub : llvalue -> llvalue -> llvalue = "LLVMConstSub"
|
||||
|
||||
(** [const_nsw_sub c1 c2] returns the constant difference of two constants with
|
||||
no signed wrapping. The result is undefined if the sum overflows.
|
||||
See the method [llvm::ConstantExpr::getNSWSub]. *)
|
||||
external const_nsw_sub : llvalue -> llvalue -> llvalue = "LLVMConstNSWSub"
|
||||
|
||||
(** [const_nuw_sub c1 c2] returns the constant difference of two constants with
|
||||
no unsigned wrapping. The result is undefined if the sum overflows.
|
||||
See the method [llvm::ConstantExpr::getNSWSub]. *)
|
||||
external const_nuw_sub : llvalue -> llvalue -> llvalue = "LLVMConstNUWSub"
|
||||
|
||||
(** [const_fsub c1 c2] returns the constant difference, [c1 - c2], of two
|
||||
constant floats. See the method [llvm::ConstantExpr::getFSub]. *)
|
||||
external const_fsub : llvalue -> llvalue -> llvalue = "LLVMConstFSub"
|
||||
@ -629,6 +763,16 @@ external const_fsub : llvalue -> llvalue -> llvalue = "LLVMConstFSub"
|
||||
See the method [llvm::ConstantExpr::getMul]. *)
|
||||
external const_mul : llvalue -> llvalue -> llvalue = "LLVMConstMul"
|
||||
|
||||
(** [const_nsw_mul c1 c2] returns the constant product of two constants with
|
||||
no signed wrapping. The result is undefined if the sum overflows.
|
||||
See the method [llvm::ConstantExpr::getNSWMul]. *)
|
||||
external const_nsw_mul : llvalue -> llvalue -> llvalue = "LLVMConstNSWMul"
|
||||
|
||||
(** [const_nuw_mul c1 c2] returns the constant product of two constants with
|
||||
no unsigned wrapping. The result is undefined if the sum overflows.
|
||||
See the method [llvm::ConstantExpr::getNSWMul]. *)
|
||||
external const_nuw_mul : llvalue -> llvalue -> llvalue = "LLVMConstNUWMul"
|
||||
|
||||
(** [const_fmul c1 c2] returns the constant product of two constants floats.
|
||||
See the method [llvm::ConstantExpr::getFMul]. *)
|
||||
external const_fmul : llvalue -> llvalue -> llvalue = "LLVMConstFMul"
|
||||
@ -858,6 +1002,16 @@ external const_extractvalue : llvalue -> int array -> llvalue
|
||||
external const_insertvalue : llvalue -> llvalue -> int array -> llvalue
|
||||
= "llvm_const_insertvalue"
|
||||
|
||||
(** [const_inline_asm ty asm con side align] inserts a inline assembly string.
|
||||
See the method [llvm::InlineAsm::get]. *)
|
||||
external const_inline_asm : lltype -> string -> string -> bool -> bool ->
|
||||
llvalue
|
||||
= "llvm_const_inline_asm"
|
||||
|
||||
(** [block_address f bb] returns the address of the basic block [bb] in the
|
||||
function [f]. See the method [llvm::BasicBlock::get]. *)
|
||||
external block_address : llvalue -> llbasicblock -> llvalue = "LLVMBlockAddress"
|
||||
|
||||
|
||||
(** {7 Operations on global variables, functions, and aliases (globals)} *)
|
||||
|
||||
@ -907,19 +1061,36 @@ external set_alignment : int -> llvalue -> unit = "llvm_set_alignment"
|
||||
(** {7 Operations on global variables} *)
|
||||
|
||||
(** [declare_global ty name m] returns a new global variable of type [ty] and
|
||||
with name [name] in module [m]. If such a global variable already exists,
|
||||
it is returned. If the type of the existing global differs, then a bitcast
|
||||
to [ty] is returned. *)
|
||||
with name [name] in module [m] in the default address space (0). If such a
|
||||
global variable already exists, it is returned. If the type of the existing
|
||||
global differs, then a bitcast to [ty] is returned. *)
|
||||
external declare_global : lltype -> string -> llmodule -> llvalue
|
||||
= "llvm_declare_global"
|
||||
|
||||
(** [declare_qualified_global ty name addrspace m] returns a new global variable
|
||||
of type [ty] and with name [name] in module [m] in the address space
|
||||
[addrspace]. If such a global variable already exists, it is returned. If
|
||||
the type of the existing global differs, then a bitcast to [ty] is
|
||||
returned. *)
|
||||
external declare_qualified_global : lltype -> string -> int -> llmodule ->
|
||||
llvalue
|
||||
= "llvm_declare_qualified_global"
|
||||
|
||||
(** [define_global name init m] returns a new global with name [name] and
|
||||
initializer [init] in module [m]. If the named global already exists, it is
|
||||
renamed.
|
||||
initializer [init] in module [m] in the default address space (0). If the
|
||||
named global already exists, it is renamed.
|
||||
See the constructor of [llvm::GlobalVariable]. *)
|
||||
external define_global : string -> llvalue -> llmodule -> llvalue
|
||||
= "llvm_define_global"
|
||||
|
||||
(** [define_qualified_global name init addrspace m] returns a new global with
|
||||
name [name] and initializer [init] in module [m] in the address space
|
||||
[addrspace]. If the named global already exists, it is renamed.
|
||||
See the constructor of [llvm::GlobalVariable]. *)
|
||||
external define_qualified_global : string -> llvalue -> int -> llmodule ->
|
||||
llvalue
|
||||
= "llvm_define_qualified_global"
|
||||
|
||||
(** [lookup_global name m] returns [Some g] if a global variable with name
|
||||
[name] exists in module [m]. If no such global exists, returns [None].
|
||||
See the [llvm::GlobalVariable] constructor. *)
|
||||
@ -1008,6 +1179,15 @@ external is_thread_local : llvalue -> bool = "llvm_is_thread_local"
|
||||
external set_thread_local : bool -> llvalue -> unit = "llvm_set_thread_local"
|
||||
|
||||
|
||||
(** {7 Operations on aliases} *)
|
||||
|
||||
(** [add_alias m t a n] inserts an alias in the module [m] with the type [t] and
|
||||
the aliasee [a] with the name [n].
|
||||
See the constructor for [llvm::GlobalAlias]. *)
|
||||
external add_alias : llmodule -> lltype -> llvalue -> string -> llvalue
|
||||
= "llvm_add_alias"
|
||||
|
||||
|
||||
(** {7 Operations on functions} *)
|
||||
|
||||
(** [declare_function name ty m] returns a new function of type [ty] and
|
||||
@ -1397,6 +1577,30 @@ external insertion_block : llbuilder -> llbasicblock = "llvm_insertion_block"
|
||||
external insert_into_builder : llvalue -> string -> llbuilder -> unit
|
||||
= "llvm_insert_into_builder"
|
||||
|
||||
(** {7 Metadata} *)
|
||||
|
||||
(** [set_current_debug_location b md] sets the current debug location [md] in
|
||||
the builder [b].
|
||||
See the method [llvm::IRBuilder::SetDebugLocation]. *)
|
||||
external set_current_debug_location : llbuilder -> llvalue -> unit
|
||||
= "llvm_set_current_debug_location"
|
||||
|
||||
(** [clear_current_debug_location b] clears the current debug location in the
|
||||
builder [b]. *)
|
||||
external clear_current_debug_location : llbuilder -> unit
|
||||
= "llvm_clear_current_debug_location"
|
||||
|
||||
(** [current_debug_location b] returns the current debug location, or None
|
||||
if none is currently set.
|
||||
See the method [llvm::IRBuilder::GetDebugLocation]. *)
|
||||
external current_debug_location : llbuilder -> llvalue option
|
||||
= "llvm_current_debug_location"
|
||||
|
||||
(** [set_inst_debug_location b i] sets the current debug location of the builder
|
||||
[b] to the instruction [i].
|
||||
See the method [llvm::IRBuilder::SetInstDebugLocation]. *)
|
||||
external set_inst_debug_location : llbuilder -> llvalue -> unit
|
||||
= "llvm_set_inst_debug_location"
|
||||
|
||||
(** {7 Terminators} *)
|
||||
|
||||
@ -1446,6 +1650,20 @@ external build_switch : llvalue -> llbasicblock -> int -> llbuilder -> llvalue
|
||||
external add_case : llvalue -> llvalue -> llbasicblock -> unit
|
||||
= "llvm_add_case"
|
||||
|
||||
(** [build_indirect_br addr count b] creates a
|
||||
[indirectbr %addr]
|
||||
instruction at the position specified by the instruction builder [b] with
|
||||
space reserved for [count] destinations.
|
||||
See the method [llvm::LLVMBuilder::CreateIndirectBr]. *)
|
||||
external build_indirect_br : llvalue -> int -> llbuilder -> llvalue
|
||||
= "llvm_build_indirect_br"
|
||||
|
||||
(** [add_destination br bb] adds the basic block [bb] as a possible branch
|
||||
location for the indirectbr instruction [br].
|
||||
See the method [llvm::IndirectBrInst::addDestination]. **)
|
||||
external add_destination : llvalue -> llbasicblock -> unit
|
||||
= "llvm_add_destination"
|
||||
|
||||
(** [build_invoke fn args tobb unwindbb name b] creates an
|
||||
[%name = invoke %fn(args) to %tobb unwind %unwindbb]
|
||||
instruction at the position specified by the instruction builder [b].
|
||||
@ -1483,6 +1701,13 @@ external build_add : llvalue -> llvalue -> string -> llbuilder -> llvalue
|
||||
external build_nsw_add : llvalue -> llvalue -> string -> llbuilder -> llvalue
|
||||
= "llvm_build_nsw_add"
|
||||
|
||||
(** [build_nuw_add x y name b] creates a
|
||||
[%name = nuw add %x, %y]
|
||||
instruction at the position specified by the instruction builder [b].
|
||||
See the method [llvm::LLVMBuilder::CreateNUWAdd]. *)
|
||||
external build_nuw_add : llvalue -> llvalue -> string -> llbuilder -> llvalue
|
||||
= "llvm_build_nuw_add"
|
||||
|
||||
(** [build_fadd x y name b] creates a
|
||||
[%name = fadd %x, %y]
|
||||
instruction at the position specified by the instruction builder [b].
|
||||
@ -1497,6 +1722,20 @@ external build_fadd : llvalue -> llvalue -> string -> llbuilder -> llvalue
|
||||
external build_sub : llvalue -> llvalue -> string -> llbuilder -> llvalue
|
||||
= "llvm_build_sub"
|
||||
|
||||
(** [build_nsw_sub x y name b] creates a
|
||||
[%name = nsw sub %x, %y]
|
||||
instruction at the position specified by the instruction builder [b].
|
||||
See the method [llvm::LLVMBuilder::CreateNSWSub]. *)
|
||||
external build_nsw_sub : llvalue -> llvalue -> string -> llbuilder -> llvalue
|
||||
= "llvm_build_nsw_sub"
|
||||
|
||||
(** [build_nuw_sub x y name b] creates a
|
||||
[%name = nuw sub %x, %y]
|
||||
instruction at the position specified by the instruction builder [b].
|
||||
See the method [llvm::LLVMBuilder::CreateNUWSub]. *)
|
||||
external build_nuw_sub : llvalue -> llvalue -> string -> llbuilder -> llvalue
|
||||
= "llvm_build_nuw_sub"
|
||||
|
||||
(** [build_fsub x y name b] creates a
|
||||
[%name = fsub %x, %y]
|
||||
instruction at the position specified by the instruction builder [b].
|
||||
@ -1511,6 +1750,20 @@ external build_fsub : llvalue -> llvalue -> string -> llbuilder -> llvalue
|
||||
external build_mul : llvalue -> llvalue -> string -> llbuilder -> llvalue
|
||||
= "llvm_build_mul"
|
||||
|
||||
(** [build_nsw_mul x y name b] creates a
|
||||
[%name = nsw mul %x, %y]
|
||||
instruction at the position specified by the instruction builder [b].
|
||||
See the method [llvm::LLVMBuilder::CreateNSWMul]. *)
|
||||
external build_nsw_mul : llvalue -> llvalue -> string -> llbuilder -> llvalue
|
||||
= "llvm_build_nsw_mul"
|
||||
|
||||
(** [build_nuw_mul x y name b] creates a
|
||||
[%name = nuw mul %x, %y]
|
||||
instruction at the position specified by the instruction builder [b].
|
||||
See the method [llvm::LLVMBuilder::CreateNUWMul]. *)
|
||||
external build_nuw_mul : llvalue -> llvalue -> string -> llbuilder -> llvalue
|
||||
= "llvm_build_nuw_mul"
|
||||
|
||||
(** [build_fmul x y name b] creates a
|
||||
[%name = fmul %x, %y]
|
||||
instruction at the position specified by the instruction builder [b].
|
||||
@ -1617,6 +1870,30 @@ external build_xor : llvalue -> llvalue -> string -> llbuilder -> llvalue
|
||||
external build_neg : llvalue -> string -> llbuilder -> llvalue
|
||||
= "llvm_build_neg"
|
||||
|
||||
(** [build_nsw_neg x name b] creates a
|
||||
[%name = nsw sub 0, %x]
|
||||
instruction at the position specified by the instruction builder [b].
|
||||
[-0.0] is used for floating point types to compute the correct sign.
|
||||
See the method [llvm::LLVMBuilder::CreateNeg]. *)
|
||||
external build_nsw_neg : llvalue -> string -> llbuilder -> llvalue
|
||||
= "llvm_build_nsw_neg"
|
||||
|
||||
(** [build_nuw_neg x name b] creates a
|
||||
[%name = nuw sub 0, %x]
|
||||
instruction at the position specified by the instruction builder [b].
|
||||
[-0.0] is used for floating point types to compute the correct sign.
|
||||
See the method [llvm::LLVMBuilder::CreateNeg]. *)
|
||||
external build_nuw_neg : llvalue -> string -> llbuilder -> llvalue
|
||||
= "llvm_build_nuw_neg"
|
||||
|
||||
(** [build_fneg x name b] creates a
|
||||
[%name = fsub 0, %x]
|
||||
instruction at the position specified by the instruction builder [b].
|
||||
[-0.0] is used for floating point types to compute the correct sign.
|
||||
See the method [llvm::LLVMBuilder::CreateFNeg]. *)
|
||||
external build_fneg : llvalue -> string -> llbuilder -> llvalue
|
||||
= "llvm_build_fneg"
|
||||
|
||||
(** [build_xor x name b] creates a
|
||||
[%name = xor %x, -1]
|
||||
instruction at the position specified by the instruction builder [b].
|
||||
@ -1628,20 +1905,6 @@ external build_not : llvalue -> string -> llbuilder -> llvalue
|
||||
|
||||
(** {7 Memory} *)
|
||||
|
||||
(** [build_malloc ty name b] creates a
|
||||
[%name = malloc %ty]
|
||||
instruction at the position specified by the instruction builder [b].
|
||||
See the method [llvm::LLVMBuilder::CreateAlloca]. *)
|
||||
external build_malloc : lltype -> string -> llbuilder -> llvalue
|
||||
= "llvm_build_malloc"
|
||||
|
||||
(** [build_array_malloc ty n name b] creates a
|
||||
[%name = malloc %ty, %n]
|
||||
instruction at the position specified by the instruction builder [b].
|
||||
See the method [llvm::LLVMBuilder::CreateMalloc]. *)
|
||||
external build_array_malloc : lltype -> llvalue -> string -> llbuilder ->
|
||||
llvalue = "llvm_build_array_malloc"
|
||||
|
||||
(** [build_alloca ty name b] creates a
|
||||
[%name = alloca %ty]
|
||||
instruction at the position specified by the instruction builder [b].
|
||||
@ -1656,12 +1919,6 @@ external build_alloca : lltype -> string -> llbuilder -> llvalue
|
||||
external build_array_alloca : lltype -> llvalue -> string -> llbuilder ->
|
||||
llvalue = "llvm_build_array_alloca"
|
||||
|
||||
(** [build_free v b] creates a
|
||||
[free %v]
|
||||
instruction at the position specified by the instruction builder [b].
|
||||
See the method [llvm::LLVMBuilder::CreateFree]. *)
|
||||
external build_free : llvalue -> llbuilder -> llvalue = "llvm_build_free"
|
||||
|
||||
(** [build_load v name b] creates a
|
||||
[%name = load %v]
|
||||
instruction at the position specified by the instruction builder [b].
|
||||
@ -1938,20 +2195,6 @@ external build_is_not_null : llvalue -> string -> llbuilder -> llvalue
|
||||
external build_ptrdiff : llvalue -> llvalue -> string -> llbuilder -> llvalue
|
||||
= "llvm_build_ptrdiff"
|
||||
|
||||
(** {6 Module providers} *)
|
||||
|
||||
module ModuleProvider : sig
|
||||
(** [create_module_provider m] encapsulates [m] in a module provider and takes
|
||||
ownership of the module. See the constructor
|
||||
[llvm::ExistingModuleProvider::ExistingModuleProvider]. *)
|
||||
external create : llmodule -> llmoduleprovider
|
||||
= "LLVMCreateModuleProviderForExistingModule"
|
||||
|
||||
(** [dispose_module_provider mp] destroys the module provider [mp] as well as
|
||||
the contained module. *)
|
||||
external dispose : llmoduleprovider -> unit = "llvm_dispose_module_provider"
|
||||
end
|
||||
|
||||
|
||||
(** {6 Memory buffers} *)
|
||||
|
||||
@ -1983,12 +2226,12 @@ module PassManager : sig
|
||||
See the constructor of [llvm::PassManager]. *)
|
||||
external create : unit -> [ `Module ] t = "llvm_passmanager_create"
|
||||
|
||||
(** [PassManager.create_function mp] constructs a new function-by-function
|
||||
pass pipeline over the module provider [mp]. It does not take ownership of
|
||||
[mp]. This type of pipeline is suitable for code generation and JIT
|
||||
compilation tasks.
|
||||
(** [PassManager.create_function m] constructs a new function-by-function
|
||||
pass pipeline over the module [m]. It does not take ownership of [m].
|
||||
This type of pipeline is suitable for code generation and JIT compilation
|
||||
tasks.
|
||||
See the constructor of [llvm::FunctionPassManager]. *)
|
||||
external create_function : llmoduleprovider -> [ `Function ] t
|
||||
external create_function : llmodule -> [ `Function ] t
|
||||
= "LLVMCreateFunctionPassManager"
|
||||
|
||||
(** [run_module m pm] initializes, executes on the module [m], and finalizes
|
||||
@ -2018,7 +2261,7 @@ module PassManager : sig
|
||||
external finalize : [ `Function ] t -> bool = "llvm_passmanager_finalize"
|
||||
|
||||
(** Frees the memory of a pass pipeline. For function pipelines, does not free
|
||||
the module provider.
|
||||
the module.
|
||||
See the destructor of [llvm::BasePassManager]. *)
|
||||
external dispose : [< any ] t -> unit = "llvm_passmanager_dispose"
|
||||
end
|
||||
|
@ -110,6 +110,13 @@ CAMLprim LLVMContextRef llvm_global_context(value Unit) {
|
||||
return LLVMGetGlobalContext();
|
||||
}
|
||||
|
||||
/* llcontext -> string -> int */
|
||||
CAMLprim value llvm_mdkind_id(LLVMContextRef C, value Name) {
|
||||
unsigned MDKindID = LLVMGetMDKindIDInContext(C, String_val(Name),
|
||||
caml_string_length(Name));
|
||||
return Val_int(MDKindID);
|
||||
}
|
||||
|
||||
/*===-- Modules -----------------------------------------------------------===*/
|
||||
|
||||
/* llcontext -> string -> llmodule */
|
||||
@ -157,6 +164,18 @@ CAMLprim value llvm_delete_type_name(value Name, LLVMModuleRef M) {
|
||||
return Val_unit;
|
||||
}
|
||||
|
||||
/* llmodule -> string -> lltype option */
|
||||
CAMLprim value llvm_type_by_name(LLVMModuleRef M, value Name) {
|
||||
CAMLparam1(Name);
|
||||
LLVMTypeRef T;
|
||||
if ((T = LLVMGetTypeByName(M, String_val(Name)))) {
|
||||
value Option = alloc(1, 0);
|
||||
Field(Option, 0) = (value) T;
|
||||
CAMLreturn(Option);
|
||||
}
|
||||
CAMLreturn(Val_int(0));
|
||||
}
|
||||
|
||||
/* llmodule -> unit */
|
||||
CAMLprim value llvm_dump_module(LLVMModuleRef M) {
|
||||
LLVMDumpModule(M);
|
||||
@ -283,7 +302,7 @@ CAMLprim LLVMTypeRef llvm_packed_struct_type(LLVMContextRef C,
|
||||
}
|
||||
|
||||
/* lltype -> lltype array */
|
||||
CAMLprim value llvm_element_types(LLVMTypeRef StructTy) {
|
||||
CAMLprim value llvm_struct_element_types(LLVMTypeRef StructTy) {
|
||||
value Tys = alloc(LLVMCountStructElementTypes(StructTy), 0);
|
||||
LLVMGetStructElementTypes(StructTy, (LLVMTypeRef *) Tys);
|
||||
return Tys;
|
||||
@ -294,6 +313,21 @@ CAMLprim value llvm_is_packed(LLVMTypeRef StructTy) {
|
||||
return Val_bool(LLVMIsPackedStruct(StructTy));
|
||||
}
|
||||
|
||||
/*--... Operations on union types ..........................................--*/
|
||||
|
||||
/* llcontext -> lltype array -> lltype */
|
||||
CAMLprim LLVMTypeRef llvm_union_type(LLVMContextRef C, value ElementTypes) {
|
||||
return LLVMUnionTypeInContext(C, (LLVMTypeRef *) ElementTypes,
|
||||
Wosize_val(ElementTypes));
|
||||
}
|
||||
|
||||
/* lltype -> lltype array */
|
||||
CAMLprim value llvm_union_element_types(LLVMTypeRef UnionTy) {
|
||||
value Tys = alloc(LLVMCountUnionElementTypes(UnionTy), 0);
|
||||
LLVMGetUnionElementTypes(UnionTy, (LLVMTypeRef *) Tys);
|
||||
return Tys;
|
||||
}
|
||||
|
||||
/*--... Operations on array, pointer, and vector types .....................--*/
|
||||
|
||||
/* lltype -> int -> lltype */
|
||||
@ -406,6 +440,13 @@ CAMLprim value llvm_dump_value(LLVMValueRef Val) {
|
||||
return Val_unit;
|
||||
}
|
||||
|
||||
/*--... Operations on users ................................................--*/
|
||||
|
||||
/* llvalue -> int -> llvalue */
|
||||
CAMLprim LLVMValueRef llvm_operand(LLVMValueRef V, value I) {
|
||||
return LLVMGetOperand(V, Int_val(I));
|
||||
}
|
||||
|
||||
/*--... Operations on constants of (mostly) any type .......................--*/
|
||||
|
||||
/* llvalue -> bool */
|
||||
@ -423,6 +464,52 @@ CAMLprim value llvm_is_undef(LLVMValueRef Val) {
|
||||
return Val_bool(LLVMIsUndef(Val));
|
||||
}
|
||||
|
||||
/*--... Operations on instructions .........................................--*/
|
||||
|
||||
/* llvalue -> bool */
|
||||
CAMLprim value llvm_has_metadata(LLVMValueRef Val) {
|
||||
return Val_bool(LLVMHasMetadata(Val));
|
||||
}
|
||||
|
||||
/* llvalue -> int -> llvalue option */
|
||||
CAMLprim value llvm_metadata(LLVMValueRef Val, value MDKindID) {
|
||||
CAMLparam1(MDKindID);
|
||||
LLVMValueRef MD;
|
||||
if ((MD = LLVMGetMetadata(Val, Int_val(MDKindID)))) {
|
||||
value Option = alloc(1, 0);
|
||||
Field(Option, 0) = (value) MD;
|
||||
CAMLreturn(Option);
|
||||
}
|
||||
CAMLreturn(Val_int(0));
|
||||
}
|
||||
|
||||
/* llvalue -> int -> llvalue -> unit */
|
||||
CAMLprim value llvm_set_metadata(LLVMValueRef Val, value MDKindID,
|
||||
LLVMValueRef MD) {
|
||||
LLVMSetMetadata(Val, Int_val(MDKindID), MD);
|
||||
return Val_unit;
|
||||
}
|
||||
|
||||
/* llvalue -> int -> unit */
|
||||
CAMLprim value llvm_clear_metadata(LLVMValueRef Val, value MDKindID) {
|
||||
LLVMSetMetadata(Val, Int_val(MDKindID), NULL);
|
||||
return Val_unit;
|
||||
}
|
||||
|
||||
|
||||
/*--... Operations on metadata .............................................--*/
|
||||
|
||||
/* llcontext -> string -> llvalue */
|
||||
CAMLprim LLVMValueRef llvm_mdstring(LLVMContextRef C, value S) {
|
||||
return LLVMMDStringInContext(C, String_val(S), caml_string_length(S));
|
||||
}
|
||||
|
||||
/* llcontext -> llvalue array -> llvalue */
|
||||
CAMLprim LLVMValueRef llvm_mdnode(LLVMContextRef C, value ElementVals) {
|
||||
return LLVMMDNodeInContext(C, (LLVMValueRef*) Op_val(ElementVals),
|
||||
Wosize_val(ElementVals));
|
||||
}
|
||||
|
||||
/*--... Operations on scalar constants .....................................--*/
|
||||
|
||||
/* lltype -> int -> llvalue */
|
||||
@ -561,6 +648,14 @@ CAMLprim LLVMValueRef llvm_const_insertvalue(LLVMValueRef Aggregate,
|
||||
CAMLreturnT(LLVMValueRef, result);
|
||||
}
|
||||
|
||||
/* lltype -> string -> string -> bool -> bool -> llvalue */
|
||||
CAMLprim LLVMValueRef llvm_const_inline_asm(LLVMTypeRef Ty, value Asm,
|
||||
value Constraints, value HasSideEffects,
|
||||
value IsAlignStack) {
|
||||
return LLVMConstInlineAsm(Ty, String_val(Asm), String_val(Constraints),
|
||||
Bool_val(HasSideEffects), Bool_val(IsAlignStack));
|
||||
}
|
||||
|
||||
/*--... Operations on global variables, functions, and aliases (globals) ...--*/
|
||||
|
||||
/* llvalue -> bool */
|
||||
@ -612,6 +707,42 @@ CAMLprim value llvm_set_alignment(value Bytes, LLVMValueRef Global) {
|
||||
return Val_unit;
|
||||
}
|
||||
|
||||
/*--... Operations on uses .................................................--*/
|
||||
|
||||
/* llvalue -> lluse option */
|
||||
CAMLprim value llvm_use_begin(LLVMValueRef Val) {
|
||||
CAMLparam0();
|
||||
LLVMUseRef First;
|
||||
if ((First = LLVMGetFirstUse(Val))) {
|
||||
value Option = alloc(1, 0);
|
||||
Field(Option, 0) = (value) First;
|
||||
CAMLreturn(Option);
|
||||
}
|
||||
CAMLreturn(Val_int(0));
|
||||
}
|
||||
|
||||
/* lluse -> lluse option */
|
||||
CAMLprim value llvm_use_succ(LLVMUseRef U) {
|
||||
CAMLparam0();
|
||||
LLVMUseRef Next;
|
||||
if ((Next = LLVMGetNextUse(U))) {
|
||||
value Option = alloc(1, 0);
|
||||
Field(Option, 0) = (value) Next;
|
||||
CAMLreturn(Option);
|
||||
}
|
||||
CAMLreturn(Val_int(0));
|
||||
}
|
||||
|
||||
/* lluse -> llvalue */
|
||||
CAMLprim LLVMValueRef llvm_user(LLVMUseRef UR) {
|
||||
return LLVMGetUser(UR);
|
||||
}
|
||||
|
||||
/* lluse -> llvalue */
|
||||
CAMLprim LLVMValueRef llvm_used_value(LLVMUseRef UR) {
|
||||
return LLVMGetUsedValue(UR);
|
||||
}
|
||||
|
||||
/*--... Operations on global variables .....................................--*/
|
||||
|
||||
DEFINE_ITERATORS(global, Global, LLVMModuleRef, LLVMValueRef,
|
||||
@ -629,6 +760,20 @@ CAMLprim LLVMValueRef llvm_declare_global(LLVMTypeRef Ty, value Name,
|
||||
return LLVMAddGlobal(M, Ty, String_val(Name));
|
||||
}
|
||||
|
||||
/* lltype -> string -> int -> llmodule -> llvalue */
|
||||
CAMLprim LLVMValueRef llvm_declare_qualified_global(LLVMTypeRef Ty, value Name,
|
||||
value AddressSpace,
|
||||
LLVMModuleRef M) {
|
||||
LLVMValueRef GlobalVar;
|
||||
if ((GlobalVar = LLVMGetNamedGlobal(M, String_val(Name)))) {
|
||||
if (LLVMGetElementType(LLVMTypeOf(GlobalVar)) != Ty)
|
||||
return LLVMConstBitCast(GlobalVar,
|
||||
LLVMPointerType(Ty, Int_val(AddressSpace)));
|
||||
return GlobalVar;
|
||||
}
|
||||
return LLVMAddGlobal(M, Ty, String_val(Name));
|
||||
}
|
||||
|
||||
/* string -> llmodule -> llvalue option */
|
||||
CAMLprim value llvm_lookup_global(value Name, LLVMModuleRef M) {
|
||||
CAMLparam1(Name);
|
||||
@ -650,6 +795,19 @@ CAMLprim LLVMValueRef llvm_define_global(value Name, LLVMValueRef Initializer,
|
||||
return GlobalVar;
|
||||
}
|
||||
|
||||
/* string -> llvalue -> int -> llmodule -> llvalue */
|
||||
CAMLprim LLVMValueRef llvm_define_qualified_global(value Name,
|
||||
LLVMValueRef Initializer,
|
||||
value AddressSpace,
|
||||
LLVMModuleRef M) {
|
||||
LLVMValueRef GlobalVar = LLVMAddGlobalInAddressSpace(M,
|
||||
LLVMTypeOf(Initializer),
|
||||
String_val(Name),
|
||||
Int_val(AddressSpace));
|
||||
LLVMSetInitializer(GlobalVar, Initializer);
|
||||
return GlobalVar;
|
||||
}
|
||||
|
||||
/* llvalue -> unit */
|
||||
CAMLprim value llvm_delete_global(LLVMValueRef GlobalVar) {
|
||||
LLVMDeleteGlobal(GlobalVar);
|
||||
@ -692,6 +850,13 @@ CAMLprim value llvm_set_global_constant(value Flag, LLVMValueRef GlobalVar) {
|
||||
return Val_unit;
|
||||
}
|
||||
|
||||
/*--... Operations on aliases ..............................................--*/
|
||||
|
||||
CAMLprim LLVMValueRef llvm_add_alias(LLVMModuleRef M, LLVMTypeRef Ty,
|
||||
LLVMValueRef Aliasee, value Name) {
|
||||
return LLVMAddAlias(M, Ty, Aliasee, String_val(Name));
|
||||
}
|
||||
|
||||
/*--... Operations on functions ............................................--*/
|
||||
|
||||
DEFINE_ITERATORS(function, Function, LLVMModuleRef, LLVMValueRef,
|
||||
@ -978,7 +1143,7 @@ CAMLprim value llvm_position_builder(value Pos, value B) {
|
||||
}
|
||||
|
||||
/* llbuilder -> llbasicblock */
|
||||
CAMLprim LLVMBasicBlockRef llvm_insertion_block(LLVMBuilderRef B) {
|
||||
CAMLprim LLVMBasicBlockRef llvm_insertion_block(value B) {
|
||||
LLVMBasicBlockRef InsertBlock = LLVMGetInsertBlock(Builder_val(B));
|
||||
if (!InsertBlock)
|
||||
raise_not_found();
|
||||
@ -986,12 +1151,44 @@ CAMLprim LLVMBasicBlockRef llvm_insertion_block(LLVMBuilderRef B) {
|
||||
}
|
||||
|
||||
/* llvalue -> string -> llbuilder -> unit */
|
||||
CAMLprim value llvm_insert_into_builder(LLVMValueRef I, value Name,
|
||||
LLVMBuilderRef B) {
|
||||
LLVMInsertIntoBuilderWithName(B, I, String_val(Name));
|
||||
CAMLprim value llvm_insert_into_builder(LLVMValueRef I, value Name, value B) {
|
||||
LLVMInsertIntoBuilderWithName(Builder_val(B), I, String_val(Name));
|
||||
return Val_unit;
|
||||
}
|
||||
|
||||
/*--... Metadata ...........................................................--*/
|
||||
|
||||
/* llbuilder -> llvalue -> unit */
|
||||
CAMLprim value llvm_set_current_debug_location(value B, LLVMValueRef V) {
|
||||
LLVMSetCurrentDebugLocation(Builder_val(B), V);
|
||||
return Val_unit;
|
||||
}
|
||||
|
||||
/* llbuilder -> unit */
|
||||
CAMLprim value llvm_clear_current_debug_location(value B) {
|
||||
LLVMSetCurrentDebugLocation(Builder_val(B), NULL);
|
||||
return Val_unit;
|
||||
}
|
||||
|
||||
/* llbuilder -> llvalue option */
|
||||
CAMLprim value llvm_current_debug_location(value B) {
|
||||
CAMLparam0();
|
||||
LLVMValueRef L;
|
||||
if ((L = LLVMGetCurrentDebugLocation(Builder_val(B)))) {
|
||||
value Option = alloc(1, 0);
|
||||
Field(Option, 0) = (value) L;
|
||||
CAMLreturn(Option);
|
||||
}
|
||||
CAMLreturn(Val_int(0));
|
||||
}
|
||||
|
||||
/* llbuilder -> llvalue -> unit */
|
||||
CAMLprim value llvm_set_inst_debug_location(value B, LLVMValueRef V) {
|
||||
LLVMSetInstDebugLocation(Builder_val(B), V);
|
||||
return Val_unit;
|
||||
}
|
||||
|
||||
|
||||
/*--... Terminators ........................................................--*/
|
||||
|
||||
/* llbuilder -> llvalue */
|
||||
@ -1038,6 +1235,20 @@ CAMLprim value llvm_add_case(LLVMValueRef Switch, LLVMValueRef OnVal,
|
||||
return Val_unit;
|
||||
}
|
||||
|
||||
/* llvalue -> llbasicblock -> llbuilder -> llvalue */
|
||||
CAMLprim LLVMValueRef llvm_build_indirect_br(LLVMValueRef Addr,
|
||||
value EstimatedDests,
|
||||
value B) {
|
||||
return LLVMBuildIndirectBr(Builder_val(B), Addr, EstimatedDests);
|
||||
}
|
||||
|
||||
/* llvalue -> llvalue -> llbasicblock -> unit */
|
||||
CAMLprim value llvm_add_destination(LLVMValueRef IndirectBr,
|
||||
LLVMBasicBlockRef Dest) {
|
||||
LLVMAddDestination(IndirectBr, Dest);
|
||||
return Val_unit;
|
||||
}
|
||||
|
||||
/* llvalue -> llvalue array -> llbasicblock -> llbasicblock -> string ->
|
||||
llbuilder -> llvalue */
|
||||
CAMLprim LLVMValueRef llvm_build_invoke_nat(LLVMValueRef Fn, value Args,
|
||||
@ -1081,6 +1292,12 @@ CAMLprim LLVMValueRef llvm_build_nsw_add(LLVMValueRef LHS, LLVMValueRef RHS,
|
||||
return LLVMBuildNSWAdd(Builder_val(B), LHS, RHS, String_val(Name));
|
||||
}
|
||||
|
||||
/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
|
||||
CAMLprim LLVMValueRef llvm_build_nuw_add(LLVMValueRef LHS, LLVMValueRef RHS,
|
||||
value Name, value B) {
|
||||
return LLVMBuildNUWAdd(Builder_val(B), LHS, RHS, String_val(Name));
|
||||
}
|
||||
|
||||
/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
|
||||
CAMLprim LLVMValueRef llvm_build_fadd(LLVMValueRef LHS, LLVMValueRef RHS,
|
||||
value Name, value B) {
|
||||
@ -1093,6 +1310,18 @@ CAMLprim LLVMValueRef llvm_build_sub(LLVMValueRef LHS, LLVMValueRef RHS,
|
||||
return LLVMBuildSub(Builder_val(B), LHS, RHS, String_val(Name));
|
||||
}
|
||||
|
||||
/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
|
||||
CAMLprim LLVMValueRef llvm_build_nsw_sub(LLVMValueRef LHS, LLVMValueRef RHS,
|
||||
value Name, value B) {
|
||||
return LLVMBuildNSWSub(Builder_val(B), LHS, RHS, String_val(Name));
|
||||
}
|
||||
|
||||
/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
|
||||
CAMLprim LLVMValueRef llvm_build_nuw_sub(LLVMValueRef LHS, LLVMValueRef RHS,
|
||||
value Name, value B) {
|
||||
return LLVMBuildNUWSub(Builder_val(B), LHS, RHS, String_val(Name));
|
||||
}
|
||||
|
||||
/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
|
||||
CAMLprim LLVMValueRef llvm_build_fsub(LLVMValueRef LHS, LLVMValueRef RHS,
|
||||
value Name, value B) {
|
||||
@ -1105,6 +1334,18 @@ CAMLprim LLVMValueRef llvm_build_mul(LLVMValueRef LHS, LLVMValueRef RHS,
|
||||
return LLVMBuildMul(Builder_val(B), LHS, RHS, String_val(Name));
|
||||
}
|
||||
|
||||
/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
|
||||
CAMLprim LLVMValueRef llvm_build_nsw_mul(LLVMValueRef LHS, LLVMValueRef RHS,
|
||||
value Name, value B) {
|
||||
return LLVMBuildNSWMul(Builder_val(B), LHS, RHS, String_val(Name));
|
||||
}
|
||||
|
||||
/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
|
||||
CAMLprim LLVMValueRef llvm_build_nuw_mul(LLVMValueRef LHS, LLVMValueRef RHS,
|
||||
value Name, value B) {
|
||||
return LLVMBuildNUWMul(Builder_val(B), LHS, RHS, String_val(Name));
|
||||
}
|
||||
|
||||
/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
|
||||
CAMLprim LLVMValueRef llvm_build_fmul(LLVMValueRef LHS, LLVMValueRef RHS,
|
||||
value Name, value B) {
|
||||
@ -1195,6 +1436,24 @@ CAMLprim LLVMValueRef llvm_build_neg(LLVMValueRef X,
|
||||
return LLVMBuildNeg(Builder_val(B), X, String_val(Name));
|
||||
}
|
||||
|
||||
/* llvalue -> string -> llbuilder -> llvalue */
|
||||
CAMLprim LLVMValueRef llvm_build_nsw_neg(LLVMValueRef X,
|
||||
value Name, value B) {
|
||||
return LLVMBuildNSWNeg(Builder_val(B), X, String_val(Name));
|
||||
}
|
||||
|
||||
/* llvalue -> string -> llbuilder -> llvalue */
|
||||
CAMLprim LLVMValueRef llvm_build_nuw_neg(LLVMValueRef X,
|
||||
value Name, value B) {
|
||||
return LLVMBuildNUWNeg(Builder_val(B), X, String_val(Name));
|
||||
}
|
||||
|
||||
/* llvalue -> string -> llbuilder -> llvalue */
|
||||
CAMLprim LLVMValueRef llvm_build_fneg(LLVMValueRef X,
|
||||
value Name, value B) {
|
||||
return LLVMBuildFNeg(Builder_val(B), X, String_val(Name));
|
||||
}
|
||||
|
||||
/* llvalue -> string -> llbuilder -> llvalue */
|
||||
CAMLprim LLVMValueRef llvm_build_not(LLVMValueRef X,
|
||||
value Name, value B) {
|
||||
@ -1203,18 +1462,6 @@ CAMLprim LLVMValueRef llvm_build_not(LLVMValueRef X,
|
||||
|
||||
/*--... Memory .............................................................--*/
|
||||
|
||||
/* 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 Size,
|
||||
value Name, value B) {
|
||||
return LLVMBuildArrayMalloc(Builder_val(B), Ty, Size, String_val(Name));
|
||||
}
|
||||
|
||||
/* lltype -> string -> llbuilder -> llvalue */
|
||||
CAMLprim LLVMValueRef llvm_build_alloca(LLVMTypeRef Ty,
|
||||
value Name, value B) {
|
||||
@ -1227,11 +1474,6 @@ CAMLprim LLVMValueRef llvm_build_array_alloca(LLVMTypeRef Ty, LLVMValueRef Size,
|
||||
return LLVMBuildArrayAlloca(Builder_val(B), Ty, Size, String_val(Name));
|
||||
}
|
||||
|
||||
/* llvalue -> llbuilder -> llvalue */
|
||||
CAMLprim LLVMValueRef llvm_build_free(LLVMValueRef Pointer, value B) {
|
||||
return LLVMBuildFree(Builder_val(B), Pointer);
|
||||
}
|
||||
|
||||
/* llvalue -> string -> llbuilder -> llvalue */
|
||||
CAMLprim LLVMValueRef llvm_build_load(LLVMValueRef Pointer,
|
||||
value Name, value B) {
|
||||
@ -1510,14 +1752,6 @@ CAMLprim LLVMValueRef llvm_build_ptrdiff(LLVMValueRef LHS, LLVMValueRef RHS,
|
||||
return LLVMBuildPtrDiff(Builder_val(B), LHS, RHS, String_val(Name));
|
||||
}
|
||||
|
||||
/*===-- Module Providers --------------------------------------------------===*/
|
||||
|
||||
/* llmoduleprovider -> unit */
|
||||
CAMLprim value llvm_dispose_module_provider(LLVMModuleProviderRef MP) {
|
||||
LLVMDisposeModuleProvider(MP);
|
||||
return Val_unit;
|
||||
}
|
||||
|
||||
|
||||
/*===-- Memory buffers ----------------------------------------------------===*/
|
||||
|
||||
|
176
configure
vendored
176
configure
vendored
@ -689,12 +689,16 @@ TARGET_HAS_JIT
|
||||
ENABLE_DOXYGEN
|
||||
ENABLE_THREADS
|
||||
ENABLE_PIC
|
||||
ENABLE_SHARED
|
||||
TARGETS_TO_BUILD
|
||||
LLVM_ENUM_TARGETS
|
||||
LLVM_ENUM_ASM_PRINTERS
|
||||
LLVM_ENUM_ASM_PARSERS
|
||||
LLVM_ENUM_DISASSEMBLERS
|
||||
ENABLE_CBE_PRINTF_A
|
||||
CLANGPATH
|
||||
CLANGXXPATH
|
||||
ENABLE_BUILT_CLANG
|
||||
OPTIMIZE_OPTION
|
||||
EXTRA_OPTIONS
|
||||
BINUTILS_INCDIR
|
||||
@ -754,6 +758,7 @@ LLVMGCCCOMMAND
|
||||
LLVMGXXCOMMAND
|
||||
LLVMGCC
|
||||
LLVMGXX
|
||||
LLVMCC_OPTION
|
||||
NO_VARIADIC_MACROS
|
||||
NO_MISSING_FIELD_INITIALIZERS
|
||||
USE_UDIS86
|
||||
@ -764,11 +769,9 @@ MMAP_FILE
|
||||
LLVMCC1
|
||||
LLVMCC1PLUS
|
||||
LLVMGCCDIR
|
||||
LLVMGCCLIBEXEC
|
||||
LLVMGCC_VERSION
|
||||
LLVMGCC_MAJVERS
|
||||
LLVMGCC_LANGS
|
||||
SHLIBEXT
|
||||
SHLIBPATH_VAR
|
||||
LLVM_PREFIX
|
||||
LLVM_BINDIR
|
||||
LLVM_LIBDIR
|
||||
@ -810,6 +813,7 @@ projects/llvm-java
|
||||
projects/llvm-tv
|
||||
projects/llvm-poolalloc
|
||||
projects/poolalloc
|
||||
projects/safecode
|
||||
projects/llvm-kernel'
|
||||
|
||||
# Initialize some variables set by options.
|
||||
@ -1401,6 +1405,8 @@ Optional Features:
|
||||
--enable-threads Use threads if available (default is YES)
|
||||
--enable-pic Build LLVM with Position Independent Code (default
|
||||
is YES)
|
||||
--enable-shared Build a shared library and link tools against it
|
||||
(default is NO)
|
||||
--enable-targets Build specific host targets: all or
|
||||
target1,target2,... Valid targets are: host, x86,
|
||||
x86_64, sparc, powerpc, alpha, arm, mips, spu,
|
||||
@ -1426,6 +1432,10 @@ Optional Packages:
|
||||
searches PATH)
|
||||
--with-llvmgxx Specify location of llvm-g++ driver (default
|
||||
searches PATH)
|
||||
--with-clang Specify location of clang compiler (default is
|
||||
--with-built-clang)
|
||||
--with-built-clang Use the compiled Clang as the LLVM compiler
|
||||
(default=check)
|
||||
--with-optimize-option Select the compiler options to use for optimized
|
||||
builds
|
||||
--with-extra-options Specify additional options to compile LLVM with
|
||||
@ -1442,6 +1452,8 @@ Optional Packages:
|
||||
--with-binutils-include Specify path to binutils/include/ containing
|
||||
plugin-api.h file for gold plugin.
|
||||
--with-tclinclude directory where tcl headers are
|
||||
--with-llvmcc=<name> Choose the LLVM capable compiler to use (llvm-gcc,
|
||||
clang, or none; default=check)
|
||||
--with-udis86=<path> Use udis86 external x86 disassembler library
|
||||
--with-oprofile=<prefix>
|
||||
Tell OProfile >= 0.9.4 how to symbolize JIT output
|
||||
@ -1967,6 +1979,8 @@ do
|
||||
llvm-poolalloc) subdirs="$subdirs projects/llvm-poolalloc"
|
||||
;;
|
||||
poolalloc) subdirs="$subdirs projects/poolalloc"
|
||||
;;
|
||||
safecode) subdirs="$subdirs projects/safecode"
|
||||
;;
|
||||
llvm-kernel) subdirs="$subdirs projects/llvm-kernel"
|
||||
;;
|
||||
@ -2320,6 +2334,7 @@ else
|
||||
msp430-*) llvm_cv_target_arch="MSP430" ;;
|
||||
s390x-*) llvm_cv_target_arch="SystemZ" ;;
|
||||
bfin-*) llvm_cv_target_arch="Blackfin" ;;
|
||||
mblaze-*) llvm_cv_target_arch="MBlaze" ;;
|
||||
*) llvm_cv_target_arch="Unknown" ;;
|
||||
esac
|
||||
fi
|
||||
@ -4784,6 +4799,8 @@ else
|
||||
SystemZ) TARGET_HAS_JIT=0
|
||||
;;
|
||||
Blackfin) TARGET_HAS_JIT=0
|
||||
;;
|
||||
MBlaze) TARGET_HAS_JIT=0
|
||||
;;
|
||||
*) TARGET_HAS_JIT=0
|
||||
;;
|
||||
@ -4857,6 +4874,25 @@ cat >>confdefs.h <<_ACEOF
|
||||
_ACEOF
|
||||
|
||||
|
||||
# Check whether --enable-shared was given.
|
||||
if test "${enable_shared+set}" = set; then
|
||||
enableval=$enable_shared;
|
||||
else
|
||||
enableval=default
|
||||
fi
|
||||
|
||||
case "$enableval" in
|
||||
yes) ENABLE_SHARED=1
|
||||
;;
|
||||
no) ENABLE_SHARED=0
|
||||
;;
|
||||
default) ENABLE_SHARED=0
|
||||
;;
|
||||
*) { { echo "$as_me:$LINENO: error: Invalid setting for --enable-shared. Use \"yes\" or \"no\"" >&5
|
||||
echo "$as_me: error: Invalid setting for --enable-shared. Use \"yes\" or \"no\"" >&2;}
|
||||
{ (exit 1); exit 1; }; } ;;
|
||||
esac
|
||||
|
||||
TARGETS_TO_BUILD=""
|
||||
# Check whether --enable-targets was given.
|
||||
if test "${enable_targets+set}" = set; then
|
||||
@ -4869,7 +4905,7 @@ if test "$enableval" = host-only ; then
|
||||
enableval=host
|
||||
fi
|
||||
case "$enableval" in
|
||||
all) TARGETS_TO_BUILD="X86 Sparc PowerPC Alpha ARM Mips CellSPU PIC16 XCore MSP430 SystemZ Blackfin CBackend MSIL CppBackend" ;;
|
||||
all) TARGETS_TO_BUILD="X86 Sparc PowerPC Alpha ARM Mips CellSPU PIC16 XCore MSP430 SystemZ Blackfin CBackend MSIL CppBackend MBlaze" ;;
|
||||
*)for a_target in `echo $enableval|sed -e 's/,/ /g' ` ; do
|
||||
case "$a_target" in
|
||||
x86) TARGETS_TO_BUILD="X86 $TARGETS_TO_BUILD" ;;
|
||||
@ -4888,6 +4924,7 @@ case "$enableval" in
|
||||
cbe) TARGETS_TO_BUILD="CBackend $TARGETS_TO_BUILD" ;;
|
||||
msil) TARGETS_TO_BUILD="MSIL $TARGETS_TO_BUILD" ;;
|
||||
cpp) TARGETS_TO_BUILD="CppBackend $TARGETS_TO_BUILD" ;;
|
||||
mblaze) TARGETS_TO_BUILD="MBlaze $TARGETS_TO_BUILD" ;;
|
||||
host) case "$llvm_cv_target_arch" in
|
||||
x86) TARGETS_TO_BUILD="X86 $TARGETS_TO_BUILD" ;;
|
||||
x86_64) TARGETS_TO_BUILD="X86 $TARGETS_TO_BUILD" ;;
|
||||
@ -4896,6 +4933,7 @@ case "$enableval" in
|
||||
Alpha) TARGETS_TO_BUILD="Alpha $TARGETS_TO_BUILD" ;;
|
||||
ARM) TARGETS_TO_BUILD="ARM $TARGETS_TO_BUILD" ;;
|
||||
Mips) TARGETS_TO_BUILD="Mips $TARGETS_TO_BUILD" ;;
|
||||
MBlaze) TARGETS_TO_BUILD="MBlaze $TARGETS_TO_BUILD" ;;
|
||||
CellSPU|SPU) TARGETS_TO_BUILD="CellSPU $TARGETS_TO_BUILD" ;;
|
||||
PIC16) TARGETS_TO_BUILD="PIC16 $TARGETS_TO_BUILD" ;;
|
||||
XCore) TARGETS_TO_BUILD="XCore $TARGETS_TO_BUILD" ;;
|
||||
@ -5029,6 +5067,69 @@ echo "$as_me: error: Invalid llvm-gcc. Use --with-llvmgcc when --with-llvmgxx is
|
||||
fi
|
||||
|
||||
|
||||
# Check whether --with-clang was given.
|
||||
if test "${with_clang+set}" = set; then
|
||||
withval=$with_clang;
|
||||
else
|
||||
with_clang=default
|
||||
fi
|
||||
|
||||
|
||||
|
||||
# Check whether --with-built-clang was given.
|
||||
if test "${with_built_clang+set}" = set; then
|
||||
withval=$with_built_clang;
|
||||
else
|
||||
with_built_clang=check
|
||||
fi
|
||||
|
||||
|
||||
{ echo "$as_me:$LINENO: checking clang compiler" >&5
|
||||
echo $ECHO_N "checking clang compiler... $ECHO_C" >&6; }
|
||||
WITH_CLANGPATH=""
|
||||
WITH_BUILT_CLANG=0
|
||||
if test "$with_clang" != "default"; then
|
||||
WITH_CLANGPATH="$with_clang"
|
||||
if ! test -x "$WITH_CLANGPATH"; then
|
||||
{ { echo "$as_me:$LINENO: error: invalid --with-clang, path does not specify an executable" >&5
|
||||
echo "$as_me: error: invalid --with-clang, path does not specify an executable" >&2;}
|
||||
{ (exit 1); exit 1; }; }
|
||||
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
|
||||
{ { echo "$as_me:$LINENO: error: invalid value for --with-built-clang." >&5
|
||||
echo "$as_me: error: invalid value for --with-built-clang." >&2;}
|
||||
{ (exit 1); exit 1; }; }
|
||||
fi
|
||||
|
||||
if test -f ${srcdir}/tools/clang/README.txt; then
|
||||
WITH_BUILT_CLANG=1
|
||||
fi
|
||||
fi
|
||||
|
||||
if ! test -z "$WITH_CLANGPATH"; then
|
||||
{ echo "$as_me:$LINENO: result: $WITH_CLANGPATH" >&5
|
||||
echo "${ECHO_T}$WITH_CLANGPATH" >&6; }
|
||||
WITH_CLANGXXPATH=`"$WITH_CLANGPATH" --print-prog-name=clang++`
|
||||
elif test "$WITH_BUILT_CLANG" = "1"; then
|
||||
{ echo "$as_me:$LINENO: result: built" >&5
|
||||
echo "${ECHO_T}built" >&6; }
|
||||
else
|
||||
{ echo "$as_me:$LINENO: result: none" >&5
|
||||
echo "${ECHO_T}none" >&6; }
|
||||
fi
|
||||
CLANGPATH=$WITH_CLANGPATH
|
||||
|
||||
CLANGXXPATH=$WITH_CLANGXXPATH
|
||||
|
||||
ENABLE_BUILT_CLANG=$WITH_BUILT_CLANG
|
||||
|
||||
|
||||
|
||||
# Check whether --with-optimize-option was given.
|
||||
if test "${with_optimize_option+set}" = set; then
|
||||
withval=$with_optimize_option;
|
||||
@ -11035,7 +11136,7 @@ else
|
||||
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
|
||||
lt_status=$lt_dlunknown
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 11038 "configure"
|
||||
#line 11139 "configure"
|
||||
#include "confdefs.h"
|
||||
|
||||
#if HAVE_DLFCN_H
|
||||
@ -12805,6 +12906,36 @@ else
|
||||
fi
|
||||
|
||||
|
||||
# Check whether --with-llvmcc was given.
|
||||
if test "${with_llvmcc+set}" = set; then
|
||||
withval=$with_llvmcc;
|
||||
else
|
||||
with_llvmcc=check
|
||||
fi
|
||||
|
||||
{ echo "$as_me:$LINENO: checking LLVM capable compiler" >&5
|
||||
echo $ECHO_N "checking LLVM capable compiler... $ECHO_C" >&6; }
|
||||
if test "$with_llvmcc" != "check"; then
|
||||
if (test "$with_llvmcc" != "llvm-gcc" &&
|
||||
test "$with_llvmcc" != "clang" &&
|
||||
test "$with_llvmcc" != "none"); then
|
||||
{ { echo "$as_me:$LINENO: error: invalid value for --with-llvmcc, expected 'llvm-gcc', 'clang', or 'none'." >&5
|
||||
echo "$as_me: error: invalid value for --with-llvmcc, expected 'llvm-gcc', 'clang', or 'none'." >&2;}
|
||||
{ (exit 1); exit 1; }; }
|
||||
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
|
||||
{ echo "$as_me:$LINENO: result: $WITH_LLVMCC" >&5
|
||||
echo "${ECHO_T}$WITH_LLVMCC" >&6; }
|
||||
LLVMCC_OPTION=$WITH_LLVMCC
|
||||
|
||||
|
||||
{ echo "$as_me:$LINENO: checking tool compatibility" >&5
|
||||
echo $ECHO_N "checking tool compatibility... $ECHO_C" >&6; }
|
||||
|
||||
@ -16413,6 +16544,7 @@ ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
|
||||
ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
|
||||
ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
|
||||
|
||||
ac_save_CXXFLAGS=$CXXFLAGS
|
||||
CXXFLAGS=-pedantic
|
||||
if test "$cross_compiling" = yes; then
|
||||
ac_cv_huge_val_sanity=yes
|
||||
@ -16465,6 +16597,7 @@ rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$a
|
||||
fi
|
||||
|
||||
|
||||
CXXFLAGS=$ac_save_CXXFLAGS
|
||||
ac_ext=c
|
||||
ac_cpp='$CPP $CPPFLAGS'
|
||||
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
|
||||
@ -19576,15 +19709,6 @@ echo $ECHO_N "checking llvm-gcc component support... $ECHO_C" >&6; }
|
||||
llvmgccdir=`echo "$llvmcc1path" | sed 's,/libexec/.*,,'`
|
||||
LLVMGCCDIR=$llvmgccdir
|
||||
|
||||
llvmgcclibexec=`echo "$llvmcc1path" | sed 's,/cc1,,'`
|
||||
LLVMGCCLIBEXEC=$llvmgcclibexec
|
||||
|
||||
llvmgccversion=`"$LLVMGCC" -dumpversion 2>&1 | sed 's/^\([0-9.]*\).*/\1/'`
|
||||
llvmgccmajvers=`echo $llvmgccversion | sed 's/^\([0-9]\).*/\1/'`
|
||||
LLVMGCC_VERSION=$llvmgccversion
|
||||
|
||||
LLVMGCC_MAJVERS=$llvmgccmajvers
|
||||
|
||||
llvmgcclangs=`"$LLVMGCC" -v --help 2>&1 | grep '^Configured with:' | sed 's/^.*--enable-languages=\([^ ]*\).*/\1/'`
|
||||
LLVMGCC_LANGS=$llvmgcclangs
|
||||
|
||||
@ -19595,6 +19719,9 @@ fi
|
||||
SHLIBEXT=$libltdl_cv_shlibext
|
||||
|
||||
|
||||
SHLIBPATH_VAR=$libltdl_cv_shlibpath_var
|
||||
|
||||
|
||||
# Translate the various configuration directories and other basic
|
||||
# information into substitutions that will end up in Makefile.config.in
|
||||
# that these configured values can be used by the makefiles
|
||||
@ -19605,7 +19732,7 @@ eval LLVM_PREFIX="${prefix}";
|
||||
eval LLVM_BINDIR="${prefix}/bin";
|
||||
eval LLVM_LIBDIR="${prefix}/lib";
|
||||
eval LLVM_DATADIR="${prefix}/share/llvm";
|
||||
eval LLVM_DOCSDIR="${prefix}/docs/llvm";
|
||||
eval LLVM_DOCSDIR="${prefix}/share/doc/llvm";
|
||||
eval LLVM_ETCDIR="${prefix}/etc/llvm";
|
||||
eval LLVM_INCLUDEDIR="${prefix}/include";
|
||||
eval LLVM_INFODIR="${prefix}/info";
|
||||
@ -20652,16 +20779,16 @@ TARGET_HAS_JIT!$TARGET_HAS_JIT$ac_delim
|
||||
ENABLE_DOXYGEN!$ENABLE_DOXYGEN$ac_delim
|
||||
ENABLE_THREADS!$ENABLE_THREADS$ac_delim
|
||||
ENABLE_PIC!$ENABLE_PIC$ac_delim
|
||||
ENABLE_SHARED!$ENABLE_SHARED$ac_delim
|
||||
TARGETS_TO_BUILD!$TARGETS_TO_BUILD$ac_delim
|
||||
LLVM_ENUM_TARGETS!$LLVM_ENUM_TARGETS$ac_delim
|
||||
LLVM_ENUM_ASM_PRINTERS!$LLVM_ENUM_ASM_PRINTERS$ac_delim
|
||||
LLVM_ENUM_ASM_PARSERS!$LLVM_ENUM_ASM_PARSERS$ac_delim
|
||||
LLVM_ENUM_DISASSEMBLERS!$LLVM_ENUM_DISASSEMBLERS$ac_delim
|
||||
ENABLE_CBE_PRINTF_A!$ENABLE_CBE_PRINTF_A$ac_delim
|
||||
OPTIMIZE_OPTION!$OPTIMIZE_OPTION$ac_delim
|
||||
EXTRA_OPTIONS!$EXTRA_OPTIONS$ac_delim
|
||||
BINUTILS_INCDIR!$BINUTILS_INCDIR$ac_delim
|
||||
ENABLE_LLVMC_DYNAMIC!$ENABLE_LLVMC_DYNAMIC$ac_delim
|
||||
CLANGPATH!$CLANGPATH$ac_delim
|
||||
CLANGXXPATH!$CLANGXXPATH$ac_delim
|
||||
ENABLE_BUILT_CLANG!$ENABLE_BUILT_CLANG$ac_delim
|
||||
_ACEOF
|
||||
|
||||
if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then
|
||||
@ -20703,6 +20830,10 @@ _ACEOF
|
||||
ac_delim='%!_!# '
|
||||
for ac_last_try in false false false false false :; do
|
||||
cat >conf$$subs.sed <<_ACEOF
|
||||
OPTIMIZE_OPTION!$OPTIMIZE_OPTION$ac_delim
|
||||
EXTRA_OPTIONS!$EXTRA_OPTIONS$ac_delim
|
||||
BINUTILS_INCDIR!$BINUTILS_INCDIR$ac_delim
|
||||
ENABLE_LLVMC_DYNAMIC!$ENABLE_LLVMC_DYNAMIC$ac_delim
|
||||
ENABLE_LLVMC_DYNAMIC_PLUGINS!$ENABLE_LLVMC_DYNAMIC_PLUGINS$ac_delim
|
||||
CXX!$CXX$ac_delim
|
||||
CXXFLAGS!$CXXFLAGS$ac_delim
|
||||
@ -20758,6 +20889,7 @@ LLVMGCCCOMMAND!$LLVMGCCCOMMAND$ac_delim
|
||||
LLVMGXXCOMMAND!$LLVMGXXCOMMAND$ac_delim
|
||||
LLVMGCC!$LLVMGCC$ac_delim
|
||||
LLVMGXX!$LLVMGXX$ac_delim
|
||||
LLVMCC_OPTION!$LLVMCC_OPTION$ac_delim
|
||||
NO_VARIADIC_MACROS!$NO_VARIADIC_MACROS$ac_delim
|
||||
NO_MISSING_FIELD_INITIALIZERS!$NO_MISSING_FIELD_INITIALIZERS$ac_delim
|
||||
USE_UDIS86!$USE_UDIS86$ac_delim
|
||||
@ -20768,11 +20900,9 @@ MMAP_FILE!$MMAP_FILE$ac_delim
|
||||
LLVMCC1!$LLVMCC1$ac_delim
|
||||
LLVMCC1PLUS!$LLVMCC1PLUS$ac_delim
|
||||
LLVMGCCDIR!$LLVMGCCDIR$ac_delim
|
||||
LLVMGCCLIBEXEC!$LLVMGCCLIBEXEC$ac_delim
|
||||
LLVMGCC_VERSION!$LLVMGCC_VERSION$ac_delim
|
||||
LLVMGCC_MAJVERS!$LLVMGCC_MAJVERS$ac_delim
|
||||
LLVMGCC_LANGS!$LLVMGCC_LANGS$ac_delim
|
||||
SHLIBEXT!$SHLIBEXT$ac_delim
|
||||
SHLIBPATH_VAR!$SHLIBPATH_VAR$ac_delim
|
||||
LLVM_PREFIX!$LLVM_PREFIX$ac_delim
|
||||
LLVM_BINDIR!$LLVM_BINDIR$ac_delim
|
||||
LLVM_LIBDIR!$LLVM_LIBDIR$ac_delim
|
||||
@ -20793,7 +20923,7 @@ LIBOBJS!$LIBOBJS$ac_delim
|
||||
LTLIBOBJS!$LTLIBOBJS$ac_delim
|
||||
_ACEOF
|
||||
|
||||
if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 88; then
|
||||
if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 91; then
|
||||
break
|
||||
elif $ac_last_try; then
|
||||
{ { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
|
||||
|
362
docs/AdvancedGetElementPtr.html
Normal file
362
docs/AdvancedGetElementPtr.html
Normal file
@ -0,0 +1,362 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
|
||||
"http://www.w3.org/TR/html4/strict.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<title>The Revenge Of The Often Misunderstood GEP Instruction</title>
|
||||
<link rel="stylesheet" href="llvm.css" type="text/css">
|
||||
<style type="text/css">
|
||||
TABLE { text-align: left; border: 1px solid black; border-collapse: collapse; margin: 0 0 0 0; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="doc_title">
|
||||
The Revenge Of The Often Misunderstood GEP Instruction
|
||||
</div>
|
||||
|
||||
<!-- *********************************************************************** -->
|
||||
<div class="doc_section"><a name="intro"><b>Introduction</b></a></div>
|
||||
<!-- *********************************************************************** -->
|
||||
<div class="doc_text">
|
||||
<p>GEP was mysterious and wily at first, but it turned out that the basic
|
||||
workings were fairly comprehensible. However the dragon was merely subdued;
|
||||
now it's back, and it has more fundamental complexity to confront. This
|
||||
document seeks to uncover misunderstandings of the GEP operator that tend
|
||||
to persist past initial confusion about the funky "extra 0" thing. Here we
|
||||
show that the GEP instruction is really not quite as simple as it seems,
|
||||
even after the initial confusion is overcome.</p>
|
||||
</div>
|
||||
|
||||
<!-- *********************************************************************** -->
|
||||
<div class="doc_subsection">
|
||||
<a name="lead0"><b>How is GEP different from ptrtoint, arithmetic,
|
||||
and inttoptr?</b></a>
|
||||
</div>
|
||||
<div class="doc_text">
|
||||
<p>It's very similar; there are only subtle differences.</p>
|
||||
|
||||
<p>With ptrtoint, you have to pick an integer type. One approach is to pick i64;
|
||||
this is safe on everything LLVM supports (LLVM internally assumes pointers
|
||||
are never wider than 64 bits in many places), and the optimizer will actually
|
||||
narrow the i64 arithmetic down to the actual pointer size on targets which
|
||||
don't support 64-bit arithmetic in most cases. However, there are some cases
|
||||
where it doesn't do this. With GEP you can avoid this problem.
|
||||
|
||||
<p>Also, GEP carries additional pointer aliasing rules. It's invalid to take a
|
||||
GEP from one object, address into a different separately allocated
|
||||
object, and dereference it. IR producers (front-ends) must follow this rule,
|
||||
and consumers (optimizers, specifically alias analysis) benefit from being
|
||||
able to rely on it.</p>
|
||||
|
||||
<p>And, GEP is more concise in common cases.</p>
|
||||
|
||||
<p>However, for the underlying integer computation implied, there
|
||||
is no difference.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- *********************************************************************** -->
|
||||
<div class="doc_subsection">
|
||||
<a name="lead0"><b>I'm writing a backend for a target which needs custom
|
||||
lowering for GEP. How do I do this?</b></a>
|
||||
</div>
|
||||
<div class="doc_text">
|
||||
<p>You don't. The integer computation implied by a GEP is target-independent.
|
||||
Typically what you'll need to do is make your backend pattern-match
|
||||
expressions trees involving ADD, MUL, etc., which are what GEP is lowered
|
||||
into. This has the advantage of letting your code work correctly in more
|
||||
cases.</p>
|
||||
|
||||
<p>GEP does use target-dependent parameters for the size and layout of data
|
||||
types, which targets can customize.</p>
|
||||
|
||||
<p>If you require support for addressing units which are not 8 bits, you'll
|
||||
need to fix a lot of code in the backend, with GEP lowering being only a
|
||||
small piece of the overall picture.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- *********************************************************************** -->
|
||||
<div class="doc_subsection">
|
||||
<a name="lead0"><b>Why do struct member indices always use i32?</b></a>
|
||||
</div>
|
||||
<div class="doc_text">
|
||||
<p>The specific type i32 is probably just a historical artifact, however it's
|
||||
wide enough for all practical purposes, so there's been no need to change it.
|
||||
It doesn't necessarily imply i32 address arithmetic; it's just an identifier
|
||||
which identifies a field in a struct. Requiring that all struct indices be
|
||||
the same reduces the range of possibilities for cases where two GEPs are
|
||||
effectively the same but have distinct operand types.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- *********************************************************************** -->
|
||||
<div class="doc_subsection">
|
||||
<a name="lead0"><b>How does VLA addressing work with GEPs?</b></a>
|
||||
</div>
|
||||
<div class="doc_text">
|
||||
<p>GEPs don't natively support VLAs. LLVM's type system is entirely static,
|
||||
and GEP address computations are guided by an LLVM type.</p>
|
||||
|
||||
<p>VLA indices can be implemented as linearized indices. For example, an
|
||||
expression like X[a][b][c], must be effectively lowered into a form
|
||||
like X[a*m+b*n+c], so that it appears to the GEP as a single-dimensional
|
||||
array reference.</p>
|
||||
|
||||
<p>This means if you want to write an analysis which understands array
|
||||
indices and you want to support VLAs, your code will have to be
|
||||
prepared to reverse-engineer the linearization. One way to solve this
|
||||
problem is to use the ScalarEvolution library, which always presents
|
||||
VLA and non-VLA indexing in the same manner.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- *********************************************************************** -->
|
||||
<div class="doc_subsection">
|
||||
<a name="lead0"><b>What happens if an array index is out of bounds?</b></a>
|
||||
</div>
|
||||
<div class="doc_text">
|
||||
<p>There are two senses in which an array index can be out of bounds.</p>
|
||||
|
||||
<p>First, there's the array type which comes from the (static) type of
|
||||
the first operand to the GEP. Indices greater than the number of elements
|
||||
in the corresponding static array type are valid. There is no problem with
|
||||
out of bounds indices in this sense. Indexing into an array only depends
|
||||
on the size of the array element, not the number of elements.</p>
|
||||
|
||||
<p>A common example of how this is used is arrays where the size is not known.
|
||||
It's common to use array types with zero length to represent these. The
|
||||
fact that the static type says there are zero elements is irrelevant; it's
|
||||
perfectly valid to compute arbitrary element indices, as the computation
|
||||
only depends on the size of the array element, not the number of
|
||||
elements. Note that zero-sized arrays are not a special case here.</p>
|
||||
|
||||
<p>This sense is unconnected with <tt>inbounds</tt> keyword. The
|
||||
<tt>inbounds</tt> keyword is designed to describe low-level pointer
|
||||
arithmetic overflow conditions, rather than high-level array
|
||||
indexing rules.
|
||||
|
||||
<p>Analysis passes which wish to understand array indexing should not
|
||||
assume that the static array type bounds are respected.</p>
|
||||
|
||||
<p>The second sense of being out of bounds is computing an address that's
|
||||
beyond the actual underlying allocated object.</p>
|
||||
|
||||
<p>With the <tt>inbounds</tt> keyword, the result value of the GEP is
|
||||
undefined if the address is outside the actual underlying allocated
|
||||
object and not the address one-past-the-end.</p>
|
||||
|
||||
<p>Without the <tt>inbounds</tt> keyword, there are no restrictions
|
||||
on computing out-of-bounds addresses. Obviously, performing a load or
|
||||
a store requires an address of allocated and sufficiently aligned
|
||||
memory. But the GEP itself is only concerned with computing addresses.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- *********************************************************************** -->
|
||||
<div class="doc_subsection">
|
||||
<a name="lead0"><b>Can array indices be negative?</b></a>
|
||||
</div>
|
||||
<div class="doc_text">
|
||||
<p>Yes. This is basically a special case of array indices being out
|
||||
of bounds.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- *********************************************************************** -->
|
||||
<div class="doc_subsection">
|
||||
<a name="lead0"><b>Can I compare two values computed with GEPs?</b></a>
|
||||
</div>
|
||||
<div class="doc_text">
|
||||
<p>Yes. If both addresses are within the same allocated object, or
|
||||
one-past-the-end, you'll get the comparison result you expect. If either
|
||||
is outside of it, integer arithmetic wrapping may occur, so the
|
||||
comparison may not be meaningful.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- *********************************************************************** -->
|
||||
<div class="doc_subsection">
|
||||
<a name="lead0"><b>Can I do GEP with a different pointer type than the type of
|
||||
the underlying object?</b></a>
|
||||
</div>
|
||||
<div class="doc_text">
|
||||
<p>Yes. There are no restrictions on bitcasting a pointer value to an arbitrary
|
||||
pointer type. The types in a GEP serve only to define the parameters for the
|
||||
underlying integer computation. They need not correspond with the actual
|
||||
type of the underlying object.</p>
|
||||
|
||||
<p>Furthermore, loads and stores don't have to use the same types as the type
|
||||
of the underlying object. Types in this context serve only to specify
|
||||
memory size and alignment. Beyond that there are merely a hint to the
|
||||
optimizer indicating how the value will likely be used.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- *********************************************************************** -->
|
||||
<div class="doc_subsection">
|
||||
<a name="lead0"><b>Can I cast an object's address to integer and add it
|
||||
to null?</b></a>
|
||||
</div>
|
||||
<div class="doc_text">
|
||||
<p>You can compute an address that way, but if you use GEP to do the add,
|
||||
you can't use that pointer to actually access the object, unless the
|
||||
object is managed outside of LLVM.</p>
|
||||
|
||||
<p>The underlying integer computation is sufficiently defined; null has a
|
||||
defined value -- zero -- and you can add whatever value you want to it.</p>
|
||||
|
||||
<p>However, it's invalid to access (load from or store to) an LLVM-aware
|
||||
object with such a pointer. This includes GlobalVariables, Allocas, and
|
||||
objects pointed to by noalias pointers.</p>
|
||||
|
||||
<p>If you really need this functionality, you can do the arithmetic with
|
||||
explicit integer instructions, and use inttoptr to convert the result to
|
||||
an address. Most of GEP's special aliasing rules do not apply to pointers
|
||||
computed from ptrtoint, arithmetic, and inttoptr sequences.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- *********************************************************************** -->
|
||||
<div class="doc_subsection">
|
||||
<a name="lead0"><b>Can I compute the distance between two objects, and add
|
||||
that value to one address to compute the other address?</b></a>
|
||||
</div>
|
||||
<div class="doc_text">
|
||||
<p>As with arithmetic on null, You can use GEP to compute an address that
|
||||
way, but you can't use that pointer to actually access the object if you
|
||||
do, unless the object is managed outside of LLVM.</p>
|
||||
|
||||
<p>Also as above, ptrtoint and inttoptr provide an alternative way to do this
|
||||
which do not have this restriction.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- *********************************************************************** -->
|
||||
<div class="doc_subsection">
|
||||
<a name="lead0"><b>Can I do type-based alias analysis on LLVM IR?</b></a>
|
||||
</div>
|
||||
<div class="doc_text">
|
||||
<p>You can't do type-based alias analysis using LLVM's built-in type system,
|
||||
because LLVM has no restrictions on mixing types in addressing, loads or
|
||||
stores.</p>
|
||||
|
||||
<p>It would be possible to add special annotations to the IR, probably using
|
||||
metadata, to describe a different type system (such as the C type system),
|
||||
and do type-based aliasing on top of that. This is a much bigger
|
||||
undertaking though.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- *********************************************************************** -->
|
||||
|
||||
<div class="doc_subsection">
|
||||
<a name="lead0"><b>What's an uglygep?</b></a>
|
||||
</div>
|
||||
<div class="doc_text">
|
||||
<p>Some LLVM optimizers operate on GEPs by internally lowering them into
|
||||
more primitive integer expressions, which allows them to be combined
|
||||
with other integer expressions and/or split into multiple separate
|
||||
integer expressions. If they've made non-trivial changes, translating
|
||||
back into LLVM IR can involve reverse-engineering the structure of
|
||||
the addressing in order to fit it into the static type of the original
|
||||
first operand. It isn't always possibly to fully reconstruct this
|
||||
structure; sometimes the underlying addressing doesn't correspond with
|
||||
the static type at all. In such cases the optimizer instead will emit
|
||||
a GEP with the base pointer casted to a simple address-unit pointer,
|
||||
using the name "uglygep". This isn't pretty, but it's just as
|
||||
valid, and it's sufficient to preserve the pointer aliasing guarantees
|
||||
that GEP provides.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- *********************************************************************** -->
|
||||
|
||||
<div class="doc_subsection">
|
||||
<a name="lead0"><b>Can GEP index into vector elements?</b></a>
|
||||
</div>
|
||||
<div class="doc_text">
|
||||
<p>Sort of. This hasn't always been forcefully disallowed, though it's
|
||||
not recommended. It leads to awkward special cases in the optimizers.
|
||||
In the future, it may be outright disallowed.</p>
|
||||
|
||||
<p>Instead, you should cast your pointer types and use arrays instead of
|
||||
vectors for addressing. Arrays have the same in-memory representation
|
||||
as vectors, so the addressing is interchangeable.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- *********************************************************************** -->
|
||||
|
||||
<div class="doc_subsection">
|
||||
<a name="lead0"><b>Can GEP index into unions?</b></a>
|
||||
</div>
|
||||
<div class="doc_text">
|
||||
<p>Unknown.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- *********************************************************************** -->
|
||||
|
||||
<div class="doc_subsection">
|
||||
<a name="lead0"><b>What happens if a GEP computation overflows?</b></a>
|
||||
</div>
|
||||
<div class="doc_text">
|
||||
<p>If the GEP has the <tt>inbounds</tt> keyword, the result value is
|
||||
undefined.</p>
|
||||
|
||||
<p>Otherwise, the result value is the result from evaluating the implied
|
||||
two's complement integer computation. However, since there's no
|
||||
guarantee of where an object will be allocated in the address space,
|
||||
such values have limited meaning.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- *********************************************************************** -->
|
||||
|
||||
<div class="doc_subsection">
|
||||
<a name="lead0"><b>What effect do address spaces have on GEPs?</b></a>
|
||||
</div>
|
||||
<div class="doc_text">
|
||||
<p>None, except that the address space qualifier on the first operand pointer
|
||||
type always matches the address space qualifier on the result type.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- *********************************************************************** -->
|
||||
|
||||
<div class="doc_subsection">
|
||||
<a name="lead0"><b>Why is GEP designed this way?</b></a>
|
||||
</div>
|
||||
<div class="doc_text">
|
||||
<p>The design of GEP has the following goals, in rough unofficial
|
||||
order of priority:</p>
|
||||
<ul>
|
||||
<li>Support C, C-like languages, and languages which can be
|
||||
conceptually lowered into C (this covers a lot).</li>
|
||||
<li>Support optimizations such as those that are common in
|
||||
C compilers.</li>
|
||||
<li>Provide a consistent method for computing addresses so that
|
||||
address computations don't need to be a part of load and
|
||||
store instructions in the IR.</li>
|
||||
<li>Support non-C-like languages, to the extent that it doesn't
|
||||
interfere with other goals.</li>
|
||||
<li>Minimize target-specific information in the IR.</li>
|
||||
</ul>
|
||||
</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">The LLVM Compiler Infrastructure</a><br/>
|
||||
Last modified: $Date: 2010-02-18 19:40:29 +0100 (Thu, 18 Feb 2010) $
|
||||
</address>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -403,7 +403,7 @@ implementing, you just override the interfaces you can improve.</p>
|
||||
href="#basic-aa">basicaa</a></tt> and <a href="#no-aa"><tt>no-aa</tt></a>
|
||||
passes) every alias analysis pass chains to another alias analysis
|
||||
implementation (for example, the user can specify "<tt>-basicaa -ds-aa
|
||||
-anders-aa -licm</tt>" to get the maximum benefit from the three alias
|
||||
-licm</tt>" to get the maximum benefit from both alias
|
||||
analyses). The alias analysis class automatically takes care of most of this
|
||||
for methods that you don't override. For methods that you do override, in code
|
||||
paths that return a conservative MayAlias or Mod/Ref result, simply return
|
||||
@ -703,25 +703,6 @@ loads and stores to be eliminated.</p>
|
||||
non-address taken globals), but is very quick analysis.</p>
|
||||
</div>
|
||||
|
||||
<!-- _______________________________________________________________________ -->
|
||||
<div class="doc_subsubsection">
|
||||
<a name="anders-aa">The <tt>-anders-aa</tt> pass</a>
|
||||
</div>
|
||||
|
||||
<div class="doc_text">
|
||||
|
||||
<p>The <tt>-anders-aa</tt> pass implements the well-known "Andersen's algorithm"
|
||||
for interprocedural alias analysis. This algorithm is a subset-based,
|
||||
flow-insensitive, context-insensitive, and field-insensitive alias analysis that
|
||||
is widely believed to be fairly precise. Unfortunately, this algorithm is also
|
||||
O(N<sup>3</sup>). The LLVM implementation currently does not implement any of
|
||||
the refinements (such as "online cycle elimination" or "offline variable
|
||||
substitution") to improve its efficiency, so it can be quite slow in common
|
||||
cases.
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- _______________________________________________________________________ -->
|
||||
<div class="doc_subsubsection">
|
||||
<a name="steens-aa">The <tt>-steens-aa</tt> pass</a>
|
||||
@ -855,7 +836,7 @@ pointer.</p>
|
||||
<div class="doc_text">
|
||||
|
||||
<p>These passes are useful for evaluating the various alias analysis
|
||||
implementations. You can use them with commands like '<tt>opt -anders-aa -ds-aa
|
||||
implementations. You can use them with commands like '<tt>opt -ds-aa
|
||||
-aa-eval foo.bc -disable-output -stats</tt>'.</p>
|
||||
|
||||
</div>
|
||||
@ -949,7 +930,7 @@ analysis directly.</p>
|
||||
|
||||
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
|
||||
<a href="http://llvm.org">LLVM Compiler Infrastructure</a><br>
|
||||
Last modified: $Date: 2009-11-22 17:01:44 +0100 (Sun, 22 Nov 2009) $
|
||||
Last modified: $Date: 2010-03-01 20:24:17 +0100 (Mon, 01 Mar 2010) $
|
||||
</address>
|
||||
|
||||
</body>
|
||||
|
@ -1041,9 +1041,9 @@ ret
|
||||
|
||||
<div class="doc_code">
|
||||
<pre>
|
||||
%t1 = add float %W, %X
|
||||
%t2 = mul float %t1, %Y
|
||||
%t3 = add float %t2, %Z
|
||||
%t1 = fadd float %W, %X
|
||||
%t2 = fmul float %t1, %Y
|
||||
%t3 = fadd float %t2, %Z
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
@ -2116,7 +2116,7 @@ MOVSX32rm16 -> 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: 2010-01-11 19:53:47 +0100 (Mon, 11 Jan 2010) $
|
||||
Last modified: $Date: 2010-03-02 02:11:08 +0100 (Tue, 02 Mar 2010) $
|
||||
</address>
|
||||
|
||||
</body>
|
||||
|
@ -194,9 +194,9 @@ something sane goes a long ways towards avoiding writing documentation.</p>
|
||||
<b>Method information</b>
|
||||
|
||||
<p>Methods defined in a class (as well as any global functions) should also be
|
||||
documented properly. A quick note about what it does any a description of the
|
||||
documented properly. A quick note about what it does and a description of the
|
||||
borderline behaviour is all that is necessary here (unless something
|
||||
particularly tricky or insideous is going on). The hope is that people can
|
||||
particularly tricky or insidious is going on). The hope is that people can
|
||||
figure out how to use your interfaces without reading the code itself... that is
|
||||
the goal metric.</p>
|
||||
|
||||
@ -1346,7 +1346,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: 2009-10-12 16:46:08 +0200 (Mon, 12 Oct 2009) $
|
||||
Last modified: $Date: 2010-02-26 21:18:32 +0100 (Fri, 26 Feb 2010) $
|
||||
</address>
|
||||
|
||||
</body>
|
||||
|
@ -25,7 +25,7 @@ match. The file to verify is always read from standard input.
|
||||
|
||||
=over
|
||||
|
||||
=item B<--help>
|
||||
=item B<-help>
|
||||
|
||||
Print a summary of command line options.
|
||||
|
||||
|
@ -85,7 +85,7 @@ mis-management.
|
||||
Continually randomize the specified passes and run them on the test program
|
||||
until a bug is found or the user kills B<bugpoint>.
|
||||
|
||||
=item B<--help>
|
||||
=item B<-help>
|
||||
|
||||
Print a summary of command line options.
|
||||
|
||||
@ -99,9 +99,9 @@ it runs, to come from that file.
|
||||
Load the dynamic object F<plugin> into B<bugpoint> itself. This object should
|
||||
register new optimization passes. Once loaded, the object will add new command
|
||||
line options to enable various optimizations. To see the new complete list of
|
||||
optimizations, use the B<--help> and B<--load> options together; for example:
|
||||
optimizations, use the B<-help> and B<--load> options together; for example:
|
||||
|
||||
bugpoint --load myNewPass.so --help
|
||||
bugpoint --load myNewPass.so -help
|
||||
|
||||
=item B<--mlimit> F<megabytes>
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
for all of the LLVM tools. These pages describe how to use the LLVM commands
|
||||
and what their options are. Note that these pages do not describe all of the
|
||||
options available for all tools. To get a complete listing, pass the
|
||||
<tt>--help</tt> (general options) or <tt>--help-hidden</tt> (general+debugging
|
||||
<tt>-help</tt> (general options) or <tt>-help-hidden</tt> (general+debugging
|
||||
options) arguments to the tool you are interested in.</p>
|
||||
|
||||
</div>
|
||||
@ -148,7 +148,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: 2009-10-19 05:54:13 +0200 (Mon, 19 Oct 2009) $
|
||||
Last modified: $Date: 2010-02-18 15:08:13 +0100 (Thu, 18 Feb 2010) $
|
||||
</address>
|
||||
|
||||
</body>
|
||||
|
@ -38,7 +38,7 @@ Other B<llc> options are as follows:
|
||||
|
||||
=over
|
||||
|
||||
=item B<--help>
|
||||
=item B<-help>
|
||||
|
||||
Print a summary of command line options.
|
||||
|
||||
@ -56,7 +56,7 @@ string.
|
||||
=item B<-march>=I<arch>
|
||||
|
||||
Specify the architecture for which to generate assembly, overriding the target
|
||||
encoded in the input file. See the output of B<llc --help> for a list of
|
||||
encoded in the input file. See the output of B<llc -help> for a list of
|
||||
valid architectures. By default this is inferred from the target triple or
|
||||
autodetected to the current architecture.
|
||||
|
||||
|
@ -73,7 +73,7 @@ architecture which is not compatible with the current system.
|
||||
=item B<-march>=I<arch>
|
||||
|
||||
Specify the architecture for which to generate assembly, overriding the target
|
||||
encoded in the bitcode file. See the output of B<llc --help> for a list of
|
||||
encoded in the bitcode file. See the output of B<llc -help> for a list of
|
||||
valid architectures. By default this is inferred from the target triple or
|
||||
autodetected to the current architecture.
|
||||
|
||||
@ -170,7 +170,7 @@ Instruction schedulers available (before register allocation):
|
||||
|
||||
=item B<-regalloc>=I<allocator>
|
||||
|
||||
Register allocator to use: (default = linearscan)
|
||||
Register allocator to use (default=linearscan)
|
||||
|
||||
=bigblock: Big-block register allocator
|
||||
=linearscan: linear scan register allocator =local - local register allocator
|
||||
@ -186,7 +186,7 @@ Choose relocation model from:
|
||||
|
||||
=item B<-spiller>
|
||||
|
||||
Spiller to use: (default: local)
|
||||
Spiller to use (default=local)
|
||||
|
||||
=simple: simple spiller
|
||||
=local: local spiller
|
||||
|
@ -50,7 +50,7 @@ Enable binary output on terminals. Normally, B<llvm-as> will refuse to
|
||||
write raw bitcode output if the output stream is a terminal. With this option,
|
||||
B<llvm-as> will write raw bitcode regardless of the output device.
|
||||
|
||||
=item B<--help>
|
||||
=item B<-help>
|
||||
|
||||
Print a summary of command line options.
|
||||
|
||||
|
@ -43,7 +43,7 @@ Causes B<llvm-bcanalyzer> to verify the module produced by reading the
|
||||
bitcode. This ensures that the statistics generated are based on a consistent
|
||||
module.
|
||||
|
||||
=item B<--help>
|
||||
=item B<-help>
|
||||
|
||||
Print a summary of command line options.
|
||||
|
||||
|
@ -30,7 +30,7 @@ To link against the JIT:
|
||||
|
||||
Print the version number of LLVM.
|
||||
|
||||
=item B<--help>
|
||||
=item B<-help>
|
||||
|
||||
Print a summary of B<llvm-config> arguments.
|
||||
|
||||
|
@ -33,7 +33,7 @@ Enable binary output on terminals. Normally, B<llvm-dis> will refuse to
|
||||
write raw bitcode output if the output stream is a terminal. With this option,
|
||||
B<llvm-dis> will write raw bitcode regardless of the output device.
|
||||
|
||||
=item B<--help>
|
||||
=item B<-help>
|
||||
|
||||
Print a summary of command line options.
|
||||
|
||||
|
@ -42,7 +42,7 @@ specified multiple times to extract multiple functions at once.
|
||||
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<--help>
|
||||
=item B<-help>
|
||||
|
||||
Print a summary of command line options.
|
||||
|
||||
|
@ -51,7 +51,7 @@ Write output in LLVM intermediate language (instead of bitcode).
|
||||
If specified, B<llvm-link> prints a human-readable version of the output
|
||||
bitcode file to standard error.
|
||||
|
||||
=item B<--help>
|
||||
=item B<-help>
|
||||
|
||||
Print a summary of command line options.
|
||||
|
||||
|
@ -77,7 +77,7 @@ Use POSIX.2 output format. Alias for B<--format=posix>.
|
||||
|
||||
Use BSD output format. Alias for B<--format=bsd>.
|
||||
|
||||
=item B<--help>
|
||||
=item B<-help>
|
||||
|
||||
Print a summary of command-line options and their meanings.
|
||||
|
||||
|
@ -18,7 +18,7 @@ where the program hotspots are.
|
||||
This program is often used in conjunction with the F<utils/profile.pl>
|
||||
script. This script automatically instruments a program, runs it with the JIT,
|
||||
then runs B<llvm-prof> to format a report. To get more information about
|
||||
F<utils/profile.pl>, execute it with the B<--help> option.
|
||||
F<utils/profile.pl>, execute it with the B<-help> option.
|
||||
|
||||
=head1 OPTIONS
|
||||
|
||||
|
@ -6,7 +6,7 @@ llvm-ranlib - Generate index for LLVM archive
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
B<llvm-ranlib> [--version] [--help] <archive-file>
|
||||
B<llvm-ranlib> [--version] [-help] <archive-file>
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
@ -30,7 +30,7 @@ Specifies the archive-file to which the symbol table is added or updated.
|
||||
|
||||
Print the version of B<llvm-ranlib> and exit without building a symbol table.
|
||||
|
||||
=item F<--help>
|
||||
=item F<-help>
|
||||
|
||||
Print usage help for B<llvm-ranlib> and exit without building a symbol table.
|
||||
|
||||
|
@ -77,11 +77,11 @@ 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>
|
||||
=item B<-help>
|
||||
|
||||
Print a summary of command-line options and exit.
|
||||
|
||||
=item B<--help-hidden>
|
||||
=item B<-help-hidden>
|
||||
|
||||
Print a summary of command-line options and exit. Print help even for
|
||||
options intended for developers.
|
||||
|
@ -26,7 +26,7 @@ to read as input.
|
||||
|
||||
=over
|
||||
|
||||
=item B<--help>
|
||||
=item B<-help>
|
||||
|
||||
Print a summary of command line options.
|
||||
|
||||
|
@ -44,7 +44,7 @@
|
||||
|
||||
<li><a href="#modifiers">Option Modifiers</a>
|
||||
<ul>
|
||||
<li><a href="#hiding">Hiding an option from <tt>--help</tt>
|
||||
<li><a href="#hiding">Hiding an option from <tt>-help</tt>
|
||||
output</a></li>
|
||||
<li><a href="#numoccurrences">Controlling the number of occurrences
|
||||
required and allowed</a></li>
|
||||
@ -161,7 +161,7 @@ you declare it. <a href="#customparser">Custom parsers</a> are no problem.</li>
|
||||
|
||||
<li>Labor Saving: The CommandLine library cuts down on the amount of grunt work
|
||||
that you, the user, have to do. For example, it automatically provides a
|
||||
<tt>--help</tt> option that shows the available command line options for your
|
||||
<tt>-help</tt> option that shows the available command line options for your
|
||||
tool. Additionally, it does most of the basic correctness checking for
|
||||
you.</li>
|
||||
|
||||
@ -239,14 +239,14 @@ href="#list">"<tt>cl::list</tt> template</a>), and tell the CommandLine library
|
||||
that the data type that we are parsing is a string.</p>
|
||||
|
||||
<p>The second and third parameters (which are optional) are used to specify what
|
||||
to output for the "<tt>--help</tt>" option. In this case, we get a line that
|
||||
to output for the "<tt>-help</tt>" option. In this case, we get a line that
|
||||
looks like this:</p>
|
||||
|
||||
<div class="doc_code"><pre>
|
||||
USAGE: compiler [options]
|
||||
|
||||
OPTIONS:
|
||||
-help - display available options (--help-hidden for more)
|
||||
-help - display available options (-help-hidden for more)
|
||||
<b>-o <filename> - Specify output filename</b>
|
||||
</pre></div>
|
||||
|
||||
@ -308,14 +308,14 @@ the CommandLine library will automatically issue an error if the argument is not
|
||||
specified, which shifts all of the command line option verification code out of
|
||||
your application into the library. This is just one example of how using flags
|
||||
can alter the default behaviour of the library, on a per-option basis. By
|
||||
adding one of the declarations above, the <tt>--help</tt> option synopsis is now
|
||||
adding one of the declarations above, the <tt>-help</tt> option synopsis is now
|
||||
extended to:</p>
|
||||
|
||||
<div class="doc_code"><pre>
|
||||
USAGE: compiler [options] <b><input file></b>
|
||||
|
||||
OPTIONS:
|
||||
-help - display available options (--help-hidden for more)
|
||||
-help - display available options (-help-hidden for more)
|
||||
-o <filename> - Specify output filename
|
||||
</pre></div>
|
||||
|
||||
@ -346,8 +346,8 @@ declaring options of boolean type like this:</p>
|
||||
("<tt>Force</tt>", "<tt>Quiet</tt>", and "<tt>Quiet2</tt>") to recognize these
|
||||
options. Note that the "<tt>-q</tt>" option is specified with the "<a
|
||||
href="#cl::Hidden"><tt>cl::Hidden</tt></a>" flag. This modifier prevents it
|
||||
from being shown by the standard "<tt>--help</tt>" output (note that it is still
|
||||
shown in the "<tt>--help-hidden</tt>" output).</p>
|
||||
from being shown by the standard "<tt>-help</tt>" output (note that it is still
|
||||
shown in the "<tt>-help-hidden</tt>" output).</p>
|
||||
|
||||
<p>The CommandLine library uses a <a href="#builtinparsers">different parser</a>
|
||||
for different data types. For example, in the string case, the argument passed
|
||||
@ -372,7 +372,7 @@ href="#doubleparser">double</a>, and <a href="#intparser">int</a> parsers work
|
||||
like you would expect, using the '<tt>strtol</tt>' and '<tt>strtod</tt>' C
|
||||
library calls to parse the string value into the specified data type.</p>
|
||||
|
||||
<p>With the declarations above, "<tt>compiler --help</tt>" emits this:</p>
|
||||
<p>With the declarations above, "<tt>compiler -help</tt>" emits this:</p>
|
||||
|
||||
<div class="doc_code"><pre>
|
||||
USAGE: compiler [options] <input file>
|
||||
@ -381,10 +381,10 @@ OPTIONS:
|
||||
<b>-f - Enable binary output on terminals</b>
|
||||
-o - Override output filename
|
||||
<b>-quiet - Don't print informational messages</b>
|
||||
-help - display available options (--help-hidden for more)
|
||||
-help - display available options (-help-hidden for more)
|
||||
</pre></div>
|
||||
|
||||
<p>and "<tt>compiler --help-hidden</tt>" prints this:</p>
|
||||
<p>and "<tt>compiler -help-hidden</tt>" prints this:</p>
|
||||
|
||||
<div class="doc_code"><pre>
|
||||
USAGE: compiler [options] <input file>
|
||||
@ -394,7 +394,7 @@ OPTIONS:
|
||||
-o - Override output filename
|
||||
<b>-q - Don't print informational messages</b>
|
||||
-quiet - Don't print informational messages
|
||||
-help - display available options (--help-hidden for more)
|
||||
-help - display available options (-help-hidden for more)
|
||||
</pre></div>
|
||||
|
||||
<p>This brief example has shown you how to use the '<tt><a
|
||||
@ -438,7 +438,7 @@ the <tt><a href="#cl::aliasopt">cl::aliasopt</a></tt> modifier) whenever it is
|
||||
specified. Because aliases do not hold state, the only thing the program has to
|
||||
query is the <tt>Quiet</tt> variable now. Another nice feature of aliases is
|
||||
that they automatically hide themselves from the <tt>-help</tt> output
|
||||
(although, again, they are still visible in the <tt>--help-hidden
|
||||
(although, again, they are still visible in the <tt>-help-hidden
|
||||
output</tt>).</p>
|
||||
|
||||
<p>Now the application code can simply use:</p>
|
||||
@ -531,7 +531,7 @@ OPTIONS:
|
||||
-O2 - Enable default optimizations
|
||||
-O3 - Enable expensive optimizations</b>
|
||||
-f - Enable binary output on terminals
|
||||
-help - display available options (--help-hidden for more)
|
||||
-help - display available options (-help-hidden for more)
|
||||
-o <filename> - Specify output filename
|
||||
-quiet - Don't print informational messages
|
||||
</pre></div>
|
||||
@ -599,7 +599,7 @@ enum DebugLev {
|
||||
<p>This definition defines an enumerated command line variable of type "<tt>enum
|
||||
DebugLev</tt>", which works exactly the same way as before. The difference here
|
||||
is just the interface exposed to the user of your program and the help output by
|
||||
the "<tt>--help</tt>" option:</p>
|
||||
the "<tt>-help</tt>" option:</p>
|
||||
|
||||
<div class="doc_code"><pre>
|
||||
USAGE: compiler [options] <input file>
|
||||
@ -615,7 +615,7 @@ OPTIONS:
|
||||
=quick - enable quick debug information
|
||||
=detailed - enable detailed debug information</b>
|
||||
-f - Enable binary output on terminals
|
||||
-help - display available options (--help-hidden for more)
|
||||
-help - display available options (-help-hidden for more)
|
||||
-o <filename> - Specify output filename
|
||||
-quiet - Don't print informational messages
|
||||
</pre></div>
|
||||
@ -706,7 +706,7 @@ checking we have to do.</p>
|
||||
<div class="doc_text">
|
||||
|
||||
<p>Instead of collecting sets of options in a list, it is also possible to
|
||||
gather information for enum values in a <b>bit vector</b>. The represention used by
|
||||
gather information for enum values in a <b>bit vector</b>. The representation used by
|
||||
the <a href="#bits"><tt>cl::bits</tt></a> class is an <tt>unsigned</tt>
|
||||
integer. An enum value is represented by a 0/1 in the enum's ordinal value bit
|
||||
position. 1 indicating that the enum was specified, 0 otherwise. As each
|
||||
@ -794,7 +794,7 @@ USAGE: compiler [options] <input file>
|
||||
|
||||
OPTIONS:
|
||||
...
|
||||
-help - display available options (--help-hidden for more)
|
||||
-help - display available options (-help-hidden for more)
|
||||
-o <filename> - Specify output filename
|
||||
</pre></div>
|
||||
|
||||
@ -835,14 +835,14 @@ Using the CommandLine library, this would be specified as:</p>
|
||||
<a href="#cl::opt">cl::opt</a><string> Filename(<a href="#cl::Positional">cl::Positional</a>, <a href="#cl::desc">cl::desc</a>("<i><input file></i>"), <a href="#cl::init">cl::init</a>("<i>-</i>"));
|
||||
</pre></div>
|
||||
|
||||
<p>Given these two option declarations, the <tt>--help</tt> output for our grep
|
||||
<p>Given these two option declarations, the <tt>-help</tt> output for our grep
|
||||
replacement would look like this:</p>
|
||||
|
||||
<div class="doc_code"><pre>
|
||||
USAGE: spiffygrep [options] <b><regular expression> <input file></b>
|
||||
|
||||
OPTIONS:
|
||||
-help - display available options (--help-hidden for more)
|
||||
-help - display available options (-help-hidden for more)
|
||||
</pre></div>
|
||||
|
||||
<p>... and the resultant program could be used just like the standard
|
||||
@ -872,7 +872,7 @@ Note that the system <tt>grep</tt> has the same problem:</p>
|
||||
|
||||
<div class="doc_code"><pre>
|
||||
$ spiffygrep '-foo' test.txt
|
||||
Unknown command line argument '-foo'. Try: spiffygrep --help'
|
||||
Unknown command line argument '-foo'. Try: spiffygrep -help'
|
||||
|
||||
$ grep '-foo' test.txt
|
||||
grep: illegal option -- f
|
||||
@ -986,7 +986,7 @@ shell itself. Using the CommandLine library, we would specify this as:</p>
|
||||
USAGE: spiffysh [options] <b><input script> <program arguments>...</b>
|
||||
|
||||
OPTIONS:
|
||||
-help - display available options (--help-hidden for more)
|
||||
-help - display available options (-help-hidden for more)
|
||||
<b>-x - Enable trace output</b>
|
||||
</pre></div>
|
||||
|
||||
@ -1098,11 +1098,11 @@ This option is specified in simple double quotes:
|
||||
</li>
|
||||
|
||||
<li><a name="cl::desc">The <b><tt>cl::desc</tt></b></a> attribute specifies a
|
||||
description for the option to be shown in the <tt>--help</tt> output for the
|
||||
description for the option to be shown in the <tt>-help</tt> output for the
|
||||
program.</li>
|
||||
|
||||
<li><a name="cl::value_desc">The <b><tt>cl::value_desc</tt></b></a> attribute
|
||||
specifies a string that can be used to fine tune the <tt>--help</tt> output for
|
||||
specifies a string that can be used to fine tune the <tt>-help</tt> output for
|
||||
a command line option. Look <a href="#value_desc_example">here</a> for an
|
||||
example.</li>
|
||||
|
||||
@ -1130,7 +1130,7 @@ the string-to-value mapping to be used by the generic parser. It takes a
|
||||
<b>clEnumValEnd terminated</b> list of (option, value, description) triplets
|
||||
that
|
||||
specify the option name, the value mapped to, and the description shown in the
|
||||
<tt>--help</tt> for the tool. Because the generic parser is used most
|
||||
<tt>-help</tt> for the tool. Because the generic parser is used most
|
||||
frequently with enum values, two macros are often useful:
|
||||
|
||||
<ol>
|
||||
@ -1175,13 +1175,13 @@ obviously).</li>
|
||||
<p>Option modifiers are the flags and expressions that you pass into the
|
||||
constructors for <tt><a href="#cl::opt">cl::opt</a></tt> and <tt><a
|
||||
href="#cl::list">cl::list</a></tt>. These modifiers give you the ability to
|
||||
tweak how options are parsed and how <tt>--help</tt> output is generated to fit
|
||||
tweak how options are parsed and how <tt>-help</tt> output is generated to fit
|
||||
your application well.</p>
|
||||
|
||||
<p>These options fall into five main categories:</p>
|
||||
|
||||
<ol>
|
||||
<li><a href="#hiding">Hiding an option from <tt>--help</tt> output</a></li>
|
||||
<li><a href="#hiding">Hiding an option from <tt>-help</tt> output</a></li>
|
||||
<li><a href="#numoccurrences">Controlling the number of occurrences
|
||||
required and allowed</a></li>
|
||||
<li><a href="#valrequired">Controlling whether or not a value must be
|
||||
@ -1200,14 +1200,14 @@ usually shouldn't have to worry about these.</p>
|
||||
|
||||
<!-- _______________________________________________________________________ -->
|
||||
<div class="doc_subsubsection">
|
||||
<a name="hiding">Hiding an option from <tt>--help</tt> output</a>
|
||||
<a name="hiding">Hiding an option from <tt>-help</tt> output</a>
|
||||
</div>
|
||||
|
||||
<div class="doc_text">
|
||||
|
||||
<p>The <tt>cl::NotHidden</tt>, <tt>cl::Hidden</tt>, and
|
||||
<tt>cl::ReallyHidden</tt> modifiers are used to control whether or not an option
|
||||
appears in the <tt>--help</tt> and <tt>--help-hidden</tt> output for the
|
||||
appears in the <tt>-help</tt> and <tt>-help-hidden</tt> output for the
|
||||
compiled program:</p>
|
||||
|
||||
<ul>
|
||||
@ -1219,8 +1219,8 @@ in both help listings.</li>
|
||||
|
||||
<li><a name="cl::Hidden">The <b><tt>cl::Hidden</tt></b></a> modifier (which is the
|
||||
default for <tt><a href="#cl::alias">cl::alias</a></tt> options) indicates that
|
||||
the option should not appear in the <tt>--help</tt> output, but should appear in
|
||||
the <tt>--help-hidden</tt> output.</li>
|
||||
the option should not appear in the <tt>-help</tt> output, but should appear in
|
||||
the <tt>-help-hidden</tt> output.</li>
|
||||
|
||||
<li><a name="cl::ReallyHidden">The <b><tt>cl::ReallyHidden</tt></b></a> modifier
|
||||
indicates that the option should not appear in any help output.</li>
|
||||
@ -1508,7 +1508,7 @@ available.</p>
|
||||
<p>The <tt>cl::ParseCommandLineOptions</tt> function requires two parameters
|
||||
(<tt>argc</tt> and <tt>argv</tt>), but may also take an optional third parameter
|
||||
which holds <a href="#description">additional extra text</a> to emit when the
|
||||
<tt>--help</tt> option is invoked, and a fourth boolean parameter that enables
|
||||
<tt>-help</tt> option is invoked, and a fourth boolean parameter that enables
|
||||
<a href="#response">response files</a>.</p>
|
||||
|
||||
</div>
|
||||
@ -1535,7 +1535,7 @@ does.</p>
|
||||
not be available, it can't just look in <tt>argv[0]</tt>), the name of the
|
||||
environment variable to examine, the optional
|
||||
<a href="#description">additional extra text</a> to emit when the
|
||||
<tt>--help</tt> option is invoked, and the boolean
|
||||
<tt>-help</tt> option is invoked, and the boolean
|
||||
switch that controls whether <a href="#response">response files</a>
|
||||
should be read.</p>
|
||||
|
||||
@ -1689,7 +1689,7 @@ the conversion from string to data.</p>
|
||||
<div class="doc_text">
|
||||
|
||||
<p>The <tt>cl::extrahelp</tt> class is a nontemplated class that allows extra
|
||||
help text to be printed out for the <tt>--help</tt> option.</p>
|
||||
help text to be printed out for the <tt>-help</tt> option.</p>
|
||||
|
||||
<div class="doc_code"><pre>
|
||||
<b>namespace</b> cl {
|
||||
@ -1906,7 +1906,7 @@ MFS(<i>"max-file-size"</i>, <a href="#cl::desc">cl::desc</a>(<i>"Maximum file si
|
||||
|
||||
<div class="doc_code"><pre>
|
||||
OPTIONS:
|
||||
-help - display available options (--help-hidden for more)
|
||||
-help - display available options (-help-hidden for more)
|
||||
...
|
||||
<b>-max-file-size=<size> - Maximum file size to accept</b>
|
||||
</pre></div>
|
||||
@ -1972,7 +1972,7 @@ tutorial.</p>
|
||||
|
||||
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
|
||||
<a href="http://llvm.org">LLVM Compiler Infrastructure</a><br>
|
||||
Last modified: $Date: 2009-10-12 16:46:08 +0200 (Mon, 12 Oct 2009) $
|
||||
Last modified: $Date: 2010-02-26 21:18:32 +0100 (Fri, 26 Feb 2010) $
|
||||
</address>
|
||||
|
||||
</body>
|
||||
|
@ -132,7 +132,7 @@ 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 LLVMC
|
||||
plugins.</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
|
||||
<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>
|
||||
@ -325,7 +325,7 @@ aliased option name. Usage example: <tt class="docutils literal"><span class="pr
|
||||
<li><p class="first">Possible option properties:</p>
|
||||
<blockquote>
|
||||
<ul class="simple">
|
||||
<li><tt class="docutils literal"><span class="pre">help</span></tt> - help string associated with this option. Used for <tt class="docutils literal"><span class="pre">--help</span></tt>
|
||||
<li><tt class="docutils literal"><span class="pre">help</span></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"><span class="pre">required</span></tt> - this option must be specified exactly once (or, in case of
|
||||
the list options without the <tt class="docutils literal"><span class="pre">multi_val</span></tt> property, at least
|
||||
@ -338,7 +338,7 @@ it is synonymous with <tt class="docutils literal"><span class="pre">required</s
|
||||
for list options in conjunction with <tt class="docutils literal"><span class="pre">multi_val</span></tt>. Incompatible with
|
||||
<tt class="docutils literal"><span class="pre">required</span></tt> and <tt class="docutils literal"><span class="pre">one_or_more</span></tt>.</li>
|
||||
<li><tt class="docutils literal"><span class="pre">hidden</span></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>
|
||||
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"><span class="pre">really_hidden</span></tt> - the option will not be mentioned in any help
|
||||
output.</li>
|
||||
@ -748,7 +748,7 @@ the <tt class="docutils literal"><span class="pre">Base</span></tt> plugin behav
|
||||
<a href="mailto:foldr@codedgers.com">Mikhail Glushenkov</a><br />
|
||||
<a href="http://llvm.org">LLVM Compiler Infrastructure</a><br />
|
||||
|
||||
Last modified: $Date: 2009-12-23 13:49:51 +0100 (Wed, 23 Dec 2009) $
|
||||
Last modified: $Date: 2010-02-18 15:08:13 +0100 (Thu, 18 Feb 2010) $
|
||||
</address></div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -520,7 +520,7 @@ Changes</a></div>
|
||||
<p>We intend to keep LLVM perpetually open source and to use a liberal open
|
||||
source license. The current license is the
|
||||
<a href="http://www.opensource.org/licenses/UoI-NCSA.php">University of
|
||||
llinois/NCSA Open Source License</a>, which boils down to this:</p>
|
||||
Illinois/NCSA Open Source License</a>, which boils down to this:</p>
|
||||
|
||||
<ul>
|
||||
<li>You can freely distribute LLVM.</li>
|
||||
@ -601,7 +601,7 @@ Changes</a></div>
|
||||
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: 2009-10-10 23:37:16 +0200 (Sat, 10 Oct 2009) $
|
||||
Last modified: $Date: 2010-02-26 21:18:32 +0100 (Fri, 26 Feb 2010) $
|
||||
</address>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -437,7 +437,7 @@ Stop.
|
||||
<div class="answer">
|
||||
<p>The <tt>GNUmakefile</tt> in the top-level directory of LLVM-GCC is a special
|
||||
<tt>Makefile</tt> used by Apple to invoke the <tt>build_gcc</tt> script after
|
||||
setting up a special environment. This has the unforunate side-effect that
|
||||
setting up a special environment. This has the unfortunate side-effect that
|
||||
trying to build LLVM-GCC with srcdir == objdir in a "non-Apple way" invokes
|
||||
the <tt>GNUmakefile</tt> instead of <tt>Makefile</tt>. Because the
|
||||
environment isn't set up correctly to do this, the build fails.</p>
|
||||
@ -931,7 +931,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: 2009-10-12 16:46:08 +0200 (Mon, 12 Oct 2009) $
|
||||
Last modified: $Date: 2010-02-26 00:41:41 +0100 (Fri, 26 Feb 2010) $
|
||||
</address>
|
||||
|
||||
</body>
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
<ol>
|
||||
<li><a href="#intro">Introduction</a></li>
|
||||
<li><a href="#questions">The Questions</a>
|
||||
<li><a href="#addresses">Address Computation</a>
|
||||
<ol>
|
||||
<li><a href="#extra_index">Why is the extra 0 index required?</a></li>
|
||||
<li><a href="#deref">What is dereferenced by GEP?</a></li>
|
||||
@ -25,6 +25,30 @@
|
||||
subsequent ones?</a></li>
|
||||
<li><a href="#lead0">Why don't GEP x,0,0,1 and GEP x,1 alias? </a></li>
|
||||
<li><a href="#trail0">Why do GEP x,1,0,0 and GEP x,1 alias? </a></li>
|
||||
<li><a href="#vectors">Can GEP index into vector elements?</a>
|
||||
<li><a href="#unions">Can GEP index into unions?</a>
|
||||
<li><a href="#addrspace">What effect do address spaces have on GEPs?</a>
|
||||
<li><a href="#int">How is GEP different from ptrtoint, arithmetic, and inttoptr?</a></li>
|
||||
<li><a href="#be">I'm writing a backend for a target which needs custom lowering for GEP. How do I do this?</a>
|
||||
<li><a href="#vla">How does VLA addressing work with GEPs?</a>
|
||||
</ol></li>
|
||||
<li><a href="#rules">Rules</a>
|
||||
<ol>
|
||||
<li><a href="#bounds">What happens if an array index is out of bounds?</a>
|
||||
<li><a href="#negative">Can array indices be negative?</a>
|
||||
<li><a href="#compare">Can I compare two values computed with GEPs?</a>
|
||||
<li><a href="#types">Can I do GEP with a different pointer type than the type of the underlying object?</a>
|
||||
<li><a href="#null">Can I cast an object's address to integer and add it to null?</a>
|
||||
<li><a href="#ptrdiff">Can I compute the distance between two objects, and add that value to one address to compute the other address?</a>
|
||||
<li><a href="#tbaa">Can I do type-based alias analysis on LLVM IR?</a>
|
||||
<li><a href="#overflow">What happens if a GEP computation overflows?</a>
|
||||
<li><a href="#check">How can I tell if my front-end is following the rules?</a>
|
||||
</ol></li>
|
||||
<li><a href="#rationale">Rationale</a>
|
||||
<ol>
|
||||
<li><a href="#goals">Why is GEP designed this way?</a></li>
|
||||
<li><a href="#i32">Why do struct member indices always use i32?</a></li>
|
||||
<li><a href="#uglygep">What's an uglygep?</a>
|
||||
</ol></li>
|
||||
<li><a href="#summary">Summary</a></li>
|
||||
</ol>
|
||||
@ -37,9 +61,10 @@
|
||||
<!-- *********************************************************************** -->
|
||||
<div class="doc_section"><a name="intro"><b>Introduction</b></a></div>
|
||||
<!-- *********************************************************************** -->
|
||||
|
||||
<div class="doc_text">
|
||||
<p>This document seeks to dispel the mystery and confusion surrounding LLVM's
|
||||
GetElementPtr (GEP) instruction. Questions about the wiley GEP instruction are
|
||||
GetElementPtr (GEP) instruction. Questions about the wily GEP instruction are
|
||||
probably the most frequently occurring questions once a developer gets down to
|
||||
coding with LLVM. Here we lay out the sources of confusion and show that the
|
||||
GEP instruction is really quite simple.
|
||||
@ -47,22 +72,14 @@
|
||||
</div>
|
||||
|
||||
<!-- *********************************************************************** -->
|
||||
<div class="doc_section"><a name="questions"><b>The Questions</b></a></div>
|
||||
<div class="doc_section"><a name="addresses"><b>Address Computation</b></a></div>
|
||||
<!-- *********************************************************************** -->
|
||||
<div class="doc_text">
|
||||
<p>When people are first confronted with the GEP instruction, they tend to
|
||||
relate it to known concepts from other programming paradigms, most notably C
|
||||
array indexing and field selection. However, GEP is a little different and
|
||||
this leads to the following questions; all of which are answered in the
|
||||
following sections.</p>
|
||||
<ol>
|
||||
<li><a href="#firstptr">What is the first index of the GEP instruction?</a>
|
||||
</li>
|
||||
<li><a href="#extra_index">Why is the extra 0 index required?</a></li>
|
||||
<li><a href="#deref">What is dereferenced by GEP?</a></li>
|
||||
<li><a href="#lead0">Why don't GEP x,0,0,1 and GEP x,1 alias? </a></li>
|
||||
<li><a href="#trail0">Why do GEP x,1,0,0 and GEP x,1 alias? </a></li>
|
||||
</ol>
|
||||
array indexing and field selection. GEP closely resembles C array indexing
|
||||
and field selection, however it's is a little different and this leads to
|
||||
the following questions.</p>
|
||||
</div>
|
||||
|
||||
<!-- *********************************************************************** -->
|
||||
@ -85,7 +102,7 @@ X = &Foo->F;
|
||||
|
||||
<p>it is natural to think that there is only one index, the selection of the
|
||||
field <tt>F</tt>. However, in this example, <tt>Foo</tt> is a pointer. That
|
||||
pointer must be indexed explicitly in LLVM. C, on the other hand, indexs
|
||||
pointer must be indexed explicitly in LLVM. C, on the other hand, indices
|
||||
through it transparently. To arrive at the same address location as the C
|
||||
code, you would provide the GEP instruction with two index operands. The
|
||||
first operand indexes through the pointer; the second operand indexes the
|
||||
@ -155,7 +172,7 @@ entry:
|
||||
|
||||
<div class="doc_code">
|
||||
<pre>
|
||||
%MyVar = unintialized global i32
|
||||
%MyVar = uninitialized global i32
|
||||
...
|
||||
%idx1 = getelementptr i32* %MyVar, i64 0
|
||||
%idx2 = getelementptr i32* %MyVar, i64 1
|
||||
@ -210,7 +227,7 @@ idx3 = (char*) &MyVar + 8
|
||||
field of the structure <tt>%MyStruct</tt>. When people first look at it, they
|
||||
wonder why the <tt>i64 0</tt> index is needed. However, a closer inspection
|
||||
of how globals and GEPs work reveals the need. Becoming aware of the following
|
||||
facts will dispell the confusion:</p>
|
||||
facts will dispel the confusion:</p>
|
||||
<ol>
|
||||
<li>The type of <tt>%MyStruct</tt> is <i>not</i> <tt>{ float*, i32 }</tt>
|
||||
but rather <tt>{ float*, i32 }*</tt>. That is, <tt>%MyStruct</tt> is a
|
||||
@ -297,8 +314,8 @@ idx3 = (char*) &MyVar + 8
|
||||
<div class="doc_code">
|
||||
<pre>
|
||||
%MyVar = global { [10 x i32 ] }
|
||||
%idx1 = getlementptr { [10 x i32 ] }* %MyVar, i64 0, i32 0, i64 1
|
||||
%idx2 = getlementptr { [10 x i32 ] }* %MyVar, i64 1
|
||||
%idx1 = getelementptr { [10 x i32 ] }* %MyVar, i64 0, i32 0, i64 1
|
||||
%idx2 = getelementptr { [10 x i32 ] }* %MyVar, i64 1
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
@ -326,8 +343,8 @@ idx3 = (char*) &MyVar + 8
|
||||
<div class="doc_code">
|
||||
<pre>
|
||||
%MyVar = global { [10 x i32 ] }
|
||||
%idx1 = getlementptr { [10 x i32 ] }* %MyVar, i64 1, i32 0, i64 0
|
||||
%idx2 = getlementptr { [10 x i32 ] }* %MyVar, i64 1
|
||||
%idx1 = getelementptr { [10 x i32 ] }* %MyVar, i64 1, i32 0, i64 0
|
||||
%idx2 = getelementptr { [10 x i32 ] }* %MyVar, i64 1
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
@ -336,6 +353,352 @@ idx3 = (char*) &MyVar + 8
|
||||
<tt>MyVar+40</tt> but its type is <tt>{ [10 x i32] }*</tt>.</p>
|
||||
</div>
|
||||
|
||||
<!-- *********************************************************************** -->
|
||||
|
||||
<div class="doc_subsection">
|
||||
<a name="vectors"><b>Can GEP index into vector elements?</b></a>
|
||||
</div>
|
||||
<div class="doc_text">
|
||||
<p>This hasn't always been forcefully disallowed, though it's not recommended.
|
||||
It leads to awkward special cases in the optimizers, and fundamental
|
||||
inconsistency in the IR. In the future, it will probably be outright
|
||||
disallowed.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- *********************************************************************** -->
|
||||
|
||||
<div class="doc_subsection">
|
||||
<a name="unions"><b>Can GEP index into unions?</b></a>
|
||||
</div>
|
||||
<div class="doc_text">
|
||||
<p>Unknown.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- *********************************************************************** -->
|
||||
|
||||
<div class="doc_subsection">
|
||||
<a name="addrspace"><b>What effect do address spaces have on GEPs?</b></a>
|
||||
</div>
|
||||
<div class="doc_text">
|
||||
<p>None, except that the address space qualifier on the first operand pointer
|
||||
type always matches the address space qualifier on the result type.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- *********************************************************************** -->
|
||||
|
||||
<div class="doc_subsection">
|
||||
<a name="int"><b>How is GEP different from ptrtoint, arithmetic,
|
||||
and inttoptr?</b></a>
|
||||
</div>
|
||||
<div class="doc_text">
|
||||
<p>It's very similar; there are only subtle differences.</p>
|
||||
|
||||
<p>With ptrtoint, you have to pick an integer type. One approach is to pick i64;
|
||||
this is safe on everything LLVM supports (LLVM internally assumes pointers
|
||||
are never wider than 64 bits in many places), and the optimizer will actually
|
||||
narrow the i64 arithmetic down to the actual pointer size on targets which
|
||||
don't support 64-bit arithmetic in most cases. However, there are some cases
|
||||
where it doesn't do this. With GEP you can avoid this problem.
|
||||
|
||||
<p>Also, GEP carries additional pointer aliasing rules. It's invalid to take a
|
||||
GEP from one object, address into a different separately allocated
|
||||
object, and dereference it. IR producers (front-ends) must follow this rule,
|
||||
and consumers (optimizers, specifically alias analysis) benefit from being
|
||||
able to rely on it. See the <a href="#rules">Rules</a> section for more
|
||||
information.</p>
|
||||
|
||||
<p>And, GEP is more concise in common cases.</p>
|
||||
|
||||
<p>However, for the underlying integer computation implied, there
|
||||
is no difference.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- *********************************************************************** -->
|
||||
|
||||
<div class="doc_subsection">
|
||||
<a name="be"><b>I'm writing a backend for a target which needs custom
|
||||
lowering for GEP. How do I do this?</b></a>
|
||||
</div>
|
||||
<div class="doc_text">
|
||||
<p>You don't. The integer computation implied by a GEP is target-independent.
|
||||
Typically what you'll need to do is make your backend pattern-match
|
||||
expressions trees involving ADD, MUL, etc., which are what GEP is lowered
|
||||
into. This has the advantage of letting your code work correctly in more
|
||||
cases.</p>
|
||||
|
||||
<p>GEP does use target-dependent parameters for the size and layout of data
|
||||
types, which targets can customize.</p>
|
||||
|
||||
<p>If you require support for addressing units which are not 8 bits, you'll
|
||||
need to fix a lot of code in the backend, with GEP lowering being only a
|
||||
small piece of the overall picture.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- *********************************************************************** -->
|
||||
|
||||
<div class="doc_subsection">
|
||||
<a name="vla"><b>How does VLA addressing work with GEPs?</b></a>
|
||||
</div>
|
||||
<div class="doc_text">
|
||||
<p>GEPs don't natively support VLAs. LLVM's type system is entirely static,
|
||||
and GEP address computations are guided by an LLVM type.</p>
|
||||
|
||||
<p>VLA indices can be implemented as linearized indices. For example, an
|
||||
expression like X[a][b][c], must be effectively lowered into a form
|
||||
like X[a*m+b*n+c], so that it appears to the GEP as a single-dimensional
|
||||
array reference.</p>
|
||||
|
||||
<p>This means if you want to write an analysis which understands array
|
||||
indices and you want to support VLAs, your code will have to be
|
||||
prepared to reverse-engineer the linearization. One way to solve this
|
||||
problem is to use the ScalarEvolution library, which always presents
|
||||
VLA and non-VLA indexing in the same manner.</p>
|
||||
</div>
|
||||
|
||||
<!-- *********************************************************************** -->
|
||||
<div class="doc_section"><a name="rules"><b>Rules</b></a></div>
|
||||
<!-- *********************************************************************** -->
|
||||
|
||||
<!-- *********************************************************************** -->
|
||||
|
||||
<div class="doc_subsection">
|
||||
<a name="bounds"><b>What happens if an array index is out of bounds?</b></a>
|
||||
</div>
|
||||
<div class="doc_text">
|
||||
<p>There are two senses in which an array index can be out of bounds.</p>
|
||||
|
||||
<p>First, there's the array type which comes from the (static) type of
|
||||
the first operand to the GEP. Indices greater than the number of elements
|
||||
in the corresponding static array type are valid. There is no problem with
|
||||
out of bounds indices in this sense. Indexing into an array only depends
|
||||
on the size of the array element, not the number of elements.</p>
|
||||
|
||||
<p>A common example of how this is used is arrays where the size is not known.
|
||||
It's common to use array types with zero length to represent these. The
|
||||
fact that the static type says there are zero elements is irrelevant; it's
|
||||
perfectly valid to compute arbitrary element indices, as the computation
|
||||
only depends on the size of the array element, not the number of
|
||||
elements. Note that zero-sized arrays are not a special case here.</p>
|
||||
|
||||
<p>This sense is unconnected with <tt>inbounds</tt> keyword. The
|
||||
<tt>inbounds</tt> keyword is designed to describe low-level pointer
|
||||
arithmetic overflow conditions, rather than high-level array
|
||||
indexing rules.
|
||||
|
||||
<p>Analysis passes which wish to understand array indexing should not
|
||||
assume that the static array type bounds are respected.</p>
|
||||
|
||||
<p>The second sense of being out of bounds is computing an address that's
|
||||
beyond the actual underlying allocated object.</p>
|
||||
|
||||
<p>With the <tt>inbounds</tt> keyword, the result value of the GEP is
|
||||
undefined if the address is outside the actual underlying allocated
|
||||
object and not the address one-past-the-end.</p>
|
||||
|
||||
<p>Without the <tt>inbounds</tt> keyword, there are no restrictions
|
||||
on computing out-of-bounds addresses. Obviously, performing a load or
|
||||
a store requires an address of allocated and sufficiently aligned
|
||||
memory. But the GEP itself is only concerned with computing addresses.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- *********************************************************************** -->
|
||||
<div class="doc_subsection">
|
||||
<a name="negative"><b>Can array indices be negative?</b></a>
|
||||
</div>
|
||||
<div class="doc_text">
|
||||
<p>Yes. This is basically a special case of array indices being out
|
||||
of bounds.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- *********************************************************************** -->
|
||||
<div class="doc_subsection">
|
||||
<a name="compare"><b>Can I compare two values computed with GEPs?</b></a>
|
||||
</div>
|
||||
<div class="doc_text">
|
||||
<p>Yes. If both addresses are within the same allocated object, or
|
||||
one-past-the-end, you'll get the comparison result you expect. If either
|
||||
is outside of it, integer arithmetic wrapping may occur, so the
|
||||
comparison may not be meaningful.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- *********************************************************************** -->
|
||||
<div class="doc_subsection">
|
||||
<a name="types"><b>Can I do GEP with a different pointer type than the type of
|
||||
the underlying object?</b></a>
|
||||
</div>
|
||||
<div class="doc_text">
|
||||
<p>Yes. There are no restrictions on bitcasting a pointer value to an arbitrary
|
||||
pointer type. The types in a GEP serve only to define the parameters for the
|
||||
underlying integer computation. They need not correspond with the actual
|
||||
type of the underlying object.</p>
|
||||
|
||||
<p>Furthermore, loads and stores don't have to use the same types as the type
|
||||
of the underlying object. Types in this context serve only to specify
|
||||
memory size and alignment. Beyond that there are merely a hint to the
|
||||
optimizer indicating how the value will likely be used.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- *********************************************************************** -->
|
||||
<div class="doc_subsection">
|
||||
<a name="null"><b>Can I cast an object's address to integer and add it
|
||||
to null?</b></a>
|
||||
</div>
|
||||
<div class="doc_text">
|
||||
<p>You can compute an address that way, but if you use GEP to do the add,
|
||||
you can't use that pointer to actually access the object, unless the
|
||||
object is managed outside of LLVM.</p>
|
||||
|
||||
<p>The underlying integer computation is sufficiently defined; null has a
|
||||
defined value -- zero -- and you can add whatever value you want to it.</p>
|
||||
|
||||
<p>However, it's invalid to access (load from or store to) an LLVM-aware
|
||||
object with such a pointer. This includes GlobalVariables, Allocas, and
|
||||
objects pointed to by noalias pointers.</p>
|
||||
|
||||
<p>If you really need this functionality, you can do the arithmetic with
|
||||
explicit integer instructions, and use inttoptr to convert the result to
|
||||
an address. Most of GEP's special aliasing rules do not apply to pointers
|
||||
computed from ptrtoint, arithmetic, and inttoptr sequences.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- *********************************************************************** -->
|
||||
<div class="doc_subsection">
|
||||
<a name="ptrdiff"><b>Can I compute the distance between two objects, and add
|
||||
that value to one address to compute the other address?</b></a>
|
||||
</div>
|
||||
<div class="doc_text">
|
||||
<p>As with arithmetic on null, You can use GEP to compute an address that
|
||||
way, but you can't use that pointer to actually access the object if you
|
||||
do, unless the object is managed outside of LLVM.</p>
|
||||
|
||||
<p>Also as above, ptrtoint and inttoptr provide an alternative way to do this
|
||||
which do not have this restriction.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- *********************************************************************** -->
|
||||
<div class="doc_subsection">
|
||||
<a name="tbaa"><b>Can I do type-based alias analysis on LLVM IR?</b></a>
|
||||
</div>
|
||||
<div class="doc_text">
|
||||
<p>You can't do type-based alias analysis using LLVM's built-in type system,
|
||||
because LLVM has no restrictions on mixing types in addressing, loads or
|
||||
stores.</p>
|
||||
|
||||
<p>It would be possible to add special annotations to the IR, probably using
|
||||
metadata, to describe a different type system (such as the C type system),
|
||||
and do type-based aliasing on top of that. This is a much bigger
|
||||
undertaking though.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- *********************************************************************** -->
|
||||
|
||||
<div class="doc_subsection">
|
||||
<a name="overflow"><b>What happens if a GEP computation overflows?</b></a>
|
||||
</div>
|
||||
<div class="doc_text">
|
||||
<p>If the GEP has the <tt>inbounds</tt> keyword, the result value is
|
||||
undefined.</p>
|
||||
|
||||
<p>Otherwise, the result value is the result from evaluating the implied
|
||||
two's complement integer computation. However, since there's no
|
||||
guarantee of where an object will be allocated in the address space,
|
||||
such values have limited meaning.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- *********************************************************************** -->
|
||||
|
||||
<div class="doc_subsection">
|
||||
<a name="check"><b>How can I tell if my front-end is following the
|
||||
rules?</b></a>
|
||||
</div>
|
||||
<div class="doc_text">
|
||||
<p>There is currently no checker for the getelementptr rules. Currently,
|
||||
the only way to do this is to manually check each place in your front-end
|
||||
where GetElementPtr operators are created.</p>
|
||||
|
||||
<p>It's not possible to write a checker which could find all rule
|
||||
violations statically. It would be possible to write a checker which
|
||||
works by instrumenting the code with dynamic checks though. Alternatively,
|
||||
it would be possible to write a static checker which catches a subset of
|
||||
possible problems. However, no such checker exists today.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- *********************************************************************** -->
|
||||
<div class="doc_section"><a name="rationale"><b>Rationale</b></a></div>
|
||||
<!-- *********************************************************************** -->
|
||||
|
||||
<!-- *********************************************************************** -->
|
||||
|
||||
<div class="doc_subsection">
|
||||
<a name="goals"><b>Why is GEP designed this way?</b></a>
|
||||
</div>
|
||||
<div class="doc_text">
|
||||
<p>The design of GEP has the following goals, in rough unofficial
|
||||
order of priority:</p>
|
||||
<ul>
|
||||
<li>Support C, C-like languages, and languages which can be
|
||||
conceptually lowered into C (this covers a lot).</li>
|
||||
<li>Support optimizations such as those that are common in
|
||||
C compilers.</li>
|
||||
<li>Provide a consistent method for computing addresses so that
|
||||
address computations don't need to be a part of load and
|
||||
store instructions in the IR.</li>
|
||||
<li>Support non-C-like languages, to the extent that it doesn't
|
||||
interfere with other goals.</li>
|
||||
<li>Minimize target-specific information in the IR.</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- *********************************************************************** -->
|
||||
<div class="doc_subsection">
|
||||
<a name="i32"><b>Why do struct member indices always use i32?</b></a>
|
||||
</div>
|
||||
<div class="doc_text">
|
||||
<p>The specific type i32 is probably just a historical artifact, however it's
|
||||
wide enough for all practical purposes, so there's been no need to change it.
|
||||
It doesn't necessarily imply i32 address arithmetic; it's just an identifier
|
||||
which identifies a field in a struct. Requiring that all struct indices be
|
||||
the same reduces the range of possibilities for cases where two GEPs are
|
||||
effectively the same but have distinct operand types.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- *********************************************************************** -->
|
||||
|
||||
<div class="doc_subsection">
|
||||
<a name="uglygep"><b>What's an uglygep?</b></a>
|
||||
</div>
|
||||
<div class="doc_text">
|
||||
<p>Some LLVM optimizers operate on GEPs by internally lowering them into
|
||||
more primitive integer expressions, which allows them to be combined
|
||||
with other integer expressions and/or split into multiple separate
|
||||
integer expressions. If they've made non-trivial changes, translating
|
||||
back into LLVM IR can involve reverse-engineering the structure of
|
||||
the addressing in order to fit it into the static type of the original
|
||||
first operand. It isn't always possibly to fully reconstruct this
|
||||
structure; sometimes the underlying addressing doesn't correspond with
|
||||
the static type at all. In such cases the optimizer instead will emit
|
||||
a GEP with the base pointer casted to a simple address-unit pointer,
|
||||
using the name "uglygep". This isn't pretty, but it's just as
|
||||
valid, and it's sufficient to preserve the pointer aliasing guarantees
|
||||
that GEP provides.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- *********************************************************************** -->
|
||||
<div class="doc_section"><a name="summary"><b>Summary</b></a></div>
|
||||
<!-- *********************************************************************** -->
|
||||
@ -365,7 +728,7 @@ idx3 = (char*) &MyVar + 8
|
||||
<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">The LLVM Compiler Infrastructure</a><br/>
|
||||
Last modified: $Date: 2009-10-12 16:46:08 +0200 (Mon, 12 Oct 2009) $
|
||||
Last modified: $Date: 2010-02-25 19:16:03 +0100 (Thu, 25 Feb 2010) $
|
||||
</address>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -1193,10 +1193,16 @@ $ ./hello.bc
|
||||
</div>
|
||||
|
||||
<p>
|
||||
This allows you to execute LLVM bitcode files directly. Thanks to Jack
|
||||
Cummings for pointing this out!
|
||||
This allows you to execute LLVM bitcode files directly. On Debian, you
|
||||
can also use this command instead of the 'echo' command above:</p>
|
||||
</p>
|
||||
|
||||
<div class="doc_code">
|
||||
<pre>
|
||||
$ sudo update-binfmts --install llvm /path/to/lli --magic 'BC'
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- *********************************************************************** -->
|
||||
@ -1363,7 +1369,7 @@ end to compile.</p>
|
||||
|
||||
<p>The <b>tools</b> directory contains the executables built out of the
|
||||
libraries above, which form the main part of the user interface. You can
|
||||
always get help for a tool by typing <tt>tool_name --help</tt>. The
|
||||
always get help for a tool by typing <tt>tool_name -help</tt>. The
|
||||
following is a brief introduction to the most important tools. More detailed
|
||||
information is in the <a href="CommandGuide/index.html">Command Guide</a>.</p>
|
||||
|
||||
@ -1434,7 +1440,7 @@ information is in the <a href="CommandGuide/index.html">Command Guide</a>.</p>
|
||||
<dt><tt><b>opt</b></tt></dt>
|
||||
<dd><tt>opt</tt> reads LLVM bitcode, applies a series of LLVM to LLVM
|
||||
transformations (which are specified on the command line), and then outputs
|
||||
the resultant bitcode. The '<tt>opt --help</tt>' command is a good way to
|
||||
the resultant bitcode. The '<tt>opt -help</tt>' command is a good way to
|
||||
get a list of the program transformations available in LLVM.<br>
|
||||
<dd><tt>opt</tt> can also be used to run a specific analysis on an input
|
||||
LLVM bitcode file and print out the results. It is primarily useful for
|
||||
@ -1667,7 +1673,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: 2010-02-11 22:51:51 +0100 (Thu, 11 Feb 2010) $
|
||||
Last modified: $Date: 2010-02-18 15:08:13 +0100 (Thu, 18 Feb 2010) $
|
||||
</address>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -848,7 +848,7 @@ define i32 @main() { <i>; i32()* </i>
|
||||
|
||||
<div class="doc_text">
|
||||
|
||||
<p>LLVM function definitions consist of the "<tt>define</tt>" keyord, an
|
||||
<p>LLVM function definitions consist of the "<tt>define</tt>" keyword, an
|
||||
optional <a href="#linkage">linkage type</a>, an optional
|
||||
<a href="#visibility">visibility style</a>, an optional
|
||||
<a href="#callingconv">calling convention</a>, a return type, an optional
|
||||
@ -1277,7 +1277,7 @@ target datalayout = "<i>layout specification</i>"
|
||||
|
||||
<ul>
|
||||
<li><tt>E</tt> - big endian</li>
|
||||
<li><tt>p:32:64:64</tt> - 32-bit pointers with 64-bit alignment</li>
|
||||
<li><tt>p:64:64:64</tt> - 64-bit pointers with 64-bit alignment</li>
|
||||
<li><tt>i1:8:8</tt> - i1 is 8-bit (byte) aligned</li>
|
||||
<li><tt>i8:8:8</tt> - i8 is 8-bit (byte) aligned</li>
|
||||
<li><tt>i16:16:16</tt> - i16 is 16-bit aligned</li>
|
||||
@ -1664,7 +1664,7 @@ Classifications</a> </div>
|
||||
which indicates that the function takes a variable number of arguments.
|
||||
Variable argument functions can access their arguments with
|
||||
the <a href="#int_varargs">variable argument handling intrinsic</a>
|
||||
functions. '<tt><returntype></tt>' is a any type except
|
||||
functions. '<tt><returntype></tt>' is any type except
|
||||
<a href="#t_label">label</a>.</p>
|
||||
|
||||
<h5>Examples:</h5>
|
||||
@ -1674,12 +1674,11 @@ Classifications</a> </div>
|
||||
<td class="left">function taking an <tt>i32</tt>, returning an <tt>i32</tt>
|
||||
</td>
|
||||
</tr><tr class="layout">
|
||||
<td class="left"><tt>float (i16 signext, i32 *) *
|
||||
<td class="left"><tt>float (i16, i32 *) *
|
||||
</tt></td>
|
||||
<td class="left"><a href="#t_pointer">Pointer</a> to a function that takes
|
||||
an <tt>i16</tt> that should be sign extended and a
|
||||
<a href="#t_pointer">pointer</a> to <tt>i32</tt>, returning
|
||||
<tt>float</tt>.
|
||||
an <tt>i16</tt> and a <a href="#t_pointer">pointer</a> to <tt>i32</tt>,
|
||||
returning <tt>float</tt>.
|
||||
</td>
|
||||
</tr><tr class="layout">
|
||||
<td class="left"><tt>i32 (i8*, ...)</tt></td>
|
||||
@ -1792,7 +1791,7 @@ Classifications</a> </div>
|
||||
and the alignment requirements of the union as a whole will be the largest
|
||||
alignment requirement of any member.</p>
|
||||
|
||||
<p>Unions members are accessed using '<tt><a href="#i_load">load</a></tt> and
|
||||
<p>Union members are accessed using '<tt><a href="#i_load">load</a></tt> and
|
||||
'<tt><a href="#i_store">store</a></tt>' by getting a pointer to a field with
|
||||
the '<tt><a href="#i_getelementptr">getelementptr</a></tt>' instruction.
|
||||
Since all members are at offset zero, the getelementptr instruction does
|
||||
@ -1827,10 +1826,13 @@ Classifications</a> </div>
|
||||
<div class="doc_text">
|
||||
|
||||
<h5>Overview:</h5>
|
||||
<p>As in many languages, the pointer type represents a pointer or reference to
|
||||
another object, which must live in memory. Pointer types may have an optional
|
||||
address space attribute defining the target-specific numbered address space
|
||||
where the pointed-to object resides. The default address space is zero.</p>
|
||||
<p>The pointer type is used to specify memory locations.
|
||||
Pointers are commonly used to reference objects in memory.</p>
|
||||
|
||||
<p>Pointer types may have an optional address space attribute defining the
|
||||
numbered address space where the pointed-to object resides. The default
|
||||
address space is number zero. The semantics of non-zero address
|
||||
spaces are target-specific.</p>
|
||||
|
||||
<p>Note that LLVM does not permit pointers to void (<tt>void*</tt>) nor does it
|
||||
permit pointers to labels (<tt>label*</tt>). Use <tt>i8*</tt> instead.</p>
|
||||
@ -2885,9 +2887,10 @@ IfUnequal:
|
||||
function to be invoked. </li>
|
||||
|
||||
<li>'<tt>function args</tt>': argument list whose types match the function
|
||||
signature argument types. If the function signature indicates the
|
||||
function accepts a variable number of arguments, the extra arguments can
|
||||
be specified.</li>
|
||||
signature argument types and parameter attributes. All arguments must be
|
||||
of <a href="#t_firstclass">first class</a> type. If the function
|
||||
signature indicates the function accepts a variable number of arguments,
|
||||
the extra arguments can be specified.</li>
|
||||
|
||||
<li>'<tt>normal label</tt>': the label reached when the called function
|
||||
executes a '<tt><a href="#i_ret">ret</a></tt>' instruction. </li>
|
||||
@ -4074,8 +4077,9 @@ Instruction</a> </div>
|
||||
|
||||
<h5>Syntax:</h5>
|
||||
<pre>
|
||||
<result> = load <ty>* <pointer>[, align <alignment>]
|
||||
<result> = volatile load <ty>* <pointer>[, align <alignment>]
|
||||
<result> = load <ty>* <pointer>[, align <alignment>][, !nontemporal !<index>]
|
||||
<result> = volatile load <ty>* <pointer>[, align <alignment>][, !nontemporal !<index>]
|
||||
!<index> = !{ i32 1 }
|
||||
</pre>
|
||||
|
||||
<h5>Overview:</h5>
|
||||
@ -4088,16 +4092,24 @@ Instruction</a> </div>
|
||||
marked as <tt>volatile</tt>, then the optimizer is not allowed to modify the
|
||||
number or order of execution of this <tt>load</tt> with other
|
||||
volatile <tt>load</tt> and <tt><a href="#i_store">store</a></tt>
|
||||
instructions. </p>
|
||||
instructions.</p>
|
||||
|
||||
<p>The optional constant "align" argument specifies the alignment of the
|
||||
<p>The optional constant <tt>align</tt> argument specifies the alignment of the
|
||||
operation (that is, the alignment of the memory address). A value of 0 or an
|
||||
omitted "align" argument means that the operation has the preferential
|
||||
omitted <tt>align</tt> argument means that the operation has the preferential
|
||||
alignment for the target. It is the responsibility of the code emitter to
|
||||
ensure that the alignment information is correct. Overestimating the
|
||||
alignment results in an undefined behavior. Underestimating the alignment may
|
||||
alignment results in undefined behavior. Underestimating the alignment may
|
||||
produce less efficient code. An alignment of 1 is always safe.</p>
|
||||
|
||||
<p>The optional <tt>!nontemporal</tt> metadata must reference a single
|
||||
metatadata name <index> corresponding to a metadata node with
|
||||
one <tt>i32</tt> entry of value 1. The existence of
|
||||
the <tt>!nontemporal</tt> metatadata on the instruction tells the optimizer
|
||||
and code generator that this load is not expected to be reused in the cache.
|
||||
The code generator may select special instructions to save cache bandwidth,
|
||||
such as the <tt>MOVNT</tt> instruction on x86.</p>
|
||||
|
||||
<h5>Semantics:</h5>
|
||||
<p>The location of memory pointed to is loaded. If the value being loaded is of
|
||||
scalar type then the number of bytes read does not exceed the minimum number
|
||||
@ -4124,8 +4136,8 @@ Instruction</a> </div>
|
||||
|
||||
<h5>Syntax:</h5>
|
||||
<pre>
|
||||
store <ty> <value>, <ty>* <pointer>[, align <alignment>] <i>; yields {void}</i>
|
||||
volatile store <ty> <value>, <ty>* <pointer>[, align <alignment>] <i>; yields {void}</i>
|
||||
store <ty> <value>, <ty>* <pointer>[, align <alignment>][, !nontemporal !<index>] <i>; yields {void}</i>
|
||||
volatile store <ty> <value>, <ty>* <pointer>[, align <alignment>][, !nontemporal !<index>] <i>; yields {void}</i>
|
||||
</pre>
|
||||
|
||||
<h5>Overview:</h5>
|
||||
@ -4150,6 +4162,15 @@ Instruction</a> </div>
|
||||
alignment results in an undefined behavior. Underestimating the alignment may
|
||||
produce less efficient code. An alignment of 1 is always safe.</p>
|
||||
|
||||
<p>The optional !nontemporal metadata must reference a single metatadata
|
||||
name <index> corresponding to a metadata node with one i32 entry of
|
||||
value 1. The existence of the !nontemporal metatadata on the
|
||||
instruction tells the optimizer and code generator that this load is
|
||||
not expected to be reused in the cache. The code generator may
|
||||
select special instructions to save cache bandwidth, such as the
|
||||
MOVNT instruction on x86.</p>
|
||||
|
||||
|
||||
<h5>Semantics:</h5>
|
||||
<p>The contents of memory are updated to contain '<tt><value></tt>' at the
|
||||
location specified by the '<tt><pointer></tt>' operand. If
|
||||
@ -4943,7 +4964,7 @@ entry:
|
||||
<tt>op1</tt> is equal to <tt>op2</tt>.</li>
|
||||
|
||||
<li><tt>ogt</tt>: yields <tt>true</tt> if both operands are not a QNAN and
|
||||
<tt>op1</tt> is greather than <tt>op2</tt>.</li>
|
||||
<tt>op1</tt> is greater than <tt>op2</tt>.</li>
|
||||
|
||||
<li><tt>oge</tt>: yields <tt>true</tt> if both operands are not a QNAN and
|
||||
<tt>op1</tt> is greater than or equal to <tt>op2</tt>.</li>
|
||||
@ -5119,7 +5140,7 @@ Loop: ; Infinite loop that counts from 0 on up...
|
||||
<li>The call is in tail position (ret immediately follows call and ret
|
||||
uses value of call or is void).</li>
|
||||
<li>Option <tt>-tailcallopt</tt> is enabled,
|
||||
or <code>llvm::PerformTailCallOpt</code> is <code>true</code>.</li>
|
||||
or <code>llvm::GuaranteedTailCallOpt</code> is <code>true</code>.</li>
|
||||
<li><a href="CodeGenerator.html#tailcallopt">Platform specific
|
||||
constraints are met.</a></li>
|
||||
</ul>
|
||||
@ -5150,10 +5171,10 @@ Loop: ; Infinite loop that counts from 0 on up...
|
||||
to function value.</li>
|
||||
|
||||
<li>'<tt>function args</tt>': argument list whose types match the function
|
||||
signature argument types. All arguments must be of
|
||||
<a href="#t_firstclass">first class</a> type. If the function signature
|
||||
indicates the function accepts a variable number of arguments, the extra
|
||||
arguments can be specified.</li>
|
||||
signature argument types and parameter attributes. All arguments must be
|
||||
of <a href="#t_firstclass">first class</a> type. If the function
|
||||
signature indicates the function accepts a variable number of arguments,
|
||||
the extra arguments can be specified.</li>
|
||||
|
||||
<li>The optional <a href="#fnattrs">function attributes</a> list. Only
|
||||
'<tt>noreturn</tt>', '<tt>nounwind</tt>', '<tt>readonly</tt>' and
|
||||
@ -5188,7 +5209,7 @@ Loop: ; Infinite loop that counts from 0 on up...
|
||||
standard C99 library as being the C99 library functions, and may perform
|
||||
optimizations or generate code for them under that assumption. This is
|
||||
something we'd like to change in the future to provide better support for
|
||||
freestanding environments and non-C-based langauges.</p>
|
||||
freestanding environments and non-C-based languages.</p>
|
||||
|
||||
</div>
|
||||
|
||||
@ -5744,7 +5765,7 @@ LLVM</a>.</p>
|
||||
|
||||
<h5>Semantics:</h5>
|
||||
<p>This intrinsic does not modify the behavior of the program. Backends that do
|
||||
not support this intrinisic may ignore it.</p>
|
||||
not support this intrinsic may ignore it.</p>
|
||||
|
||||
</div>
|
||||
|
||||
@ -5824,7 +5845,7 @@ LLVM</a>.</p>
|
||||
number of bytes to copy, and the fourth argument is the alignment of the
|
||||
source and destination locations.</p>
|
||||
|
||||
<p>If the call to this intrinisic has an alignment value that is not 0 or 1,
|
||||
<p>If the call to this intrinsic has an alignment value that is not 0 or 1,
|
||||
then the caller guarantees that both the source and destination pointers are
|
||||
aligned to that boundary.</p>
|
||||
|
||||
@ -5874,7 +5895,7 @@ LLVM</a>.</p>
|
||||
number of bytes to copy, and the fourth argument is the alignment of the
|
||||
source and destination locations.</p>
|
||||
|
||||
<p>If the call to this intrinisic has an alignment value that is not 0 or 1,
|
||||
<p>If the call to this intrinsic has an alignment value that is not 0 or 1,
|
||||
then the caller guarantees that the source and destination pointers are
|
||||
aligned to that boundary.</p>
|
||||
|
||||
@ -5922,7 +5943,7 @@ LLVM</a>.</p>
|
||||
specifying the number of bytes to fill, and the fourth argument is the known
|
||||
alignment of destination location.</p>
|
||||
|
||||
<p>If the call to this intrinisic has an alignment value that is not 0 or 1,
|
||||
<p>If the call to this intrinsic has an alignment value that is not 0 or 1,
|
||||
then the caller guarantees that the destination pointer is aligned to that
|
||||
boundary.</p>
|
||||
|
||||
@ -6693,7 +6714,7 @@ LLVM</a>.</p>
|
||||
<h5>Arguments:</h5>
|
||||
<p>The <tt>llvm.memory.barrier</tt> intrinsic requires five boolean arguments.
|
||||
The first four arguments enables a specific barrier as listed below. The
|
||||
fith argument specifies that the barrier applies to io or device or uncached
|
||||
fifth argument specifies that the barrier applies to io or device or uncached
|
||||
memory.</p>
|
||||
|
||||
<ul>
|
||||
@ -7432,7 +7453,7 @@ LLVM</a>.</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: 2010-02-12 21:49:41 +0100 (Fri, 12 Feb 2010) $
|
||||
Last modified: $Date: 2010-03-02 07:36:51 +0100 (Tue, 02 Mar 2010) $
|
||||
</address>
|
||||
|
||||
</body>
|
||||
|
@ -818,6 +818,10 @@
|
||||
<tt>mklib</tt> by the <tt>configure</tt> script and always located in the
|
||||
<dt><a name="LLVMAS"><tt>LLVMAS</tt></a><small>(defaulted)</small></dt>
|
||||
<dd>Specifies the path to the <tt>llvm-as</tt> tool.</dd>
|
||||
<dt><a name="LLVMCC"><tt>LLVMCC</tt></a></dt>
|
||||
<dd>Specifies the path to the LLVM capable compiler.</dd>
|
||||
<dt><a name="LLVMCXX"><tt>LLVMCXX</tt></a></dt>
|
||||
<dd>Specifies the path to the LLVM C++ capable compiler.</dd>
|
||||
<dt><a name="LLVMGCC"><tt>LLVMGCC</tt></a><small>(defaulted)</small></dt>
|
||||
<dd>Specifies the path to the LLVM version of the GCC 'C' Compiler</dd>
|
||||
<dt><a name="LLVMGXX"><tt>LLVMGXX</tt></a><small>(defaulted)</small></dt>
|
||||
@ -1021,7 +1025,7 @@
|
||||
|
||||
<a href="mailto:rspencer@x10sys.com">Reid Spencer</a><br>
|
||||
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br>
|
||||
Last modified: $Date: 2009-10-12 16:46:08 +0200 (Mon, 12 Oct 2009) $
|
||||
Last modified: $Date: 2010-02-23 11:00:53 +0100 (Tue, 23 Feb 2010) $
|
||||
</address>
|
||||
</body>
|
||||
</html>
|
||||
|
118
docs/Packaging.html
Normal file
118
docs/Packaging.html
Normal file
@ -0,0 +1,118 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
|
||||
"http://www.w3.org/TR/html4/strict.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<title>Advice on Packaging LLVM</title>
|
||||
<link rel="stylesheet" href="llvm.css" type="text/css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="doc_title">Advice on Packaging LLVM</div>
|
||||
<ol>
|
||||
<li><a href="#overview">Overview</a></li>
|
||||
<li><a href="#compilation">Compile Flags</a></li>
|
||||
<li><a href="#cxx-features">C++ Features</a></li>
|
||||
<li><a href="#shared-library">Shared Library</a></li>
|
||||
<li><a href="#deps">Dependencies</a></li>
|
||||
</ol>
|
||||
|
||||
<!--=========================================================================-->
|
||||
<div class="doc_section"><a name="overview">Overview</a></div>
|
||||
<!--=========================================================================-->
|
||||
<div class="doc_text">
|
||||
|
||||
<p>LLVM sets certain default configure options to make sure our developers don't
|
||||
break things for constrained platforms. These settings are not optimal for most
|
||||
desktop systems, and we hope that packagers (e.g., Redhat, Debian, MacPorts,
|
||||
etc.) will tweak them. This document lists settings we suggest you tweak.
|
||||
</p>
|
||||
|
||||
<p>LLVM's API changes with each release, so users are likely to want, for
|
||||
example, both LLVM-2.6 and LLVM-2.7 installed at the same time to support apps
|
||||
developed against each.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!--=========================================================================-->
|
||||
<div class="doc_section"><a name="compilation">Compile Flags</a></div>
|
||||
<!--=========================================================================-->
|
||||
<div class="doc_text">
|
||||
|
||||
<p>LLVM runs much more quickly when it's optimized and assertions are removed.
|
||||
However, such a build is currently incompatible with users who build without
|
||||
defining NDEBUG, and the lack of assertions makes it hard to debug problems in
|
||||
user code. We recommend allowing users to install both optimized and debug
|
||||
versions of LLVM in parallel. The following configure flags are relevant:
|
||||
</p>
|
||||
|
||||
<dl>
|
||||
<dt><tt>--disable-assertions</tt></dt><dd>Builds LLVM with <tt>NDEBUG</tt>
|
||||
defined. Changes the LLVM ABI. Also available by setting
|
||||
<tt>DISABLE_ASSERTIONS=0|1</tt> in <tt>make</tt>'s environment. This defaults
|
||||
to enabled regardless of the optimization setting, but it slows things
|
||||
down.</dd>
|
||||
|
||||
<dt><tt>--enable-debug-symbols</tt></dt><dd>Builds LLVM with <tt>-g</tt>.
|
||||
Also available by setting <tt>DEBUG_SYMBOLS=0|1</tt> in <tt>make</tt>'s
|
||||
environment. This defaults to disabled when optimizing, so you should turn it
|
||||
back on to let users debug their programs.</dd>
|
||||
|
||||
<dt><tt>--enable-optimized</tt></dt><dd>(For svn checkouts) Builds LLVM with
|
||||
<tt>-O2</tt> and, by default, turns off debug symbols. Also available by
|
||||
setting <tt>ENABLE_OPTIMIZED=0|1</tt> in <tt>make</tt>'s environment. This
|
||||
defaults to enabled when not in a checkout.</dd>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
<!--=========================================================================-->
|
||||
<div class="doc_section"><a name="cxx-features">C++ Features</a></div>
|
||||
<!--=========================================================================-->
|
||||
<div class="doc_text">
|
||||
|
||||
<dl>
|
||||
<dt>RTTI</dt><dd>LLVM disables RTTI by default. Add <tt>REQUIRES_RTTI=1</tt>
|
||||
to your environment while running <tt>make</tt> to re-enable it. This will
|
||||
allow users to build with RTTI enabled and still inherit from LLVM
|
||||
classes.</dd>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
<!--=========================================================================-->
|
||||
<div class="doc_section"><a name="shared-library">Shared Library</a></div>
|
||||
<!--=========================================================================-->
|
||||
<div class="doc_text">
|
||||
|
||||
<p>Configure with <tt>--enable-shared</tt> to build
|
||||
<tt>libLLVM-<var>major</var>.<var>minor</var>.(so|dylib)</tt> and link the tools
|
||||
against it. This saves lots of binary size at the cost of some startup time.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!--=========================================================================-->
|
||||
<div class="doc_section"><a name="deps">Dependencies</a></div>
|
||||
<!--=========================================================================-->
|
||||
<div class="doc_text">
|
||||
|
||||
<dl>
|
||||
<dt><tt>--enable-libffi</tt></dt><dd>Depend on <a
|
||||
href="http://sources.redhat.com/libffi/">libffi</a> to allow the LLVM
|
||||
interpreter to call external functions.</dd>
|
||||
<dt><tt>--with-oprofile</tt></dt><dd>Depend on <a
|
||||
href="http://oprofile.sourceforge.net/doc/devel/index.html">libopagent</a>
|
||||
(>=version 0.9.4) to let the LLVM JIT tell oprofile about function addresses and
|
||||
line numbers.</dd>
|
||||
</dl>
|
||||
</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">The LLVM Compiler Infrastructure</a><br>
|
||||
Last modified: $Date: 2010-02-26 23:25:06 +0100 (Fri, 26 Feb 2010) $
|
||||
</address>
|
||||
</body>
|
||||
</html>
|
@ -75,7 +75,6 @@ perl -e '$/ = undef; for (split(/\n/, <>)) { s:^ *///? ?::; print " <p>\n" if !
|
||||
<tr><th colspan="2"><b>ANALYSIS PASSES</b></th></tr>
|
||||
<tr><th>Option</th><th>Name</th></tr>
|
||||
<tr><td><a href="#aa-eval">-aa-eval</a></td><td>Exhaustive Alias Analysis Precision Evaluator</td></tr>
|
||||
<tr><td><a href="#anders-aa">-anders-aa</a></td><td>Andersen's Interprocedural Alias Analysis</td></tr>
|
||||
<tr><td><a href="#basicaa">-basicaa</a></td><td>Basic Alias Analysis (default AA impl)</td></tr>
|
||||
<tr><td><a href="#basiccg">-basiccg</a></td><td>Basic CallGraph Construction</td></tr>
|
||||
<tr><td><a href="#codegenprepare">-codegenprepare</a></td><td>Optimize for code generation</td></tr>
|
||||
@ -202,80 +201,6 @@ perl -e '$/ = undef; for (split(/\n/, <>)) { s:^ *///? ?::; print " <p>\n" if !
|
||||
Spadini, and Wojciech Stryjewski.</p>
|
||||
</div>
|
||||
|
||||
<!-------------------------------------------------------------------------- -->
|
||||
<div class="doc_subsection">
|
||||
<a name="anders-aa">Andersen's Interprocedural Alias Analysis</a>
|
||||
</div>
|
||||
<div class="doc_text">
|
||||
<p>
|
||||
This is an implementation of Andersen's interprocedural alias
|
||||
analysis
|
||||
</p>
|
||||
|
||||
<p>
|
||||
In pointer analysis terms, this is a subset-based, flow-insensitive,
|
||||
field-sensitive, and context-insensitive algorithm pointer algorithm.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
This algorithm is implemented as three stages:
|
||||
</p>
|
||||
|
||||
<ol>
|
||||
<li>Object identification.</li>
|
||||
<li>Inclusion constraint identification.</li>
|
||||
<li>Offline constraint graph optimization.</li>
|
||||
<li>Inclusion constraint solving.</li>
|
||||
</ol>
|
||||
|
||||
<p>
|
||||
The object identification stage identifies all of the memory objects in the
|
||||
program, which includes globals, heap allocated objects, and stack allocated
|
||||
objects.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The inclusion constraint identification stage finds all inclusion constraints
|
||||
in the program by scanning the program, looking for pointer assignments and
|
||||
other statements that effect the points-to graph. For a statement like
|
||||
<code><var>A</var> = <var>B</var></code>, this statement is processed to
|
||||
indicate that <var>A</var> can point to anything that <var>B</var> can point
|
||||
to. Constraints can handle copies, loads, and stores, and address taking.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The offline constraint graph optimization portion includes offline variable
|
||||
substitution algorithms intended to computer pointer and location
|
||||
equivalences. Pointer equivalences are those pointers that will have the
|
||||
same points-to sets, and location equivalences are those variables that
|
||||
always appear together in points-to sets.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The inclusion constraint solving phase iteratively propagates the inclusion
|
||||
constraints until a fixed point is reached. This is an O(<var>n</var>³)
|
||||
algorithm.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Function constraints are handled as if they were structs with <var>X</var>
|
||||
fields. Thus, an access to argument <var>X</var> of function <var>Y</var> is
|
||||
an access to node index <code>getNode(<var>Y</var>) + <var>X</var></code>.
|
||||
This representation allows handling of indirect calls without any issues. To
|
||||
wit, an indirect call <code><var>Y</var>(<var>a</var>,<var>b</var>)</code> is
|
||||
equivalent to <code>*(<var>Y</var> + 1) = <var>a</var>, *(<var>Y</var> + 2) =
|
||||
<var>b</var></code>. The return node for a function <var>F</var> is always
|
||||
located at <code>getNode(<var>F</var>) + CallReturnPos</code>. The arguments
|
||||
start at <code>getNode(<var>F</var>) + CallArgPos</code>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Please keep in mind that the current andersen's pass has many known
|
||||
problems and bugs. It should be considered "research quality".
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-------------------------------------------------------------------------- -->
|
||||
<div class="doc_subsection">
|
||||
<a name="basicaa">Basic Alias Analysis (default AA impl)</a>
|
||||
@ -1848,7 +1773,7 @@ if (X < 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: 2009-10-28 05:47:06 +0100 (Wed, 28 Oct 2009) $
|
||||
Last modified: $Date: 2010-03-01 20:24:17 +0100 (Mon, 01 Mar 2010) $
|
||||
</address>
|
||||
|
||||
</body>
|
||||
|
@ -525,7 +525,7 @@ lightweight <a href="http://en.wikipedia.org/wiki/Rope_(computer_science)">rope<
|
||||
which points to temporary (stack allocated) objects. Twines can be implicitly
|
||||
constructed as the result of the plus operator applied to strings (i.e., a C
|
||||
strings, an <tt>std::string</tt>, or a <tt>StringRef</tt>). The twine delays the
|
||||
actual concatentation of strings until it is actually required, at which point
|
||||
actual concatenation of strings until it is actually required, at which point
|
||||
it can be efficiently rendered directly into a character array. This avoids
|
||||
unnecessary heap allocation involved in constructing the temporary results of
|
||||
string concatenation. See
|
||||
@ -1098,7 +1098,7 @@ in the default manner.</p>
|
||||
</div>
|
||||
|
||||
<div class="doc_text">
|
||||
<p><tt>ilist</tt>s have another speciality that must be considered. To be a good
|
||||
<p><tt>ilist</tt>s have another specialty that must be considered. To be a good
|
||||
citizen in the C++ ecosystem, it needs to support the standard container
|
||||
operations, such as <tt>begin</tt> and <tt>end</tt> iterators, etc. Also, the
|
||||
<tt>operator--</tt> must work correctly on the <tt>end</tt> iterator in the
|
||||
@ -3921,7 +3921,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: 2010-02-15 17:12:20 +0100 (Mon, 15 Feb 2010) $
|
||||
Last modified: $Date: 2010-02-26 00:51:27 +0100 (Fri, 26 Feb 2010) $
|
||||
</address>
|
||||
|
||||
</body>
|
||||
|
@ -451,6 +451,8 @@ release includes a few major enhancements and additions to the optimizers:</p>
|
||||
|
||||
</ul>
|
||||
|
||||
<p>Also, -anders-aa was removed</p>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
@ -644,6 +646,10 @@ Clients must replace calls to
|
||||
<li>The <tt>llvm/Support/DataTypes.h</tt> header has moved
|
||||
to <tt>llvm/System/DataTypes.h</tt>.</li>
|
||||
|
||||
<li>The <tt>isInteger</tt>, <tt>isIntOrIntVector</tt>, <tt>isFloatingPoint</tt>,
|
||||
<tt>isFPOrFPVector</tt> and <tt>isFPOrFPVector</tt> methods have been renamed
|
||||
<tt>isIntegerTy</tt>, <tt>isIntOrIntVectorTy</tt>, <tt>isFloatingPointTy</tt>,
|
||||
<tt>isFPOrFPVectorTy</tt> and <tt>isFPOrFPVectorTy</tt> respectively.</li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
@ -729,7 +735,6 @@ href="http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev">LLVMdev list</a>.</p>
|
||||
experimental.</li>
|
||||
<li>The <tt>llc</tt> "<tt>-filetype=asm</tt>" (the default) is the only
|
||||
supported value for this option. The ELF writer is experimental.</li>
|
||||
<li>The implementation of Andersen's Alias Analysis has many known bugs.</li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
@ -992,7 +997,7 @@ lists</a>.</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: 2010-02-14 02:47:19 +0100 (Sun, 14 Feb 2010) $
|
||||
Last modified: $Date: 2010-03-01 20:29:17 +0100 (Mon, 01 Mar 2010) $
|
||||
</address>
|
||||
|
||||
</body>
|
||||
|
@ -155,7 +155,6 @@ file prints this (at the time of this writing):</p>
|
||||
<b>bit</b> hasCtrlDep = 0;
|
||||
<b>bit</b> isNotDuplicable = 0;
|
||||
<b>bit</b> hasSideEffects = 0;
|
||||
<b>bit</b> mayHaveSideEffects = 0;
|
||||
<b>bit</b> neverHasSideEffects = 0;
|
||||
InstrItinClass Itinerary = NoItinerary;
|
||||
<b>string</b> Constraints = "";
|
||||
@ -189,7 +188,7 @@ backend, and is only shown as an example.</p>
|
||||
|
||||
<p>As you can see, a lot of information is needed for every instruction
|
||||
supported by the code generator, and specifying it all manually would be
|
||||
unmaintainble, prone to bugs, and tiring to do in the first place. Because we
|
||||
unmaintainable, prone to bugs, and tiring to do in the first place. Because we
|
||||
are using TableGen, all of the information was derived from the following
|
||||
definition:</p>
|
||||
|
||||
@ -798,7 +797,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: 2010-01-05 20:11:42 +0100 (Tue, 05 Jan 2010) $
|
||||
Last modified: $Date: 2010-02-28 00:47:46 +0100 (Sun, 28 Feb 2010) $
|
||||
</address>
|
||||
|
||||
</body>
|
||||
|
@ -693,8 +693,6 @@ that FileCheck is not actually line-oriented when it matches, this allows you to
|
||||
define two separate CHECK lines that match on the same line.
|
||||
</p>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<!-- _______________________________________________________________________ -->
|
||||
@ -761,12 +759,6 @@ substitutions</a></div>
|
||||
<dd>The full path to the <tt>llvm-gxx</tt> executable as specified in the
|
||||
configured LLVM environment</dd>
|
||||
|
||||
<dt><b>llvmgcc_version</b> (%llvmgcc_version)</dt>
|
||||
<dd>The full version number of the <tt>llvm-gcc</tt> executable.</dd>
|
||||
|
||||
<dt><b>llvmgccmajvers</b> (%llvmgccmajvers)</dt>
|
||||
<dd>The major version number of the <tt>llvm-gcc</tt> executable.</dd>
|
||||
|
||||
<dt><b>gccpath</b></dt>
|
||||
<dd>The full path to the C compiler used to <i>build </i> LLVM. Note that
|
||||
this might not be gcc.</dd>
|
||||
@ -824,22 +816,20 @@ substitutions</a></div>
|
||||
</dl>
|
||||
|
||||
<p>Sometimes it is necessary to mark a test case as "expected fail" or XFAIL.
|
||||
You can easily mark a test as XFAIL just by including <tt>XFAIL: </tt> on a
|
||||
You can easily mark a test as XFAIL just by including <tt>XFAIL: </tt> on a
|
||||
line near the top of the file. This signals that the test case should succeed
|
||||
if the test fails. Such test cases are counted separately by DejaGnu. To
|
||||
specify an expected fail, use the XFAIL keyword in the comments of the test
|
||||
program followed by a colon and one or more regular expressions (separated by
|
||||
a comma). The regular expressions allow you to XFAIL the test conditionally
|
||||
by host platform. The regular expressions following the : are matched against
|
||||
the target triplet or llvmgcc version number for the host machine. If there is
|
||||
a match, the test is expected to fail. If not, the test is expected to
|
||||
succeed. To XFAIL everywhere just specify <tt>XFAIL: *</tt>. When matching
|
||||
the llvm-gcc version, you can specify the major (e.g. 3) or full version
|
||||
(i.e. 3.4) number. Here is an example of an <tt>XFAIL</tt> line:</p>
|
||||
a comma). The regular expressions allow you to XFAIL the test conditionally by
|
||||
host platform. The regular expressions following the : are matched against the
|
||||
target triplet for the host machine. If there is a match, the test is expected
|
||||
to fail. If not, the test is expected to succeed. To XFAIL everywhere just
|
||||
specify <tt>XFAIL: *</tt>. Here is an example of an <tt>XFAIL</tt> line:</p>
|
||||
|
||||
<div class="doc_code">
|
||||
<pre>
|
||||
; XFAIL: darwin,sun,llvmgcc4
|
||||
; XFAIL: darwin,sun
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
@ -1145,7 +1135,6 @@ example reports that can do fancy stuff.</p>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!--=========================================================================-->
|
||||
<div class="doc_section"><a name="nightly">Running the nightly tester</a></div>
|
||||
<!--=========================================================================-->
|
||||
@ -1217,7 +1206,7 @@ know. Thanks!</p>
|
||||
|
||||
John T. Criswell, Reid Spencer, and Tanya Lattner<br>
|
||||
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br>
|
||||
Last modified: $Date: 2009-09-27 10:01:44 +0200 (Sun, 27 Sep 2009) $
|
||||
Last modified: $Date: 2010-02-26 22:23:59 +0100 (Fri, 26 Feb 2010) $
|
||||
</address>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -377,10 +377,10 @@ interesting way, we just throw away the result of <tt>opt</tt> (sending it to
|
||||
<tt>/dev/null</tt>).</p>
|
||||
|
||||
<p>To see what happened to the other string you registered, try running
|
||||
<tt>opt</tt> with the <tt>--help</tt> option:</p>
|
||||
<tt>opt</tt> with the <tt>-help</tt> option:</p>
|
||||
|
||||
<div class="doc_code"><pre>
|
||||
$ opt -load ../../../Debug/lib/Hello.so --help
|
||||
$ opt -load ../../../Debug/lib/Hello.so -help
|
||||
OVERVIEW: llvm .bc -> .bc modular optimizer
|
||||
|
||||
USAGE: opt [options] <input bitcode>
|
||||
@ -970,7 +970,7 @@ template, which requires you to pass at least two
|
||||
parameters. The first parameter is the name of the pass that is to be used on
|
||||
the command line to specify that the pass should be added to a program (for
|
||||
example, with <tt>opt</tt> or <tt>bugpoint</tt>). The second argument is the
|
||||
name of the pass, which is to be used for the <tt>--help</tt> output of
|
||||
name of the pass, which is to be used for the <tt>-help</tt> output of
|
||||
programs, as
|
||||
well as for debug output generated by the <tt>--debug-pass</tt> option.</p>
|
||||
|
||||
@ -1410,7 +1410,7 @@ allowing any analysis results to live across the execution of your pass.</p>
|
||||
options that is useful for debugging pass execution, seeing how things work, and
|
||||
diagnosing when you should be preserving more analyses than you currently are
|
||||
(To get information about all of the variants of the <tt>--debug-pass</tt>
|
||||
option, just type '<tt>opt --help-hidden</tt>').</p>
|
||||
option, just type '<tt>opt -help-hidden</tt>').</p>
|
||||
|
||||
<p>By using the <tt>--debug-pass=Structure</tt> option, for example, we can see
|
||||
how our <a href="#basiccode">Hello World</a> pass interacts with other passes.
|
||||
@ -1625,12 +1625,12 @@ form; </p>
|
||||
</pre></div>
|
||||
|
||||
<p>Note the two spaces prior to the help string produces a tidy result on the
|
||||
--help query.</p>
|
||||
-help query.</p>
|
||||
|
||||
<div class="doc_code"><pre>
|
||||
$ llc --help
|
||||
$ llc -help
|
||||
...
|
||||
-regalloc - Register allocator to use: (default = linearscan)
|
||||
-regalloc - Register allocator to use (default=linearscan)
|
||||
=linearscan - linear scan register allocator
|
||||
=local - local register allocator
|
||||
=simple - simple register allocator
|
||||
@ -1829,7 +1829,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: 2009-10-12 16:46:08 +0200 (Mon, 12 Oct 2009) $
|
||||
Last modified: $Date: 2010-02-18 15:37:52 +0100 (Thu, 18 Feb 2010) $
|
||||
</address>
|
||||
|
||||
</body>
|
||||
|
@ -93,7 +93,6 @@ Current tools:
|
||||
<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/stkrc.html">stkrc</a>,
|
||||
<a href="/cmds/bugpoint.html">bugpoint</a>,
|
||||
<a href="/cmds/llvm-bcanalyzer.html">llvm-bcanalyzer</a>,
|
||||
</li>
|
||||
@ -117,6 +116,9 @@ manual for using the LLVM testing infrastructure.</li>
|
||||
<li><a href="GCCFEBuildInstrs.html">How to build the Ada/C/C++/Fortran front-ends</a> -
|
||||
Instructions for building gcc front-ends from source.</li>
|
||||
|
||||
<li><a href="Packaging.html">Packaging guide</a> - Advice on packaging
|
||||
LLVM into a distribution.</li>
|
||||
|
||||
<li><a href="Lexicon.html">The LLVM Lexicon</a> - Definition of acronyms, terms
|
||||
and concepts used in LLVM.</li>
|
||||
|
||||
@ -285,7 +287,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: 2010-02-03 19:49:55 +0100 (Wed, 03 Feb 2010) $
|
||||
Last modified: $Date: 2010-02-26 01:54:42 +0100 (Fri, 26 Feb 2010) $
|
||||
</address>
|
||||
</body></html>
|
||||
|
||||
|
@ -170,7 +170,7 @@ internally (<tt>APFloat</tt> has the capability of holding floating point
|
||||
constants of <em>A</em>rbitrary <em>P</em>recision). This code basically just
|
||||
creates and returns a <tt>ConstantFP</tt>. Note that in the LLVM IR
|
||||
that constants are all uniqued together and shared. For this reason, the API
|
||||
uses "the Context.get..." idiom instead of "new foo(..)" or "foo::Create(..)".</p>
|
||||
uses the "foo::get(...)" idiom instead of "new foo(..)" or "foo::Create(..)".</p>
|
||||
|
||||
<div class="doc_code">
|
||||
<pre>
|
||||
@ -323,10 +323,10 @@ really talks about the external interface for a function (not the value computed
|
||||
by an expression), it makes sense for it to return the LLVM Function it
|
||||
corresponds to when codegen'd.</p>
|
||||
|
||||
<p>The call to <tt>Context.get</tt> creates
|
||||
<p>The call to <tt>FunctionType::get</tt> creates
|
||||
the <tt>FunctionType</tt> that should be used for a given Prototype. Since all
|
||||
function arguments in Kaleidoscope are of type double, the first line creates
|
||||
a vector of "N" LLVM double types. It then uses the <tt>Context.get</tt>
|
||||
a vector of "N" LLVM double types. It then uses the <tt>Functiontype::get</tt>
|
||||
method to create a function type that takes "N" doubles as arguments, returns
|
||||
one double as a result, and that is not vararg (the false parameter indicates
|
||||
this). Note that Types in LLVM are uniqued just like Constants are, so you
|
||||
@ -535,8 +535,7 @@ ready> <b>4+5</b>;
|
||||
Read top-level expression:
|
||||
define double @""() {
|
||||
entry:
|
||||
%addtmp = add double 4.000000e+00, 5.000000e+00
|
||||
ret double %addtmp
|
||||
ret double 9.000000e+00
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
@ -544,7 +543,8 @@ entry:
|
||||
<p>Note how the parser turns the top-level expression into anonymous functions
|
||||
for us. This will be handy when we add <a href="LangImpl4.html#jit">JIT
|
||||
support</a> in the next chapter. Also note that the code is very literally
|
||||
transcribed, no optimizations are being performed. We will
|
||||
transcribed, no optimizations are being performed except simple constant
|
||||
folding done by IRBuilder. We will
|
||||
<a href="LangImpl4.html#trivialconstfold">add optimizations</a> explicitly in
|
||||
the next chapter.</p>
|
||||
|
||||
@ -554,12 +554,12 @@ ready> <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 = mul double %a, %a
|
||||
%multmp1 = mul double 2.000000e+00, %a
|
||||
%multmp2 = mul double %multmp1, %b
|
||||
%addtmp = add double %multmp, %multmp2
|
||||
%multmp3 = mul double %b, %b
|
||||
%addtmp4 = add double %addtmp, %multmp3
|
||||
%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>
|
||||
@ -576,7 +576,7 @@ 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 = add double %calltmp, %calltmp1
|
||||
%addtmp = fadd double %calltmp, %calltmp1
|
||||
ret double %addtmp
|
||||
}
|
||||
</pre>
|
||||
@ -612,18 +612,18 @@ ready> <b>^D</b>
|
||||
|
||||
define double @""() {
|
||||
entry:
|
||||
%addtmp = add double 4.000000e+00, 5.000000e+00
|
||||
%addtmp = fadd double 4.000000e+00, 5.000000e+00
|
||||
ret double %addtmp
|
||||
}
|
||||
|
||||
define double @foo(double %a, double %b) {
|
||||
entry:
|
||||
%multmp = mul double %a, %a
|
||||
%multmp1 = mul double 2.000000e+00, %a
|
||||
%multmp2 = mul double %multmp1, %b
|
||||
%addtmp = add double %multmp, %multmp2
|
||||
%multmp3 = mul double %b, %b
|
||||
%addtmp4 = add double %addtmp, %multmp3
|
||||
%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
|
||||
}
|
||||
|
||||
@ -631,7 +631,7 @@ 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 = add double %calltmp, %calltmp1
|
||||
%addtmp = fadd double %calltmp, %calltmp1
|
||||
ret double %addtmp
|
||||
}
|
||||
|
||||
@ -1263,7 +1263,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: 2010-02-03 18:27:31 +0100 (Wed, 03 Feb 2010) $
|
||||
Last modified: $Date: 2010-03-02 02:11:08 +0100 (Tue, 02 Mar 2010) $
|
||||
</address>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -65,7 +65,7 @@ ready> <b>def test(x) 1+2+x;</b>
|
||||
Read function definition:
|
||||
define double @test(double %x) {
|
||||
entry:
|
||||
%addtmp = add double 3.000000e+00, %x
|
||||
%addtmp = fadd double 3.000000e+00, %x
|
||||
ret double %addtmp
|
||||
}
|
||||
</pre>
|
||||
@ -80,8 +80,8 @@ ready> <b>def test(x) 1+2+x;</b>
|
||||
Read function definition:
|
||||
define double @test(double %x) {
|
||||
entry:
|
||||
%addtmp = add double 2.000000e+00, 1.000000e+00
|
||||
%addtmp1 = add double %addtmp, %x
|
||||
%addtmp = fadd double 2.000000e+00, 1.000000e+00
|
||||
%addtmp1 = fadd double %addtmp, %x
|
||||
ret double %addtmp1
|
||||
}
|
||||
</pre>
|
||||
@ -113,9 +113,9 @@ ready> <b>def test(x) (1+2+x)*(x+(1+2));</b>
|
||||
ready> Read function definition:
|
||||
define double @test(double %x) {
|
||||
entry:
|
||||
%addtmp = add double 3.000000e+00, %x
|
||||
%addtmp1 = add double %x, 3.000000e+00
|
||||
%multmp = mul double %addtmp, %addtmp1
|
||||
%addtmp = fadd double 3.000000e+00, %x
|
||||
%addtmp1 = fadd double %x, 3.000000e+00
|
||||
%multmp = fmul double %addtmp, %addtmp1
|
||||
ret double %multmp
|
||||
}
|
||||
</pre>
|
||||
@ -240,8 +240,8 @@ ready> <b>def test(x) (1+2+x)*(x+(1+2));</b>
|
||||
ready> Read function definition:
|
||||
define double @test(double %x) {
|
||||
entry:
|
||||
%addtmp = add double %x, 3.000000e+00
|
||||
%multmp = mul double %addtmp, %addtmp
|
||||
%addtmp = fadd double %x, 3.000000e+00
|
||||
%multmp = fmul double %addtmp, %addtmp
|
||||
ret double %multmp
|
||||
}
|
||||
</pre>
|
||||
@ -363,8 +363,8 @@ ready> <b>def testfunc(x y) x + y*2; </b>
|
||||
Read function definition:
|
||||
define double @testfunc(double %x, double %y) {
|
||||
entry:
|
||||
%multmp = mul double %y, 2.000000e+00
|
||||
%addtmp = add double %multmp, %x
|
||||
%multmp = fmul double %y, 2.000000e+00
|
||||
%addtmp = fadd double %multmp, %x
|
||||
ret double %addtmp
|
||||
}
|
||||
|
||||
@ -411,10 +411,10 @@ Read function definition:
|
||||
define double @foo(double %x) {
|
||||
entry:
|
||||
%calltmp = call double @sin( double %x )
|
||||
%multmp = mul double %calltmp, %calltmp
|
||||
%multmp = fmul double %calltmp, %calltmp
|
||||
%calltmp2 = call double @cos( double %x )
|
||||
%multmp4 = mul double %calltmp2, %calltmp2
|
||||
%addtmp = add double %multmp, %multmp4
|
||||
%multmp4 = fmul double %calltmp2, %calltmp2
|
||||
%addtmp = fadd double %multmp, %multmp4
|
||||
ret double %addtmp
|
||||
}
|
||||
|
||||
@ -1126,7 +1126,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: 2010-02-11 20:15:20 +0100 (Thu, 11 Feb 2010) $
|
||||
Last modified: $Date: 2010-03-02 02:11:08 +0100 (Tue, 02 Mar 2010) $
|
||||
</address>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -678,7 +678,7 @@ loop: ; preds = %loop, %entry
|
||||
; body
|
||||
%calltmp = call double @putchard( double 4.200000e+01 )
|
||||
; increment
|
||||
%nextvar = add double %i, 1.000000e+00
|
||||
%nextvar = fadd double %i, 1.000000e+00
|
||||
|
||||
; termination test
|
||||
%cmptmp = fcmp ult double %i, %n
|
||||
@ -1771,7 +1771,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: 2010-02-11 20:15:20 +0100 (Thu, 11 Feb 2010) $
|
||||
Last modified: $Date: 2010-03-02 02:11:08 +0100 (Tue, 02 Mar 2010) $
|
||||
</address>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -557,12 +557,12 @@ then: ; preds = %entry
|
||||
|
||||
else: ; preds = %entry
|
||||
<b>%x3 = load double* %x1</b>
|
||||
%subtmp = sub double %x3, 1.000000e+00
|
||||
%subtmp = fsub double %x3, 1.000000e+00
|
||||
%calltmp = call double @fib( double %subtmp )
|
||||
<b>%x4 = load double* %x1</b>
|
||||
%subtmp5 = sub double %x4, 2.000000e+00
|
||||
%subtmp5 = fsub double %x4, 2.000000e+00
|
||||
%calltmp6 = call double @fib( double %subtmp5 )
|
||||
%addtmp = add double %calltmp, %calltmp6
|
||||
%addtmp = fadd double %calltmp, %calltmp6
|
||||
br label %ifcont
|
||||
|
||||
ifcont: ; preds = %else, %then
|
||||
@ -595,11 +595,11 @@ then:
|
||||
br label %ifcont
|
||||
|
||||
else:
|
||||
%subtmp = sub double <b>%x</b>, 1.000000e+00
|
||||
%subtmp = fsub double <b>%x</b>, 1.000000e+00
|
||||
%calltmp = call double @fib( double %subtmp )
|
||||
%subtmp5 = sub double <b>%x</b>, 2.000000e+00
|
||||
%subtmp5 = fsub double <b>%x</b>, 2.000000e+00
|
||||
%calltmp6 = call double @fib( double %subtmp5 )
|
||||
%addtmp = add double %calltmp, %calltmp6
|
||||
%addtmp = fadd double %calltmp, %calltmp6
|
||||
br label %ifcont
|
||||
|
||||
ifcont: ; preds = %else, %then
|
||||
@ -625,11 +625,11 @@ entry:
|
||||
br i1 %ifcond, label %else, label %ifcont
|
||||
|
||||
else:
|
||||
%subtmp = sub double %x, 1.000000e+00
|
||||
%subtmp = fsub double %x, 1.000000e+00
|
||||
%calltmp = call double @fib( double %subtmp )
|
||||
%subtmp5 = sub double %x, 2.000000e+00
|
||||
%subtmp5 = fsub double %x, 2.000000e+00
|
||||
%calltmp6 = call double @fib( double %subtmp5 )
|
||||
%addtmp = add double %calltmp, %calltmp6
|
||||
%addtmp = fadd double %calltmp, %calltmp6
|
||||
ret double %addtmp
|
||||
|
||||
ifcont:
|
||||
@ -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: 2010-02-11 20:15:20 +0100 (Thu, 11 Feb 2010) $
|
||||
Last modified: $Date: 2010-03-02 02:11:08 +0100 (Tue, 02 Mar 2010) $
|
||||
</address>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -484,7 +484,7 @@ ready> <b>4+5</b>;
|
||||
Read top-level expression:
|
||||
define double @""() {
|
||||
entry:
|
||||
%addtmp = add double 4.000000e+00, 5.000000e+00
|
||||
%addtmp = fadd double 4.000000e+00, 5.000000e+00
|
||||
ret double %addtmp
|
||||
}
|
||||
</pre>
|
||||
@ -503,12 +503,12 @@ ready> <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 = mul double %a, %a
|
||||
%multmp1 = mul double 2.000000e+00, %a
|
||||
%multmp2 = mul double %multmp1, %b
|
||||
%addtmp = add double %multmp, %multmp2
|
||||
%multmp3 = mul double %b, %b
|
||||
%addtmp4 = add double %addtmp, %multmp3
|
||||
%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>
|
||||
@ -525,7 +525,7 @@ 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 = add double %calltmp, %calltmp1
|
||||
%addtmp = fadd double %calltmp, %calltmp1
|
||||
ret double %addtmp
|
||||
}
|
||||
</pre>
|
||||
@ -561,18 +561,18 @@ ready> <b>^D</b>
|
||||
|
||||
define double @""() {
|
||||
entry:
|
||||
%addtmp = add double 4.000000e+00, 5.000000e+00
|
||||
%addtmp = fadd double 4.000000e+00, 5.000000e+00
|
||||
ret double %addtmp
|
||||
}
|
||||
|
||||
define double @foo(double %a, double %b) {
|
||||
entry:
|
||||
%multmp = mul double %a, %a
|
||||
%multmp1 = mul double 2.000000e+00, %a
|
||||
%multmp2 = mul double %multmp1, %b
|
||||
%addtmp = add double %multmp, %multmp2
|
||||
%multmp3 = mul double %b, %b
|
||||
%addtmp4 = add double %addtmp, %multmp3
|
||||
%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
|
||||
}
|
||||
|
||||
@ -580,7 +580,7 @@ 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 = add double %calltmp, %calltmp1
|
||||
%addtmp = fadd double %calltmp, %calltmp1
|
||||
ret double %addtmp
|
||||
}
|
||||
|
||||
@ -1085,7 +1085,7 @@ main ()
|
||||
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
|
||||
<a href="mailto:idadesub@users.sourceforge.net">Erick Tryzelaar</a><br>
|
||||
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br>
|
||||
Last modified: $Date: 2010-02-03 18:27:31 +0100 (Wed, 03 Feb 2010) $
|
||||
Last modified: $Date: 2010-03-02 02:11:08 +0100 (Tue, 02 Mar 2010) $
|
||||
</address>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -72,8 +72,8 @@ ready> <b>def test(x) 1+2+x;</b>
|
||||
Read function definition:
|
||||
define double @test(double %x) {
|
||||
entry:
|
||||
%addtmp = add double 1.000000e+00, 2.000000e+00
|
||||
%addtmp1 = add double %addtmp, %x
|
||||
%addtmp = fadd double 1.000000e+00, 2.000000e+00
|
||||
%addtmp1 = fadd double %addtmp, %x
|
||||
ret double %addtmp1
|
||||
}
|
||||
</pre>
|
||||
@ -104,7 +104,7 @@ ready> <b>def test(x) 1+2+x;</b>
|
||||
Read function definition:
|
||||
define double @test(double %x) {
|
||||
entry:
|
||||
%addtmp = add double 3.000000e+00, %x
|
||||
%addtmp = fadd double 3.000000e+00, %x
|
||||
ret double %addtmp
|
||||
}
|
||||
</pre>
|
||||
@ -127,9 +127,9 @@ ready> <b>def test(x) (1+2+x)*(x+(1+2));</b>
|
||||
ready> Read function definition:
|
||||
define double @test(double %x) {
|
||||
entry:
|
||||
%addtmp = add double 3.000000e+00, %x
|
||||
%addtmp1 = add double %x, 3.000000e+00
|
||||
%multmp = mul double %addtmp, %addtmp1
|
||||
%addtmp = fadd double 3.000000e+00, %x
|
||||
%addtmp1 = fadd double %x, 3.000000e+00
|
||||
%multmp = fmul double %addtmp, %addtmp1
|
||||
ret double %multmp
|
||||
}
|
||||
</pre>
|
||||
@ -267,8 +267,8 @@ ready> <b>def test(x) (1+2+x)*(x+(1+2));</b>
|
||||
ready> Read function definition:
|
||||
define double @test(double %x) {
|
||||
entry:
|
||||
%addtmp = add double %x, 3.000000e+00
|
||||
%multmp = mul double %addtmp, %addtmp
|
||||
%addtmp = fadd double %x, 3.000000e+00
|
||||
%multmp = fmul double %addtmp, %addtmp
|
||||
ret double %multmp
|
||||
}
|
||||
</pre>
|
||||
@ -388,8 +388,8 @@ ready> <b>def testfunc(x y) x + y*2; </b>
|
||||
Read function definition:
|
||||
define double @testfunc(double %x, double %y) {
|
||||
entry:
|
||||
%multmp = mul double %y, 2.000000e+00
|
||||
%addtmp = add double %multmp, %x
|
||||
%multmp = fmul double %y, 2.000000e+00
|
||||
%addtmp = fadd double %multmp, %x
|
||||
ret double %addtmp
|
||||
}
|
||||
|
||||
@ -436,10 +436,10 @@ Read function definition:
|
||||
define double @foo(double %x) {
|
||||
entry:
|
||||
%calltmp = call double @sin( double %x )
|
||||
%multmp = mul double %calltmp, %calltmp
|
||||
%multmp = fmul double %calltmp, %calltmp
|
||||
%calltmp2 = call double @cos( double %x )
|
||||
%multmp4 = mul double %calltmp2, %calltmp2
|
||||
%addtmp = add double %multmp, %multmp4
|
||||
%multmp4 = fmul double %calltmp2, %calltmp2
|
||||
%addtmp = fadd double %multmp, %multmp4
|
||||
ret double %addtmp
|
||||
}
|
||||
|
||||
@ -1032,7 +1032,7 @@ extern double putchard(double X) {
|
||||
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
|
||||
<a href="mailto:idadesub@users.sourceforge.net">Erick Tryzelaar</a><br>
|
||||
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br>
|
||||
Last modified: $Date: 2010-02-03 18:27:31 +0100 (Wed, 03 Feb 2010) $
|
||||
Last modified: $Date: 2010-03-02 02:11:08 +0100 (Tue, 02 Mar 2010) $
|
||||
</address>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -653,7 +653,7 @@ loop: ; preds = %loop, %entry
|
||||
; body
|
||||
%calltmp = call double @putchard( double 4.200000e+01 )
|
||||
; increment
|
||||
%nextvar = add double %i, 1.000000e+00
|
||||
%nextvar = fadd double %i, 1.000000e+00
|
||||
|
||||
; termination test
|
||||
%cmptmp = fcmp ult double %i, %n
|
||||
@ -1563,7 +1563,7 @@ operators</a>
|
||||
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
|
||||
<a href="mailto:idadesub@users.sourceforge.net">Erick Tryzelaar</a><br>
|
||||
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br>
|
||||
Last modified: $Date: 2010-02-03 18:27:31 +0100 (Wed, 03 Feb 2010) $
|
||||
Last modified: $Date: 2010-03-02 02:11:08 +0100 (Tue, 02 Mar 2010) $
|
||||
</address>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -581,12 +581,12 @@ then: ; preds = %entry
|
||||
|
||||
else: ; preds = %entry
|
||||
<b>%x3 = load double* %x1</b>
|
||||
%subtmp = sub double %x3, 1.000000e+00
|
||||
%subtmp = fsub double %x3, 1.000000e+00
|
||||
%calltmp = call double @fib( double %subtmp )
|
||||
<b>%x4 = load double* %x1</b>
|
||||
%subtmp5 = sub double %x4, 2.000000e+00
|
||||
%subtmp5 = fsub double %x4, 2.000000e+00
|
||||
%calltmp6 = call double @fib( double %subtmp5 )
|
||||
%addtmp = add double %calltmp, %calltmp6
|
||||
%addtmp = fadd double %calltmp, %calltmp6
|
||||
br label %ifcont
|
||||
|
||||
ifcont: ; preds = %else, %then
|
||||
@ -619,11 +619,11 @@ then:
|
||||
br label %ifcont
|
||||
|
||||
else:
|
||||
%subtmp = sub double <b>%x</b>, 1.000000e+00
|
||||
%subtmp = fsub double <b>%x</b>, 1.000000e+00
|
||||
%calltmp = call double @fib( double %subtmp )
|
||||
%subtmp5 = sub double <b>%x</b>, 2.000000e+00
|
||||
%subtmp5 = fsub double <b>%x</b>, 2.000000e+00
|
||||
%calltmp6 = call double @fib( double %subtmp5 )
|
||||
%addtmp = add double %calltmp, %calltmp6
|
||||
%addtmp = fadd double %calltmp, %calltmp6
|
||||
br label %ifcont
|
||||
|
||||
ifcont: ; preds = %else, %then
|
||||
@ -649,11 +649,11 @@ entry:
|
||||
br i1 %ifcond, label %else, label %ifcont
|
||||
|
||||
else:
|
||||
%subtmp = sub double %x, 1.000000e+00
|
||||
%subtmp = fsub double %x, 1.000000e+00
|
||||
%calltmp = call double @fib( double %subtmp )
|
||||
%subtmp5 = sub double %x, 2.000000e+00
|
||||
%subtmp5 = fsub double %x, 2.000000e+00
|
||||
%calltmp6 = call double @fib( double %subtmp5 )
|
||||
%addtmp = add double %calltmp, %calltmp6
|
||||
%addtmp = fadd double %calltmp, %calltmp6
|
||||
ret double %addtmp
|
||||
|
||||
ifcont:
|
||||
@ -1901,7 +1901,7 @@ extern double printd(double X) {
|
||||
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
|
||||
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br>
|
||||
<a href="mailto:idadesub@users.sourceforge.net">Erick Tryzelaar</a><br>
|
||||
Last modified: $Date: 2010-02-03 18:27:31 +0100 (Wed, 03 Feb 2010) $
|
||||
Last modified: $Date: 2010-03-02 02:11:08 +0100 (Tue, 02 Mar 2010) $
|
||||
</address>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -17,7 +17,12 @@ PARALLEL_DIRS += ParallelJIT
|
||||
endif
|
||||
|
||||
ifeq ($(LLVM_ON_UNIX),1)
|
||||
PARALLEL_DIRS += ExceptionDemo
|
||||
ifeq ($(ARCH),x86)
|
||||
PARALLEL_DIRS += ExceptionDemo
|
||||
endif
|
||||
ifeq ($(ARCH),x86_64)
|
||||
PARALLEL_DIRS += ExceptionDemo
|
||||
endif
|
||||
endif
|
||||
|
||||
include $(LEVEL)/Makefile.common
|
||||
|
@ -36,18 +36,28 @@ LLVMBool LLVMParseBitcodeInContext(LLVMContextRef ContextRef,
|
||||
LLVMMemoryBufferRef MemBuf,
|
||||
LLVMModuleRef *OutModule, char **OutMessage);
|
||||
|
||||
/* Reads a module from the specified path, returning via the OutMP parameter
|
||||
a module provider which performs lazy deserialization. Returns 0 on success.
|
||||
Optionally returns a human-readable error message via OutMessage. */
|
||||
LLVMBool LLVMGetBitcodeModuleProvider(LLVMMemoryBufferRef MemBuf,
|
||||
LLVMModuleProviderRef *OutMP,
|
||||
char **OutMessage);
|
||||
/** Reads a module from the specified path, returning via the OutMP parameter
|
||||
a module provider which performs lazy deserialization. Returns 0 on success.
|
||||
Optionally returns a human-readable error message via OutMessage. */
|
||||
LLVMBool LLVMGetBitcodeModuleInContext(LLVMContextRef ContextRef,
|
||||
LLVMMemoryBufferRef MemBuf,
|
||||
LLVMModuleRef *OutM,
|
||||
char **OutMessage);
|
||||
|
||||
LLVMBool LLVMGetBitcodeModule(LLVMMemoryBufferRef MemBuf, LLVMModuleRef *OutM,
|
||||
char **OutMessage);
|
||||
|
||||
|
||||
/** Deprecated: Use LLVMGetBitcodeModuleInContext instead. */
|
||||
LLVMBool LLVMGetBitcodeModuleProviderInContext(LLVMContextRef ContextRef,
|
||||
LLVMMemoryBufferRef MemBuf,
|
||||
LLVMModuleProviderRef *OutMP,
|
||||
char **OutMessage);
|
||||
|
||||
/** Deprecated: Use LLVMGetBitcodeModule instead. */
|
||||
LLVMBool LLVMGetBitcodeModuleProvider(LLVMMemoryBufferRef MemBuf,
|
||||
LLVMModuleProviderRef *OutMP,
|
||||
char **OutMessage);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -92,11 +92,8 @@ typedef struct LLVMOpaqueMemoryBuffer *LLVMMemoryBufferRef;
|
||||
/** See the llvm::PassManagerBase class. */
|
||||
typedef struct LLVMOpaquePassManager *LLVMPassManagerRef;
|
||||
|
||||
/**
|
||||
* Used to iterate through the uses of a Value, allowing access to all Values
|
||||
* that use this Value. See the llvm::Use and llvm::value_use_iterator classes.
|
||||
*/
|
||||
typedef struct LLVMOpaqueUseIterator *LLVMUseIteratorRef;
|
||||
/** Used to get the users and usees of a Value. See the llvm::Use class. */
|
||||
typedef struct LLVMOpaqueUse *LLVMUseRef;
|
||||
|
||||
typedef enum {
|
||||
LLVMZExtAttribute = 1<<0,
|
||||
@ -282,13 +279,19 @@ typedef enum {
|
||||
void LLVMDisposeMessage(char *Message);
|
||||
|
||||
|
||||
/*===-- Modules -----------------------------------------------------------===*/
|
||||
/*===-- Contexts ----------------------------------------------------------===*/
|
||||
|
||||
/* Create and destroy contexts. */
|
||||
LLVMContextRef LLVMContextCreate(void);
|
||||
LLVMContextRef LLVMGetGlobalContext(void);
|
||||
void LLVMContextDispose(LLVMContextRef C);
|
||||
|
||||
unsigned LLVMGetMDKindIDInContext(LLVMContextRef C, const char* Name,
|
||||
unsigned SLen);
|
||||
unsigned LLVMGetMDKindID(const char* Name, unsigned SLen);
|
||||
|
||||
/*===-- Modules -----------------------------------------------------------===*/
|
||||
|
||||
/* Create and destroy modules. */
|
||||
/** See llvm::Module::Module. */
|
||||
LLVMModuleRef LLVMModuleCreateWithName(const char *ModuleID);
|
||||
@ -497,6 +500,9 @@ const char *LLVMGetValueName(LLVMValueRef Val);
|
||||
void LLVMSetValueName(LLVMValueRef Val, const char *Name);
|
||||
void LLVMDumpValue(LLVMValueRef Val);
|
||||
void LLVMReplaceAllUsesWith(LLVMValueRef OldVal, LLVMValueRef NewVal);
|
||||
int LLVMHasMetadata(LLVMValueRef Val);
|
||||
LLVMValueRef LLVMGetMetadata(LLVMValueRef Val, unsigned KindID);
|
||||
void LLVMSetMetadata(LLVMValueRef Val, unsigned KindID, LLVMValueRef Node);
|
||||
|
||||
/* Conversion functions. Return the input value if it is an instance of the
|
||||
specified class, otherwise NULL. See llvm::dyn_cast_or_null<>. */
|
||||
@ -505,10 +511,10 @@ void LLVMReplaceAllUsesWith(LLVMValueRef OldVal, LLVMValueRef NewVal);
|
||||
LLVM_FOR_EACH_VALUE_SUBCLASS(LLVM_DECLARE_VALUE_CAST)
|
||||
|
||||
/* Operations on Uses */
|
||||
LLVMUseIteratorRef LLVMGetFirstUse(LLVMValueRef Val);
|
||||
LLVMUseIteratorRef LLVMGetNextUse(LLVMUseIteratorRef U);
|
||||
LLVMValueRef LLVMGetUser(LLVMUseIteratorRef U);
|
||||
LLVMValueRef LLVMGetUsedValue(LLVMUseIteratorRef U);
|
||||
LLVMUseRef LLVMGetFirstUse(LLVMValueRef Val);
|
||||
LLVMUseRef LLVMGetNextUse(LLVMUseRef U);
|
||||
LLVMValueRef LLVMGetUser(LLVMUseRef U);
|
||||
LLVMValueRef LLVMGetUsedValue(LLVMUseRef U);
|
||||
|
||||
/* Operations on Users */
|
||||
LLVMValueRef LLVMGetOperand(LLVMValueRef Val, unsigned Index);
|
||||
@ -522,6 +528,14 @@ LLVMBool LLVMIsNull(LLVMValueRef Val);
|
||||
LLVMBool LLVMIsUndef(LLVMValueRef Val);
|
||||
LLVMValueRef LLVMConstPointerNull(LLVMTypeRef Ty);
|
||||
|
||||
/* Operations on metadata */
|
||||
LLVMValueRef LLVMMDStringInContext(LLVMContextRef C, const char *Str,
|
||||
unsigned SLen);
|
||||
LLVMValueRef LLVMMDString(const char *Str, unsigned SLen);
|
||||
LLVMValueRef LLVMMDNodeInContext(LLVMContextRef C, LLVMValueRef *Vals,
|
||||
unsigned Count);
|
||||
LLVMValueRef LLVMMDNode(LLVMValueRef *Vals, unsigned Count);
|
||||
|
||||
/* Operations on scalar constants */
|
||||
LLVMValueRef LLVMConstInt(LLVMTypeRef IntTy, unsigned long long N,
|
||||
LLVMBool SignExtend);
|
||||
@ -551,20 +565,28 @@ LLVMValueRef LLVMConstArray(LLVMTypeRef ElementTy,
|
||||
LLVMValueRef LLVMConstStruct(LLVMValueRef *ConstantVals, unsigned Count,
|
||||
LLVMBool Packed);
|
||||
LLVMValueRef LLVMConstVector(LLVMValueRef *ScalarConstantVals, unsigned Size);
|
||||
LLVMValueRef LLVMConstUnion(LLVMTypeRef Ty, LLVMValueRef Val);
|
||||
|
||||
/* Constant expressions */
|
||||
LLVMOpcode LLVMGetConstOpcode(LLVMValueRef ConstantVal);
|
||||
LLVMValueRef LLVMAlignOf(LLVMTypeRef Ty);
|
||||
LLVMValueRef LLVMSizeOf(LLVMTypeRef Ty);
|
||||
LLVMValueRef LLVMConstNeg(LLVMValueRef ConstantVal);
|
||||
LLVMValueRef LLVMConstNSWNeg(LLVMValueRef ConstantVal);
|
||||
LLVMValueRef LLVMConstNUWNeg(LLVMValueRef ConstantVal);
|
||||
LLVMValueRef LLVMConstFNeg(LLVMValueRef ConstantVal);
|
||||
LLVMValueRef LLVMConstNot(LLVMValueRef ConstantVal);
|
||||
LLVMValueRef LLVMConstAdd(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
|
||||
LLVMValueRef LLVMConstNSWAdd(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
|
||||
LLVMValueRef LLVMConstNUWAdd(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
|
||||
LLVMValueRef LLVMConstFAdd(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
|
||||
LLVMValueRef LLVMConstSub(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
|
||||
LLVMValueRef LLVMConstNSWSub(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
|
||||
LLVMValueRef LLVMConstNUWSub(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
|
||||
LLVMValueRef LLVMConstFSub(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
|
||||
LLVMValueRef LLVMConstMul(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
|
||||
LLVMValueRef LLVMConstNSWMul(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
|
||||
LLVMValueRef LLVMConstNUWMul(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
|
||||
LLVMValueRef LLVMConstFMul(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
|
||||
LLVMValueRef LLVMConstUDiv(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
|
||||
LLVMValueRef LLVMConstSDiv(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
|
||||
@ -630,6 +652,7 @@ LLVMValueRef LLVMConstInsertValue(LLVMValueRef AggConstant,
|
||||
LLVMValueRef LLVMConstInlineAsm(LLVMTypeRef Ty,
|
||||
const char *AsmString, const char *Constraints,
|
||||
LLVMBool HasSideEffects, LLVMBool IsAlignStack);
|
||||
LLVMValueRef LLVMBlockAddress(LLVMValueRef F, LLVMBasicBlockRef BB);
|
||||
|
||||
/* Operations on global variables, functions, and aliases (globals) */
|
||||
LLVMModuleRef LLVMGetGlobalParent(LLVMValueRef Global);
|
||||
@ -645,6 +668,9 @@ void LLVMSetAlignment(LLVMValueRef Global, unsigned Bytes);
|
||||
|
||||
/* Operations on global variables */
|
||||
LLVMValueRef LLVMAddGlobal(LLVMModuleRef M, LLVMTypeRef Ty, const char *Name);
|
||||
LLVMValueRef LLVMAddGlobalInAddressSpace(LLVMModuleRef M, LLVMTypeRef Ty,
|
||||
const char *Name,
|
||||
unsigned AddressSpace);
|
||||
LLVMValueRef LLVMGetNamedGlobal(LLVMModuleRef M, const char *Name);
|
||||
LLVMValueRef LLVMGetFirstGlobal(LLVMModuleRef M);
|
||||
LLVMValueRef LLVMGetLastGlobal(LLVMModuleRef M);
|
||||
@ -765,6 +791,11 @@ void LLVMInsertIntoBuilderWithName(LLVMBuilderRef Builder, LLVMValueRef Instr,
|
||||
const char *Name);
|
||||
void LLVMDisposeBuilder(LLVMBuilderRef Builder);
|
||||
|
||||
/* Metadata */
|
||||
void LLVMSetCurrentDebugLocation(LLVMBuilderRef Builder, LLVMValueRef L);
|
||||
LLVMValueRef LLVMGetCurrentDebugLocation(LLVMBuilderRef Builder);
|
||||
void LLVMSetInstDebugLocation(LLVMBuilderRef Builder, LLVMValueRef Inst);
|
||||
|
||||
/* Terminators */
|
||||
LLVMValueRef LLVMBuildRetVoid(LLVMBuilderRef);
|
||||
LLVMValueRef LLVMBuildRet(LLVMBuilderRef, LLVMValueRef V);
|
||||
@ -775,6 +806,8 @@ LLVMValueRef LLVMBuildCondBr(LLVMBuilderRef, LLVMValueRef If,
|
||||
LLVMBasicBlockRef Then, LLVMBasicBlockRef Else);
|
||||
LLVMValueRef LLVMBuildSwitch(LLVMBuilderRef, LLVMValueRef V,
|
||||
LLVMBasicBlockRef Else, unsigned NumCases);
|
||||
LLVMValueRef LLVMBuildIndirectBr(LLVMBuilderRef B, LLVMValueRef Addr,
|
||||
unsigned NumDests);
|
||||
LLVMValueRef LLVMBuildInvoke(LLVMBuilderRef, LLVMValueRef Fn,
|
||||
LLVMValueRef *Args, unsigned NumArgs,
|
||||
LLVMBasicBlockRef Then, LLVMBasicBlockRef Catch,
|
||||
@ -786,19 +819,32 @@ LLVMValueRef LLVMBuildUnreachable(LLVMBuilderRef);
|
||||
void LLVMAddCase(LLVMValueRef Switch, LLVMValueRef OnVal,
|
||||
LLVMBasicBlockRef Dest);
|
||||
|
||||
/* Add a destination to the indirectbr instruction */
|
||||
void LLVMAddDestination(LLVMValueRef IndirectBr, LLVMBasicBlockRef Dest);
|
||||
|
||||
/* Arithmetic */
|
||||
LLVMValueRef LLVMBuildAdd(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
|
||||
const char *Name);
|
||||
LLVMValueRef LLVMBuildNSWAdd(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
|
||||
const char *Name);
|
||||
LLVMValueRef LLVMBuildNUWAdd(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
|
||||
const char *Name);
|
||||
LLVMValueRef LLVMBuildFAdd(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
|
||||
const char *Name);
|
||||
LLVMValueRef LLVMBuildSub(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
|
||||
const char *Name);
|
||||
LLVMValueRef LLVMBuildNSWSub(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
|
||||
const char *Name);
|
||||
LLVMValueRef LLVMBuildNUWSub(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
|
||||
const char *Name);
|
||||
LLVMValueRef LLVMBuildFSub(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
|
||||
const char *Name);
|
||||
LLVMValueRef LLVMBuildMul(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
|
||||
const char *Name);
|
||||
LLVMValueRef LLVMBuildNSWMul(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
|
||||
const char *Name);
|
||||
LLVMValueRef LLVMBuildNUWMul(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
|
||||
const char *Name);
|
||||
LLVMValueRef LLVMBuildFMul(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
|
||||
const char *Name);
|
||||
LLVMValueRef LLVMBuildUDiv(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
|
||||
@ -827,7 +873,14 @@ LLVMValueRef LLVMBuildOr(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
|
||||
const char *Name);
|
||||
LLVMValueRef LLVMBuildXor(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
|
||||
const char *Name);
|
||||
LLVMValueRef LLVMBuildBinOp(LLVMBuilderRef B, LLVMOpcode Op,
|
||||
LLVMValueRef LHS, LLVMValueRef RHS,
|
||||
const char *Name);
|
||||
LLVMValueRef LLVMBuildNeg(LLVMBuilderRef, LLVMValueRef V, const char *Name);
|
||||
LLVMValueRef LLVMBuildNSWNeg(LLVMBuilderRef B, LLVMValueRef V,
|
||||
const char *Name);
|
||||
LLVMValueRef LLVMBuildNUWNeg(LLVMBuilderRef B, LLVMValueRef V,
|
||||
const char *Name);
|
||||
LLVMValueRef LLVMBuildFNeg(LLVMBuilderRef, LLVMValueRef V, const char *Name);
|
||||
LLVMValueRef LLVMBuildNot(LLVMBuilderRef, LLVMValueRef V, const char *Name);
|
||||
|
||||
@ -886,6 +939,8 @@ LLVMValueRef LLVMBuildSExtOrBitCast(LLVMBuilderRef, LLVMValueRef Val,
|
||||
LLVMTypeRef DestTy, const char *Name);
|
||||
LLVMValueRef LLVMBuildTruncOrBitCast(LLVMBuilderRef, LLVMValueRef Val,
|
||||
LLVMTypeRef DestTy, const char *Name);
|
||||
LLVMValueRef LLVMBuildCast(LLVMBuilderRef B, LLVMOpcode Op, LLVMValueRef Val,
|
||||
LLVMTypeRef DestTy, const char *Name);
|
||||
LLVMValueRef LLVMBuildPointerCast(LLVMBuilderRef, LLVMValueRef Val,
|
||||
LLVMTypeRef DestTy, const char *Name);
|
||||
LLVMValueRef LLVMBuildIntCast(LLVMBuilderRef, LLVMValueRef Val, /*Signed cast!*/
|
||||
@ -967,6 +1022,9 @@ LLVMPassManagerRef LLVMCreatePassManager(void);
|
||||
provider. It does not take ownership of the module provider. This type of
|
||||
pipeline is suitable for code generation and JIT compilation tasks.
|
||||
See llvm::FunctionPassManager::FunctionPassManager. */
|
||||
LLVMPassManagerRef LLVMCreateFunctionPassManagerForModule(LLVMModuleRef M);
|
||||
|
||||
/** Deprecated: Use LLVMCreateFunctionPassManagerForModule instead. */
|
||||
LLVMPassManagerRef LLVMCreateFunctionPassManager(LLVMModuleProviderRef MP);
|
||||
|
||||
/** Initializes, executes on the provided module, and finalizes all of the
|
||||
@ -1038,7 +1096,7 @@ namespace llvm {
|
||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(PATypeHolder, LLVMTypeHandleRef )
|
||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(MemoryBuffer, LLVMMemoryBufferRef )
|
||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LLVMContext, LLVMContextRef )
|
||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Use, LLVMUseIteratorRef )
|
||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Use, LLVMUseRef )
|
||||
DEFINE_STDCXX_CONVERSION_FUNCTIONS(PassManagerBase, LLVMPassManagerRef )
|
||||
/* LLVMModuleProviderRef exists for historical reasons, but now just holds a
|
||||
* Module.
|
||||
|
@ -55,14 +55,30 @@ void LLVMDisposeGenericValue(LLVMGenericValueRef GenVal);
|
||||
|
||||
/*===-- Operations on execution engines -----------------------------------===*/
|
||||
|
||||
LLVMBool LLVMCreateExecutionEngineForModule(LLVMExecutionEngineRef *OutEE,
|
||||
LLVMModuleRef M,
|
||||
char **OutError);
|
||||
|
||||
LLVMBool LLVMCreateInterpreterForModule(LLVMExecutionEngineRef *OutInterp,
|
||||
LLVMModuleRef M,
|
||||
char **OutError);
|
||||
|
||||
LLVMBool LLVMCreateJITCompilerForModule(LLVMExecutionEngineRef *OutJIT,
|
||||
LLVMModuleRef M,
|
||||
unsigned OptLevel,
|
||||
char **OutError);
|
||||
|
||||
/** Deprecated: Use LLVMCreateExecutionEngineForModule instead. */
|
||||
LLVMBool LLVMCreateExecutionEngine(LLVMExecutionEngineRef *OutEE,
|
||||
LLVMModuleProviderRef MP,
|
||||
char **OutError);
|
||||
|
||||
/** Deprecated: Use LLVMCreateInterpreterForModule instead. */
|
||||
LLVMBool LLVMCreateInterpreter(LLVMExecutionEngineRef *OutInterp,
|
||||
LLVMModuleProviderRef MP,
|
||||
char **OutError);
|
||||
|
||||
/** Deprecated: Use LLVMCreateJITCompilerForModule instead. */
|
||||
LLVMBool LLVMCreateJITCompiler(LLVMExecutionEngineRef *OutJIT,
|
||||
LLVMModuleProviderRef MP,
|
||||
unsigned OptLevel,
|
||||
@ -84,8 +100,15 @@ LLVMGenericValueRef LLVMRunFunction(LLVMExecutionEngineRef EE, LLVMValueRef F,
|
||||
|
||||
void LLVMFreeMachineCodeForFunction(LLVMExecutionEngineRef EE, LLVMValueRef F);
|
||||
|
||||
void LLVMAddModule(LLVMExecutionEngineRef EE, LLVMModuleRef M);
|
||||
|
||||
/** Deprecated: Use LLVMAddModule instead. */
|
||||
void LLVMAddModuleProvider(LLVMExecutionEngineRef EE, LLVMModuleProviderRef MP);
|
||||
|
||||
LLVMBool LLVMRemoveModule(LLVMExecutionEngineRef EE, LLVMModuleRef M,
|
||||
LLVMModuleRef *OutMod, char **OutError);
|
||||
|
||||
/** Deprecated: Use LLVMRemoveModule instead. */
|
||||
LLVMBool LLVMRemoveModuleProvider(LLVMExecutionEngineRef EE,
|
||||
LLVMModuleProviderRef MP,
|
||||
LLVMModuleRef *OutMod, char **OutError);
|
||||
|
@ -173,11 +173,16 @@ namespace llvm {
|
||||
fcZero
|
||||
};
|
||||
|
||||
enum uninitializedTag {
|
||||
uninitialized
|
||||
};
|
||||
|
||||
// Constructors.
|
||||
APFloat(const fltSemantics &); // Default construct to 0.0
|
||||
APFloat(const fltSemantics &, const StringRef &);
|
||||
APFloat(const fltSemantics &, integerPart);
|
||||
APFloat(const fltSemantics &, fltCategory, bool negative, unsigned type=0);
|
||||
APFloat(const fltSemantics &, fltCategory, bool negative);
|
||||
APFloat(const fltSemantics &, uninitializedTag);
|
||||
explicit APFloat(double d);
|
||||
explicit APFloat(float f);
|
||||
explicit APFloat(const APInt &, bool isIEEE = false);
|
||||
@ -199,7 +204,26 @@ namespace llvm {
|
||||
/// default. The value is truncated as necessary.
|
||||
static APFloat getNaN(const fltSemantics &Sem, bool Negative = false,
|
||||
unsigned type = 0) {
|
||||
return APFloat(Sem, fcNaN, Negative, type);
|
||||
if (type) {
|
||||
APInt fill(64, type);
|
||||
return getQNaN(Sem, Negative, &fill);
|
||||
} else {
|
||||
return getQNaN(Sem, Negative, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/// getQNan - Factory for QNaN values.
|
||||
static APFloat getQNaN(const fltSemantics &Sem,
|
||||
bool Negative = false,
|
||||
const APInt *payload = 0) {
|
||||
return makeNaN(Sem, false, Negative, payload);
|
||||
}
|
||||
|
||||
/// getSNan - Factory for SNaN values.
|
||||
static APFloat getSNaN(const fltSemantics &Sem,
|
||||
bool Negative = false,
|
||||
const APInt *payload = 0) {
|
||||
return makeNaN(Sem, true, Negative, payload);
|
||||
}
|
||||
|
||||
/// getLargest - Returns the largest finite number in the given
|
||||
@ -350,7 +374,9 @@ namespace llvm {
|
||||
opStatus modSpecials(const APFloat &);
|
||||
|
||||
/* Miscellany. */
|
||||
void makeNaN(unsigned = 0);
|
||||
static APFloat makeNaN(const fltSemantics &Sem, bool SNaN, bool Negative,
|
||||
const APInt *fill);
|
||||
void makeNaN(bool SNaN = false, bool Neg = false, const APInt *fill = 0);
|
||||
opStatus normalize(roundingMode, lostFraction);
|
||||
opStatus addOrSubtract(const APFloat &, roundingMode, bool subtract);
|
||||
cmpResult compareAbsoluteValue(const APFloat &) const;
|
||||
|
@ -150,7 +150,17 @@ class APInt {
|
||||
return isSingleWord() ? VAL : pVal[whichWord(bitPosition)];
|
||||
}
|
||||
|
||||
/// Converts a string into a number. The string must be non-empty
|
||||
/// and well-formed as a number of the given base. The bit-width
|
||||
/// must be sufficient to hold the result.
|
||||
///
|
||||
/// This is used by the constructors that take string arguments.
|
||||
///
|
||||
/// StringRef::getAsInteger is superficially similar but (1) does
|
||||
/// not assume that the string is well-formed and (2) grows the
|
||||
/// result to hold the input.
|
||||
///
|
||||
/// @param radix 2, 8, 10, or 16
|
||||
/// @brief Convert a char array into an APInt
|
||||
void fromString(unsigned numBits, const StringRef &str, uint8_t radix);
|
||||
|
||||
@ -571,6 +581,21 @@ public:
|
||||
/// @brief Bitwise OR assignment operator.
|
||||
APInt& operator|=(const APInt& RHS);
|
||||
|
||||
/// Performs a bitwise OR operation on this APInt and RHS. RHS is
|
||||
/// logically zero-extended or truncated to match the bit-width of
|
||||
/// the LHS.
|
||||
///
|
||||
/// @brief Bitwise OR assignment operator.
|
||||
APInt& operator|=(uint64_t RHS) {
|
||||
if (isSingleWord()) {
|
||||
VAL |= RHS;
|
||||
clearUnusedBits();
|
||||
} else {
|
||||
pVal[0] |= RHS;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Performs a bitwise XOR operation on this APInt and RHS. The result is
|
||||
/// assigned to *this.
|
||||
/// @returns *this after XORing with RHS.
|
||||
@ -1308,6 +1333,9 @@ public:
|
||||
/// Set the given bit of a bignum. Zero-based.
|
||||
static void tcSetBit(integerPart *, unsigned int bit);
|
||||
|
||||
/// Clear the given bit of a bignum. Zero-based.
|
||||
static void tcClearBit(integerPart *, unsigned int bit);
|
||||
|
||||
/// Returns the bit number of the least or most significant set bit
|
||||
/// of a number. If the input number has no bits set -1U is
|
||||
/// returned.
|
||||
|
@ -52,7 +52,7 @@ private:
|
||||
/// \return - The test result.
|
||||
bool GetTestResult(const changeset_ty &Changes);
|
||||
|
||||
/// Split - Partition a set of changes \arg Sinto one or two subsets.
|
||||
/// Split - Partition a set of changes \arg S into one or two subsets.
|
||||
void Split(const changeset_ty &S, changesetlist_ty &Res);
|
||||
|
||||
/// Delta - Minimize a set of \arg Changes which has been partioned into
|
||||
|
@ -36,10 +36,10 @@
|
||||
|
||||
namespace llvm {
|
||||
|
||||
template <typename K, typename V>
|
||||
template <typename K, typename V, typename KInfo = DenseMapInfo<K> >
|
||||
class ScopedHashTable;
|
||||
|
||||
template <typename K, typename V>
|
||||
template <typename K, typename V, typename KInfo = DenseMapInfo<K> >
|
||||
class ScopedHashTableVal {
|
||||
ScopedHashTableVal *NextInScope;
|
||||
ScopedHashTableVal *NextForKey;
|
||||
@ -61,35 +61,39 @@ public:
|
||||
ScopedHashTableVal *getNextInScope() { return NextInScope; }
|
||||
};
|
||||
|
||||
template <typename K, typename V>
|
||||
template <typename K, typename V, typename KInfo = DenseMapInfo<K> >
|
||||
class ScopedHashTableScope {
|
||||
/// HT - The hashtable that we are active for.
|
||||
ScopedHashTable<K, V> &HT;
|
||||
ScopedHashTable<K, V, KInfo> &HT;
|
||||
|
||||
/// PrevScope - This is the scope that we are shadowing in HT.
|
||||
ScopedHashTableScope *PrevScope;
|
||||
|
||||
/// LastValInScope - This is the last value that was inserted for this scope
|
||||
/// or null if none have been inserted yet.
|
||||
ScopedHashTableVal<K,V> *LastValInScope;
|
||||
ScopedHashTableVal<K, V, KInfo> *LastValInScope;
|
||||
void operator=(ScopedHashTableScope&); // DO NOT IMPLEMENT
|
||||
ScopedHashTableScope(ScopedHashTableScope&); // DO NOT IMPLEMENT
|
||||
public:
|
||||
ScopedHashTableScope(ScopedHashTable<K, V> &HT);
|
||||
ScopedHashTableScope(ScopedHashTable<K, V, KInfo> &HT);
|
||||
~ScopedHashTableScope();
|
||||
|
||||
private:
|
||||
friend class ScopedHashTable<K, V>;
|
||||
ScopedHashTableVal<K, V> *getLastValInScope() { return LastValInScope; }
|
||||
void setLastValInScope(ScopedHashTableVal<K,V> *Val) { LastValInScope = Val; }
|
||||
friend class ScopedHashTable<K, V, KInfo>;
|
||||
ScopedHashTableVal<K, V, KInfo> *getLastValInScope() {
|
||||
return LastValInScope;
|
||||
}
|
||||
void setLastValInScope(ScopedHashTableVal<K, V, KInfo> *Val) {
|
||||
LastValInScope = Val;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename K, typename V>
|
||||
template <typename K, typename V, typename KInfo = DenseMapInfo<K> >
|
||||
class ScopedHashTableIterator {
|
||||
ScopedHashTableVal<K,V> *Node;
|
||||
ScopedHashTableVal<K, V, KInfo> *Node;
|
||||
public:
|
||||
ScopedHashTableIterator(ScopedHashTableVal<K,V> *node) : Node(node){}
|
||||
ScopedHashTableIterator(ScopedHashTableVal<K, V, KInfo> *node) : Node(node) {}
|
||||
|
||||
V &operator*() const {
|
||||
assert(Node && "Dereference end()");
|
||||
@ -117,35 +121,43 @@ public:
|
||||
};
|
||||
|
||||
|
||||
template <typename K, typename V>
|
||||
template <typename K, typename V, typename KInfo>
|
||||
class ScopedHashTable {
|
||||
DenseMap<K, ScopedHashTableVal<K,V>*> TopLevelMap;
|
||||
ScopedHashTableScope<K, V> *CurScope;
|
||||
DenseMap<K, ScopedHashTableVal<K, V, KInfo>*, KInfo> TopLevelMap;
|
||||
ScopedHashTableScope<K, V, KInfo> *CurScope;
|
||||
ScopedHashTable(const ScopedHashTable&); // NOT YET IMPLEMENTED
|
||||
void operator=(const ScopedHashTable&); // NOT YET IMPLEMENTED
|
||||
friend class ScopedHashTableScope<K, V>;
|
||||
friend class ScopedHashTableScope<K, V, KInfo>;
|
||||
public:
|
||||
ScopedHashTable() : CurScope(0) {}
|
||||
~ScopedHashTable() {
|
||||
assert(CurScope == 0 && TopLevelMap.empty() && "Scope imbalance!");
|
||||
}
|
||||
|
||||
bool count(const K &Key) const {
|
||||
return TopLevelMap.count(Key);
|
||||
}
|
||||
|
||||
V lookup(const K &Key) {
|
||||
return TopLevelMap[Key].getValue();
|
||||
}
|
||||
|
||||
void insert(const K &Key, const V &Val) {
|
||||
assert(CurScope && "No scope active!");
|
||||
|
||||
ScopedHashTableVal<K,V> *&KeyEntry = TopLevelMap[Key];
|
||||
ScopedHashTableVal<K, V, KInfo> *&KeyEntry = TopLevelMap[Key];
|
||||
|
||||
KeyEntry = new ScopedHashTableVal<K,V>(CurScope->getLastValInScope(),
|
||||
KeyEntry, Key, Val);
|
||||
KeyEntry= new ScopedHashTableVal<K, V, KInfo>(CurScope->getLastValInScope(),
|
||||
KeyEntry, Key, Val);
|
||||
CurScope->setLastValInScope(KeyEntry);
|
||||
}
|
||||
|
||||
typedef ScopedHashTableIterator<K, V> iterator;
|
||||
typedef ScopedHashTableIterator<K, V, KInfo> iterator;
|
||||
|
||||
iterator end() { return iterator(0); }
|
||||
|
||||
iterator begin(const K &Key) {
|
||||
typename DenseMap<K, ScopedHashTableVal<K,V>*>::iterator I =
|
||||
typename DenseMap<K, ScopedHashTableVal<K, V, KInfo>*, KInfo>::iterator I =
|
||||
TopLevelMap.find(Key);
|
||||
if (I == TopLevelMap.end()) return end();
|
||||
return iterator(I->second);
|
||||
@ -154,28 +166,29 @@ public:
|
||||
|
||||
/// ScopedHashTableScope ctor - Install this as the current scope for the hash
|
||||
/// table.
|
||||
template <typename K, typename V>
|
||||
ScopedHashTableScope<K, V>::ScopedHashTableScope(ScopedHashTable<K, V> &ht)
|
||||
: HT(ht) {
|
||||
template <typename K, typename V, typename KInfo>
|
||||
ScopedHashTableScope<K, V, KInfo>::
|
||||
ScopedHashTableScope(ScopedHashTable<K, V, KInfo> &ht) : HT(ht) {
|
||||
PrevScope = HT.CurScope;
|
||||
HT.CurScope = this;
|
||||
LastValInScope = 0;
|
||||
}
|
||||
|
||||
template <typename K, typename V>
|
||||
ScopedHashTableScope<K, V>::~ScopedHashTableScope() {
|
||||
template <typename K, typename V, typename KInfo>
|
||||
ScopedHashTableScope<K, V, KInfo>::~ScopedHashTableScope() {
|
||||
assert(HT.CurScope == this && "Scope imbalance!");
|
||||
HT.CurScope = PrevScope;
|
||||
|
||||
// Pop and delete all values corresponding to this scope.
|
||||
while (ScopedHashTableVal<K, V> *ThisEntry = LastValInScope) {
|
||||
while (ScopedHashTableVal<K, V, KInfo> *ThisEntry = LastValInScope) {
|
||||
// Pop this value out of the TopLevelMap.
|
||||
if (ThisEntry->getNextForKey() == 0) {
|
||||
assert(HT.TopLevelMap[ThisEntry->getKey()] == ThisEntry &&
|
||||
"Scope imbalance!");
|
||||
HT.TopLevelMap.erase(ThisEntry->getKey());
|
||||
} else {
|
||||
ScopedHashTableVal<K,V> *&KeyEntry = HT.TopLevelMap[ThisEntry->getKey()];
|
||||
ScopedHashTableVal<K, V, KInfo> *&KeyEntry =
|
||||
HT.TopLevelMap[ThisEntry->getKey()];
|
||||
assert(KeyEntry == ThisEntry && "Scope imbalance!");
|
||||
KeyEntry = ThisEntry->getNextForKey();
|
||||
}
|
||||
|
@ -18,6 +18,7 @@
|
||||
namespace llvm {
|
||||
template<typename T>
|
||||
class SmallVectorImpl;
|
||||
class APInt;
|
||||
|
||||
/// StringRef - Represent a constant reference to a string, i.e. a character
|
||||
/// array and a length, which need not be null terminated.
|
||||
@ -273,6 +274,19 @@ namespace llvm {
|
||||
|
||||
// TODO: Provide overloads for int/unsigned that check for overflow.
|
||||
|
||||
/// getAsInteger - Parse the current string as an integer of the
|
||||
/// specified radix, or of an autosensed radix if the radix given
|
||||
/// is 0. The current value in Result is discarded, and the
|
||||
/// storage is changed to be wide enough to store the parsed
|
||||
/// integer.
|
||||
///
|
||||
/// Returns true if the string does not solely consist of a valid
|
||||
/// non-empty number in the appropriate base.
|
||||
///
|
||||
/// APInt::fromString is superficially similar but assumes the
|
||||
/// string is well-formed in the given radix.
|
||||
bool getAsInteger(unsigned Radix, APInt &Result) const;
|
||||
|
||||
/// @}
|
||||
/// @name Substring Operations
|
||||
/// @{
|
||||
@ -355,7 +369,7 @@ namespace llvm {
|
||||
/// \param A - Where to put the substrings.
|
||||
/// \param Separator - The string to split on.
|
||||
/// \param MaxSplit - The maximum number of times the string is split.
|
||||
/// \parm KeepEmpty - True if empty substring should be added.
|
||||
/// \param KeepEmpty - True if empty substring should be added.
|
||||
void split(SmallVectorImpl<StringRef> &A,
|
||||
StringRef Separator, int MaxSplit = -1,
|
||||
bool KeepEmpty = true) const;
|
||||
|
@ -73,6 +73,7 @@ public:
|
||||
x86, // X86: i[3-9]86
|
||||
x86_64, // X86-64: amd64, x86_64
|
||||
xcore, // XCore: xcore
|
||||
mblaze, // MBlaze: mblaze
|
||||
|
||||
InvalidArch
|
||||
};
|
||||
|
@ -459,9 +459,11 @@ namespace llvm {
|
||||
if (DbgNode && !isLexicalBlock())
|
||||
DbgNode = 0;
|
||||
}
|
||||
DIScope getContext() const { return getFieldAs<DIScope>(1); }
|
||||
StringRef getDirectory() const { return getContext().getDirectory(); }
|
||||
StringRef getFilename() const { return getContext().getFilename(); }
|
||||
DIScope getContext() const { return getFieldAs<DIScope>(1); }
|
||||
StringRef getDirectory() const { return getContext().getDirectory(); }
|
||||
StringRef getFilename() const { return getContext().getFilename(); }
|
||||
unsigned getLineNumber() const { return getUnsignedField(2); }
|
||||
unsigned getColumnNumber() const { return getUnsignedField(3); }
|
||||
};
|
||||
|
||||
/// DINameSpace - A wrapper for a C++ style name space.
|
||||
@ -636,7 +638,8 @@ namespace llvm {
|
||||
|
||||
/// CreateLexicalBlock - This creates a descriptor for a lexical block
|
||||
/// with the specified parent context.
|
||||
DILexicalBlock CreateLexicalBlock(DIDescriptor Context);
|
||||
DILexicalBlock CreateLexicalBlock(DIDescriptor Context, unsigned Line = 0,
|
||||
unsigned Col = 0);
|
||||
|
||||
/// CreateNameSpace - This creates new descriptor for a namespace
|
||||
/// with the specified parent context.
|
||||
|
@ -52,7 +52,7 @@ protected:
|
||||
Roots(), IsPostDominators(isPostDom) {}
|
||||
public:
|
||||
|
||||
/// getRoots - Return the root blocks of the current CFG. This may include
|
||||
/// getRoots - Return the root blocks of the current CFG. This may include
|
||||
/// multiple blocks if we are computing post dominators. For forward
|
||||
/// dominators, this will always be a single block (the entry node).
|
||||
///
|
||||
@ -225,7 +225,7 @@ protected:
|
||||
DenseMap<NodeT*, InfoRec> Info;
|
||||
|
||||
void reset() {
|
||||
for (typename DomTreeNodeMapType::iterator I = this->DomTreeNodes.begin(),
|
||||
for (typename DomTreeNodeMapType::iterator I = this->DomTreeNodes.begin(),
|
||||
E = DomTreeNodes.end(); I != E; ++I)
|
||||
delete I->second;
|
||||
DomTreeNodes.clear();
|
||||
@ -248,7 +248,7 @@ protected:
|
||||
for (typename GraphTraits<Inverse<N> >::ChildIteratorType PI =
|
||||
GraphTraits<Inverse<N> >::child_begin(NewBB),
|
||||
PE = GraphTraits<Inverse<N> >::child_end(NewBB); PI != PE; ++PI)
|
||||
PredBlocks.push_back(*PI);
|
||||
PredBlocks.push_back(*PI);
|
||||
|
||||
assert(!PredBlocks.empty() && "No predblocks??");
|
||||
|
||||
@ -310,7 +310,7 @@ public:
|
||||
if (DomTreeNodes.size() != OtherDomTreeNodes.size())
|
||||
return true;
|
||||
|
||||
for (typename DomTreeNodeMapType::const_iterator
|
||||
for (typename DomTreeNodeMapType::const_iterator
|
||||
I = this->DomTreeNodes.begin(),
|
||||
E = this->DomTreeNodes.end(); I != E; ++I) {
|
||||
NodeT *BB = I->first;
|
||||
@ -361,7 +361,7 @@ public:
|
||||
return properlyDominates(getNode(A), getNode(B));
|
||||
}
|
||||
|
||||
bool dominatedBySlowTreeWalk(const DomTreeNodeBase<NodeT> *A,
|
||||
bool dominatedBySlowTreeWalk(const DomTreeNodeBase<NodeT> *A,
|
||||
const DomTreeNodeBase<NodeT> *B) const {
|
||||
const DomTreeNodeBase<NodeT> *IDom;
|
||||
if (A == 0 || B == 0) return false;
|
||||
@ -374,7 +374,7 @@ public:
|
||||
/// isReachableFromEntry - Return true if A is dominated by the entry
|
||||
/// block of the function containing it.
|
||||
bool isReachableFromEntry(NodeT* A) {
|
||||
assert (!this->isPostDominator()
|
||||
assert (!this->isPostDominator()
|
||||
&& "This is not implemented for post dominators");
|
||||
return dominates(&A->getParent()->front(), A);
|
||||
}
|
||||
@ -384,7 +384,7 @@ public:
|
||||
///
|
||||
inline bool dominates(const DomTreeNodeBase<NodeT> *A,
|
||||
const DomTreeNodeBase<NodeT> *B) {
|
||||
if (B == A)
|
||||
if (B == A)
|
||||
return true; // A node trivially dominates itself.
|
||||
|
||||
if (A == 0 || B == 0)
|
||||
@ -412,7 +412,7 @@ public:
|
||||
}
|
||||
|
||||
inline bool dominates(const NodeT *A, const NodeT *B) {
|
||||
if (A == B)
|
||||
if (A == B)
|
||||
return true;
|
||||
|
||||
// Cast away the const qualifiers here. This is ok since
|
||||
@ -431,9 +431,9 @@ public:
|
||||
/// for basic block A and B. If there is no such block then return NULL.
|
||||
NodeT *findNearestCommonDominator(NodeT *A, NodeT *B) {
|
||||
|
||||
assert (!this->isPostDominator()
|
||||
assert (!this->isPostDominator()
|
||||
&& "This is not implemented for post dominators");
|
||||
assert (A->getParent() == B->getParent()
|
||||
assert (A->getParent() == B->getParent()
|
||||
&& "Two blocks are not in same function");
|
||||
|
||||
// If either A or B is a entry block then it is nearest common dominator.
|
||||
@ -478,14 +478,14 @@ public:
|
||||
// the CFG...
|
||||
|
||||
/// addNewBlock - Add a new node to the dominator tree information. This
|
||||
/// creates a new node as a child of DomBB dominator node,linking it into
|
||||
/// creates a new node as a child of DomBB dominator node,linking it into
|
||||
/// the children list of the immediate dominator.
|
||||
DomTreeNodeBase<NodeT> *addNewBlock(NodeT *BB, NodeT *DomBB) {
|
||||
assert(getNode(BB) == 0 && "Block already in dominator tree!");
|
||||
DomTreeNodeBase<NodeT> *IDomNode = getNode(DomBB);
|
||||
assert(IDomNode && "Not immediate dominator specified for block!");
|
||||
DFSInfoValid = false;
|
||||
return DomTreeNodes[BB] =
|
||||
return DomTreeNodes[BB] =
|
||||
IDomNode->addChild(new DomTreeNodeBase<NodeT>(BB, IDomNode));
|
||||
}
|
||||
|
||||
@ -503,7 +503,7 @@ public:
|
||||
changeImmediateDominator(getNode(BB), getNode(NewBB));
|
||||
}
|
||||
|
||||
/// eraseNode - Removes a node from the dominator tree. Block must not
|
||||
/// eraseNode - Removes a node from the dominator tree. Block must not
|
||||
/// domiante any other blocks. Removes node from its immediate dominator's
|
||||
/// children list. Deletes dominator node associated with basic block BB.
|
||||
void eraseNode(NodeT *BB) {
|
||||
@ -708,7 +708,7 @@ public:
|
||||
|
||||
DominatorTreeBase<BasicBlock>& getBase() { return *DT; }
|
||||
|
||||
/// getRoots - Return the root blocks of the current CFG. This may include
|
||||
/// getRoots - Return the root blocks of the current CFG. This may include
|
||||
/// multiple blocks if we are computing post dominators. For forward
|
||||
/// dominators, this will always be a single block (the entry node).
|
||||
///
|
||||
@ -785,7 +785,7 @@ public:
|
||||
}
|
||||
|
||||
/// addNewBlock - Add a new node to the dominator tree information. This
|
||||
/// creates a new node as a child of DomBB dominator node,linking it into
|
||||
/// creates a new node as a child of DomBB dominator node,linking it into
|
||||
/// the children list of the immediate dominator.
|
||||
inline DomTreeNode *addNewBlock(BasicBlock *BB, BasicBlock *DomBB) {
|
||||
return DT->addNewBlock(BB, DomBB);
|
||||
@ -802,7 +802,7 @@ public:
|
||||
DT->changeImmediateDominator(N, NewIDom);
|
||||
}
|
||||
|
||||
/// eraseNode - Removes a node from the dominator tree. Block must not
|
||||
/// eraseNode - Removes a node from the dominator tree. Block must not
|
||||
/// domiante any other blocks. Removes node from its immediate dominator's
|
||||
/// children list. Deletes dominator node associated with basic block BB.
|
||||
inline void eraseNode(BasicBlock *BB) {
|
||||
@ -820,7 +820,7 @@ public:
|
||||
}
|
||||
|
||||
|
||||
virtual void releaseMemory() {
|
||||
virtual void releaseMemory() {
|
||||
DT->releaseMemory();
|
||||
}
|
||||
|
||||
@ -886,10 +886,10 @@ protected:
|
||||
const bool IsPostDominators;
|
||||
|
||||
public:
|
||||
DominanceFrontierBase(void *ID, bool isPostDom)
|
||||
DominanceFrontierBase(void *ID, bool isPostDom)
|
||||
: FunctionPass(ID), IsPostDominators(isPostDom) {}
|
||||
|
||||
/// getRoots - Return the root blocks of the current CFG. This may include
|
||||
/// getRoots - Return the root blocks of the current CFG. This may include
|
||||
/// multiple blocks if we are computing post dominators. For forward
|
||||
/// dominators, this will always be a single block (the entry node).
|
||||
///
|
||||
@ -940,7 +940,7 @@ public:
|
||||
bool compareDomSet(DomSetType &DS1, const DomSetType &DS2) const {
|
||||
std::set<BasicBlock *> tmpSet;
|
||||
for (DomSetType::const_iterator I = DS2.begin(),
|
||||
E = DS2.end(); I != E; ++I)
|
||||
E = DS2.end(); I != E; ++I)
|
||||
tmpSet.insert(*I);
|
||||
|
||||
for (DomSetType::const_iterator I = DS1.begin(),
|
||||
@ -965,14 +965,14 @@ public:
|
||||
bool compare(DominanceFrontierBase &Other) const {
|
||||
DomSetMapType tmpFrontiers;
|
||||
for (DomSetMapType::const_iterator I = Other.begin(),
|
||||
E = Other.end(); I != E; ++I)
|
||||
E = Other.end(); I != E; ++I)
|
||||
tmpFrontiers.insert(std::make_pair(I->first, I->second));
|
||||
|
||||
for (DomSetMapType::iterator I = tmpFrontiers.begin(),
|
||||
E = tmpFrontiers.end(); I != E; ) {
|
||||
BasicBlock *Node = I->first;
|
||||
const_iterator DFI = find(Node);
|
||||
if (DFI == end())
|
||||
if (DFI == end())
|
||||
return true;
|
||||
|
||||
if (compareDomSet(I->second, DFI->second))
|
||||
@ -1001,7 +1001,7 @@ public:
|
||||
class DominanceFrontier : public DominanceFrontierBase {
|
||||
public:
|
||||
static char ID; // Pass ID, replacement for typeid
|
||||
DominanceFrontier() :
|
||||
DominanceFrontier() :
|
||||
DominanceFrontierBase(&ID, false) {}
|
||||
|
||||
BasicBlock *getRoot() const {
|
||||
@ -1033,7 +1033,7 @@ public:
|
||||
/// to reflect this change.
|
||||
void changeImmediateDominator(BasicBlock *BB, BasicBlock *NewBB,
|
||||
DominatorTree *DT) {
|
||||
// NewBB is now dominating BB. Which means BB's dominance
|
||||
// NewBB is now dominating BB. Which means BB's dominance
|
||||
// frontier is now part of NewBB's dominance frontier. However, BB
|
||||
// itself is not member of NewBB's dominance frontier.
|
||||
DominanceFrontier::iterator NewDFI = find(NewBB);
|
||||
|
@ -61,7 +61,7 @@ public:
|
||||
Stride = Val;
|
||||
}
|
||||
|
||||
/// getOffset - Return the offset to add to a theoeretical induction
|
||||
/// getOffset - Return the offset to add to a theoretical induction
|
||||
/// variable that starts at zero and counts up by the stride to compute
|
||||
/// the value for the use. This always has the same type as the stride.
|
||||
const SCEV *getOffset() const { return Offset; }
|
||||
@ -116,7 +116,7 @@ private:
|
||||
bool IsUseOfPostIncrementedValue;
|
||||
|
||||
/// Deleted - Implementation of CallbackVH virtual function to
|
||||
/// recieve notification when the User is deleted.
|
||||
/// receive notification when the User is deleted.
|
||||
virtual void deleted();
|
||||
};
|
||||
|
||||
|
@ -835,7 +835,7 @@ public:
|
||||
} else if (BlockLoop != Child) {
|
||||
LoopT *SubLoop = BlockLoop;
|
||||
// Reparent all of the blocks which used to belong to BlockLoops
|
||||
for (unsigned j = 0, e = SubLoop->Blocks.size(); j != e; ++j)
|
||||
for (unsigned j = 0, f = SubLoop->Blocks.size(); j != f; ++j)
|
||||
ContainingLoops[SubLoop->Blocks[j]] = Child;
|
||||
|
||||
// There is already a loop which contains this block, that means
|
||||
|
@ -249,7 +249,7 @@ namespace llvm {
|
||||
SmallPtrSet<Instruction*, 4> > ReverseDepMapType;
|
||||
ReverseDepMapType ReverseLocalDeps;
|
||||
|
||||
// A reverse mapping form dependencies to the non-local dependees.
|
||||
// A reverse mapping from dependencies to the non-local dependees.
|
||||
ReverseDepMapType ReverseNonLocalDeps;
|
||||
|
||||
/// Current AA implementation, just a cache.
|
||||
@ -312,6 +312,11 @@ namespace llvm {
|
||||
/// value and replaces the other value with ptr. This can make Ptr available
|
||||
/// in more places that cached info does not necessarily keep.
|
||||
void invalidateCachedPointerInfo(Value *Ptr);
|
||||
|
||||
/// invalidateCachedPredecessors - Clear the PredIteratorCache info.
|
||||
/// This needs to be done when the CFG changes, e.g., due to splitting
|
||||
/// critical edges.
|
||||
void invalidateCachedPredecessors();
|
||||
|
||||
private:
|
||||
MemDepResult getPointerDependencyFrom(Value *Pointer, uint64_t MemSize,
|
||||
|
@ -66,9 +66,11 @@ public:
|
||||
bool IsPotentiallyPHITranslatable() const;
|
||||
|
||||
/// PHITranslateValue - PHI translate the current address up the CFG from
|
||||
/// CurBB to Pred, updating our state the reflect any needed changes. This
|
||||
/// returns true on failure and sets Addr to null.
|
||||
bool PHITranslateValue(BasicBlock *CurBB, BasicBlock *PredBB);
|
||||
/// CurBB to Pred, updating our state to reflect any needed changes. If the
|
||||
/// dominator tree DT is non-null, the translated value must dominate
|
||||
/// PredBB. This returns true on failure and sets Addr to null.
|
||||
bool PHITranslateValue(BasicBlock *CurBB, BasicBlock *PredBB,
|
||||
const DominatorTree *DT);
|
||||
|
||||
/// PHITranslateWithInsertion - PHI translate this value into the specified
|
||||
/// predecessor block, inserting a computation of the value if it is
|
||||
@ -88,14 +90,8 @@ public:
|
||||
/// returns false.
|
||||
bool Verify() const;
|
||||
private:
|
||||
Value *PHITranslateSubExpr(Value *V, BasicBlock *CurBB, BasicBlock *PredBB);
|
||||
|
||||
|
||||
/// GetAvailablePHITranslatedSubExpr - Return the value computed by
|
||||
/// PHITranslateSubExpr if it dominates PredBB, otherwise return null.
|
||||
Value *GetAvailablePHITranslatedSubExpr(Value *V,
|
||||
BasicBlock *CurBB, BasicBlock *PredBB,
|
||||
const DominatorTree &DT) const;
|
||||
Value *PHITranslateSubExpr(Value *V, BasicBlock *CurBB, BasicBlock *PredBB,
|
||||
const DominatorTree *DT);
|
||||
|
||||
/// InsertPHITranslatedSubExpr - Insert a computation of the PHI translated
|
||||
/// version of 'V' for the edge PredBB->CurBB into the end of the PredBB
|
||||
|
@ -79,13 +79,6 @@ namespace llvm {
|
||||
//
|
||||
FunctionPass *createScalarEvolutionAliasAnalysisPass();
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
//
|
||||
// createAndersensPass - This pass implements Andersen's interprocedural alias
|
||||
// analysis.
|
||||
//
|
||||
ModulePass *createAndersensPass();
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
//
|
||||
// createProfileLoaderPass - This pass loads information from a profile dump
|
||||
|
@ -8,7 +8,7 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The ScalarEvolution class is an LLVM pass which can be used to analyze and
|
||||
// catagorize scalar expressions in loops. It specializes in recognizing
|
||||
// categorize scalar expressions in loops. It specializes in recognizing
|
||||
// general induction variables, representing them with the abstract and opaque
|
||||
// SCEV class. Given this analysis, trip counts of loops and other important
|
||||
// properties can be obtained.
|
||||
@ -55,7 +55,7 @@ namespace llvm {
|
||||
|
||||
protected:
|
||||
/// SubclassData - This field is initialized to zero and may be used in
|
||||
/// subclasses to store miscelaneous information.
|
||||
/// subclasses to store miscellaneous information.
|
||||
unsigned short SubclassData;
|
||||
|
||||
private:
|
||||
@ -177,7 +177,7 @@ namespace llvm {
|
||||
///
|
||||
LoopInfo *LI;
|
||||
|
||||
/// TD - The target data information for the target we are targetting.
|
||||
/// TD - The target data information for the target we are targeting.
|
||||
///
|
||||
TargetData *TD;
|
||||
|
||||
@ -194,7 +194,7 @@ namespace llvm {
|
||||
std::map<SCEVCallbackVH, const SCEV *> Scalars;
|
||||
|
||||
/// BackedgeTakenInfo - Information about the backedge-taken count
|
||||
/// of a loop. This currently inclues an exact count and a maximum count.
|
||||
/// of a loop. This currently includes an exact count and a maximum count.
|
||||
///
|
||||
struct BackedgeTakenInfo {
|
||||
/// Exact - An expression indicating the exact backedge-taken count of
|
||||
@ -305,7 +305,7 @@ namespace llvm {
|
||||
/// ComputeLoadConstantCompareBackedgeTakenCount - Given an exit condition
|
||||
/// of 'icmp op load X, cst', try to see if we can compute the
|
||||
/// backedge-taken count.
|
||||
const SCEV *
|
||||
BackedgeTakenInfo
|
||||
ComputeLoadConstantCompareBackedgeTakenCount(LoadInst *LI,
|
||||
Constant *RHS,
|
||||
const Loop *L,
|
||||
@ -323,12 +323,12 @@ namespace llvm {
|
||||
/// HowFarToZero - Return the number of times a backedge comparing the
|
||||
/// specified value to zero will execute. If not computable, return
|
||||
/// CouldNotCompute.
|
||||
const SCEV *HowFarToZero(const SCEV *V, const Loop *L);
|
||||
BackedgeTakenInfo HowFarToZero(const SCEV *V, const Loop *L);
|
||||
|
||||
/// HowFarToNonZero - Return the number of times a backedge checking the
|
||||
/// specified value for nonzero will execute. If not computable, return
|
||||
/// CouldNotCompute.
|
||||
const SCEV *HowFarToNonZero(const SCEV *V, const Loop *L);
|
||||
BackedgeTakenInfo HowFarToNonZero(const SCEV *V, const Loop *L);
|
||||
|
||||
/// HowManyLessThans - Return the number of times a backedge containing the
|
||||
/// specified less-than comparison will execute. If not computable, return
|
||||
@ -353,14 +353,14 @@ namespace llvm {
|
||||
bool Inverse);
|
||||
|
||||
/// isImpliedCondOperands - Test whether the condition described by Pred,
|
||||
/// LHS, and RHS is true whenever the condition desribed by Pred, FoundLHS,
|
||||
/// LHS, and RHS is true whenever the condition described by Pred, FoundLHS,
|
||||
/// and FoundRHS is true.
|
||||
bool isImpliedCondOperands(ICmpInst::Predicate Pred,
|
||||
const SCEV *LHS, const SCEV *RHS,
|
||||
const SCEV *FoundLHS, const SCEV *FoundRHS);
|
||||
|
||||
/// isImpliedCondOperandsHelper - Test whether the condition described by
|
||||
/// Pred, LHS, and RHS is true whenever the condition desribed by Pred,
|
||||
/// Pred, LHS, and RHS is true whenever the condition described by Pred,
|
||||
/// FoundLHS, and FoundRHS is true.
|
||||
bool isImpliedCondOperandsHelper(ICmpInst::Predicate Pred,
|
||||
const SCEV *LHS, const SCEV *RHS,
|
||||
@ -586,6 +586,11 @@ namespace llvm {
|
||||
/// compute a trip count, or if the loop is deleted.
|
||||
void forgetLoop(const Loop *L);
|
||||
|
||||
/// forgetValue - This method should be called by the client when it has
|
||||
/// changed a value in a way that may effect its value, or which may
|
||||
/// disconnect it from a def-use chain linking it to a loop.
|
||||
void forgetValue(Value *V);
|
||||
|
||||
/// GetMinTrailingZeros - Determine the minimum number of zero bits that S
|
||||
/// is guaranteed to end in (at every loop iteration). It is, at the same
|
||||
/// time, the minimum number of times S is divisible by 2. For example,
|
||||
|
@ -60,11 +60,11 @@ const Attributes NoImplicitFloat = 1<<23; /// disable implicit floating point
|
||||
const Attributes Naked = 1<<24; ///< Naked function
|
||||
const Attributes InlineHint = 1<<25; ///< source said inlining was
|
||||
///desirable
|
||||
const Attributes StackAlignment = 31<<26; ///< Alignment of stack for
|
||||
///function (5 bits) stored as log2
|
||||
///of alignment with +1 bias
|
||||
///0 means unaligned (different from
|
||||
///alignstack(1))
|
||||
const Attributes StackAlignment = 7<<26; ///< Alignment of stack for
|
||||
///function (3 bits) stored as log2
|
||||
///of alignment with +1 bias
|
||||
///0 means unaligned (different from
|
||||
///alignstack(1))
|
||||
|
||||
/// @brief Attributes that only apply to function parameters.
|
||||
const Attributes ParameterOnly = ByVal | Nest | StructRet | NoCapture;
|
||||
@ -118,7 +118,7 @@ inline Attributes constructStackAlignmentFromInt(unsigned i) {
|
||||
return 0;
|
||||
|
||||
assert(isPowerOf2_32(i) && "Alignment must be a power of two.");
|
||||
assert(i <= 0x40000000 && "Alignment too large.");
|
||||
assert(i <= 0x100 && "Alignment too large.");
|
||||
return (Log2_32(i)+1) << 26;
|
||||
}
|
||||
|
||||
|
@ -223,7 +223,7 @@ namespace llvm {
|
||||
void EmitFunctionBody();
|
||||
|
||||
/// EmitInstruction - Targets should implement this to emit instructions.
|
||||
virtual void EmitInstruction(const MachineInstr *MI) {
|
||||
virtual void EmitInstruction(const MachineInstr *) {
|
||||
assert(0 && "EmitInstruction not implemented");
|
||||
}
|
||||
|
||||
@ -356,6 +356,11 @@ namespace llvm {
|
||||
/// printOffset - This is just convenient handler for printing offsets.
|
||||
void printOffset(int64_t Offset) const;
|
||||
|
||||
/// isBlockOnlyReachableByFallthough - Return true if the basic block has
|
||||
/// exactly one predecessor and the control transfer mechanism between
|
||||
/// the predecessor and this block is a fall-through.
|
||||
virtual bool isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const;
|
||||
|
||||
private:
|
||||
|
||||
/// processDebugLoc - Processes the debug information of each machine
|
||||
|
@ -1,414 +0,0 @@
|
||||
//==-llvm/CodeGen/DAGISelHeader.h - Common DAG ISel definitions -*- C++ -*-==//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file provides definitions of the common, target-independent methods and
|
||||
// data, which is used by SelectionDAG-based instruction selectors.
|
||||
//
|
||||
// *** NOTE: This file is #included into the middle of the target
|
||||
// instruction selector class. These functions are really methods.
|
||||
// This is a little awkward, but it allows this code to be shared
|
||||
// by all the targets while still being able to call into
|
||||
// target-specific code without using a virtual function call.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CODEGEN_DAGISEL_HEADER_H
|
||||
#define LLVM_CODEGEN_DAGISEL_HEADER_H
|
||||
|
||||
/// ISelPosition - Node iterator marking the current position of
|
||||
/// instruction selection as it procedes through the topologically-sorted
|
||||
/// node list.
|
||||
SelectionDAG::allnodes_iterator ISelPosition;
|
||||
|
||||
/// IsChainCompatible - Returns true if Chain is Op or Chain does
|
||||
/// not reach Op.
|
||||
static bool IsChainCompatible(SDNode *Chain, SDNode *Op) {
|
||||
if (Chain->getOpcode() == ISD::EntryToken)
|
||||
return true;
|
||||
if (Chain->getOpcode() == ISD::TokenFactor)
|
||||
return false;
|
||||
if (Chain->getNumOperands() > 0) {
|
||||
SDValue C0 = Chain->getOperand(0);
|
||||
if (C0.getValueType() == MVT::Other)
|
||||
return C0.getNode() != Op && IsChainCompatible(C0.getNode(), Op);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// ISelUpdater - helper class to handle updates of the
|
||||
/// instruciton selection graph.
|
||||
class VISIBILITY_HIDDEN ISelUpdater : public SelectionDAG::DAGUpdateListener {
|
||||
SelectionDAG::allnodes_iterator &ISelPosition;
|
||||
public:
|
||||
explicit ISelUpdater(SelectionDAG::allnodes_iterator &isp)
|
||||
: ISelPosition(isp) {}
|
||||
|
||||
/// NodeDeleted - Handle nodes deleted from the graph. If the
|
||||
/// node being deleted is the current ISelPosition node, update
|
||||
/// ISelPosition.
|
||||
///
|
||||
virtual void NodeDeleted(SDNode *N, SDNode *E) {
|
||||
if (ISelPosition == SelectionDAG::allnodes_iterator(N))
|
||||
++ISelPosition;
|
||||
}
|
||||
|
||||
/// NodeUpdated - Ignore updates for now.
|
||||
virtual void NodeUpdated(SDNode *N) {}
|
||||
};
|
||||
|
||||
/// ReplaceUses - replace all uses of the old node F with the use
|
||||
/// of the new node T.
|
||||
DISABLE_INLINE void ReplaceUses(SDValue F, SDValue T) {
|
||||
ISelUpdater ISU(ISelPosition);
|
||||
CurDAG->ReplaceAllUsesOfValueWith(F, T, &ISU);
|
||||
}
|
||||
|
||||
/// ReplaceUses - replace all uses of the old nodes F with the use
|
||||
/// of the new nodes T.
|
||||
DISABLE_INLINE void ReplaceUses(const SDValue *F, const SDValue *T,
|
||||
unsigned Num) {
|
||||
ISelUpdater ISU(ISelPosition);
|
||||
CurDAG->ReplaceAllUsesOfValuesWith(F, T, Num, &ISU);
|
||||
}
|
||||
|
||||
/// ReplaceUses - replace all uses of the old node F with the use
|
||||
/// of the new node T.
|
||||
DISABLE_INLINE void ReplaceUses(SDNode *F, SDNode *T) {
|
||||
ISelUpdater ISU(ISelPosition);
|
||||
CurDAG->ReplaceAllUsesWith(F, T, &ISU);
|
||||
}
|
||||
|
||||
/// SelectRoot - Top level entry to DAG instruction selector.
|
||||
/// Selects instructions starting at the root of the current DAG.
|
||||
void SelectRoot(SelectionDAG &DAG) {
|
||||
SelectRootInit();
|
||||
|
||||
// Create a dummy node (which is not added to allnodes), that adds
|
||||
// a reference to the root node, preventing it from being deleted,
|
||||
// and tracking any changes of the root.
|
||||
HandleSDNode Dummy(CurDAG->getRoot());
|
||||
ISelPosition = llvm::next(SelectionDAG::allnodes_iterator(CurDAG->getRoot().getNode()));
|
||||
|
||||
// The AllNodes list is now topological-sorted. Visit the
|
||||
// nodes by starting at the end of the list (the root of the
|
||||
// graph) and preceding back toward the beginning (the entry
|
||||
// node).
|
||||
while (ISelPosition != CurDAG->allnodes_begin()) {
|
||||
SDNode *Node = --ISelPosition;
|
||||
// Skip dead nodes. DAGCombiner is expected to eliminate all dead nodes,
|
||||
// but there are currently some corner cases that it misses. Also, this
|
||||
// makes it theoretically possible to disable the DAGCombiner.
|
||||
if (Node->use_empty())
|
||||
continue;
|
||||
#if 0
|
||||
DAG.setSubgraphColor(Node, "red");
|
||||
#endif
|
||||
SDNode *ResNode = Select(Node);
|
||||
// If node should not be replaced, continue with the next one.
|
||||
if (ResNode == Node)
|
||||
continue;
|
||||
// Replace node.
|
||||
if (ResNode) {
|
||||
#if 0
|
||||
DAG.setSubgraphColor(ResNode, "yellow");
|
||||
DAG.setSubgraphColor(ResNode, "black");
|
||||
#endif
|
||||
ReplaceUses(Node, ResNode);
|
||||
}
|
||||
// If after the replacement this node is not used any more,
|
||||
// remove this dead node.
|
||||
if (Node->use_empty()) { // Don't delete EntryToken, etc.
|
||||
ISelUpdater ISU(ISelPosition);
|
||||
CurDAG->RemoveDeadNode(Node, &ISU);
|
||||
}
|
||||
}
|
||||
|
||||
CurDAG->setRoot(Dummy.getValue());
|
||||
}
|
||||
|
||||
|
||||
/// CheckInteger - Return true if the specified node is not a ConstantSDNode or
|
||||
/// if it doesn't have the specified value.
|
||||
static bool CheckInteger(SDValue V, int64_t Val) {
|
||||
ConstantSDNode *C = dyn_cast<ConstantSDNode>(V);
|
||||
return C == 0 || C->getSExtValue() != Val;
|
||||
}
|
||||
|
||||
/// CheckAndImmediate - Check to see if the specified node is an and with an
|
||||
/// immediate returning true on failure.
|
||||
///
|
||||
/// FIXME: Inline this gunk into CheckAndMask.
|
||||
bool CheckAndImmediate(SDValue V, int64_t Val) {
|
||||
if (V->getOpcode() == ISD::AND)
|
||||
if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(V->getOperand(1)))
|
||||
if (CheckAndMask(V.getOperand(0), C, Val))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// CheckOrImmediate - Check to see if the specified node is an or with an
|
||||
/// immediate returning true on failure.
|
||||
///
|
||||
/// FIXME: Inline this gunk into CheckOrMask.
|
||||
bool CheckOrImmediate(SDValue V, int64_t Val) {
|
||||
if (V->getOpcode() == ISD::OR)
|
||||
if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(V->getOperand(1)))
|
||||
if (CheckOrMask(V.getOperand(0), C, Val))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// These functions are marked always inline so that Idx doesn't get pinned to
|
||||
// the stack.
|
||||
ALWAYS_INLINE static int8_t
|
||||
GetInt1(const unsigned char *MatcherTable, unsigned &Idx) {
|
||||
return MatcherTable[Idx++];
|
||||
}
|
||||
|
||||
ALWAYS_INLINE static int16_t
|
||||
GetInt2(const unsigned char *MatcherTable, unsigned &Idx) {
|
||||
int16_t Val = GetInt1(MatcherTable, Idx);
|
||||
Val |= int16_t(GetInt1(MatcherTable, Idx)) << 8;
|
||||
return Val;
|
||||
}
|
||||
|
||||
ALWAYS_INLINE static int32_t
|
||||
GetInt4(const unsigned char *MatcherTable, unsigned &Idx) {
|
||||
int32_t Val = GetInt2(MatcherTable, Idx);
|
||||
Val |= int32_t(GetInt2(MatcherTable, Idx)) << 16;
|
||||
return Val;
|
||||
}
|
||||
|
||||
ALWAYS_INLINE static int64_t
|
||||
GetInt8(const unsigned char *MatcherTable, unsigned &Idx) {
|
||||
int64_t Val = GetInt4(MatcherTable, Idx);
|
||||
Val |= int64_t(GetInt4(MatcherTable, Idx)) << 32;
|
||||
return Val;
|
||||
}
|
||||
|
||||
enum BuiltinOpcodes {
|
||||
OPC_Emit,
|
||||
OPC_Push,
|
||||
OPC_Record,
|
||||
OPC_MoveChild,
|
||||
OPC_MoveParent,
|
||||
OPC_CheckSame,
|
||||
OPC_CheckPatternPredicate,
|
||||
OPC_CheckPredicate,
|
||||
OPC_CheckOpcode,
|
||||
OPC_CheckType,
|
||||
OPC_CheckInteger1, OPC_CheckInteger2, OPC_CheckInteger4, OPC_CheckInteger8,
|
||||
OPC_CheckCondCode,
|
||||
OPC_CheckValueType,
|
||||
OPC_CheckComplexPat,
|
||||
OPC_CheckAndImm1, OPC_CheckAndImm2, OPC_CheckAndImm4, OPC_CheckAndImm8,
|
||||
OPC_CheckOrImm1, OPC_CheckOrImm2, OPC_CheckOrImm4, OPC_CheckOrImm8,
|
||||
OPC_IsProfitableToFold,
|
||||
OPC_IsLegalToFold
|
||||
};
|
||||
|
||||
struct MatchScope {
|
||||
/// FailIndex - If this match fails, this is the index to continue with.
|
||||
unsigned FailIndex;
|
||||
|
||||
/// NodeStackSize - The size of the node stack when the scope was formed.
|
||||
unsigned NodeStackSize;
|
||||
|
||||
/// NumRecordedNodes - The number of recorded nodes when the scope was formed.
|
||||
unsigned NumRecordedNodes;
|
||||
};
|
||||
|
||||
SDNode *SelectCodeCommon(SDNode *NodeToMatch, const unsigned char *MatcherTable,
|
||||
unsigned TableSize) {
|
||||
switch (NodeToMatch->getOpcode()) {
|
||||
default:
|
||||
break;
|
||||
case ISD::EntryToken: // These nodes remain the same.
|
||||
case ISD::BasicBlock:
|
||||
case ISD::Register:
|
||||
case ISD::HANDLENODE:
|
||||
case ISD::TargetConstant:
|
||||
case ISD::TargetConstantFP:
|
||||
case ISD::TargetConstantPool:
|
||||
case ISD::TargetFrameIndex:
|
||||
case ISD::TargetExternalSymbol:
|
||||
case ISD::TargetBlockAddress:
|
||||
case ISD::TargetJumpTable:
|
||||
case ISD::TargetGlobalTLSAddress:
|
||||
case ISD::TargetGlobalAddress:
|
||||
case ISD::TokenFactor:
|
||||
case ISD::CopyFromReg:
|
||||
case ISD::CopyToReg:
|
||||
return 0;
|
||||
case ISD::AssertSext:
|
||||
case ISD::AssertZext:
|
||||
ReplaceUses(SDValue(NodeToMatch, 0), NodeToMatch->getOperand(0));
|
||||
return 0;
|
||||
case ISD::INLINEASM: return Select_INLINEASM(NodeToMatch);
|
||||
case ISD::EH_LABEL: return Select_EH_LABEL(NodeToMatch);
|
||||
case ISD::UNDEF: return Select_UNDEF(NodeToMatch);
|
||||
}
|
||||
|
||||
assert(!NodeToMatch->isMachineOpcode() && "Node already selected!");
|
||||
|
||||
SmallVector<MatchScope, 8> MatchScopes;
|
||||
|
||||
// RecordedNodes - This is the set of nodes that have been recorded by the
|
||||
// state machine.
|
||||
SmallVector<SDValue, 8> RecordedNodes;
|
||||
|
||||
// Set up the node stack with NodeToMatch as the only node on the stack.
|
||||
SmallVector<SDValue, 8> NodeStack;
|
||||
SDValue N = SDValue(NodeToMatch, 0);
|
||||
NodeStack.push_back(N);
|
||||
|
||||
// Interpreter starts at opcode #0.
|
||||
unsigned MatcherIndex = 0;
|
||||
while (1) {
|
||||
assert(MatcherIndex < TableSize && "Invalid index");
|
||||
switch ((BuiltinOpcodes)MatcherTable[MatcherIndex++]) {
|
||||
case OPC_Emit: {
|
||||
errs() << "EMIT NODE\n";
|
||||
return 0;
|
||||
}
|
||||
case OPC_Push: {
|
||||
unsigned NumToSkip = MatcherTable[MatcherIndex++];
|
||||
MatchScope NewEntry;
|
||||
NewEntry.FailIndex = MatcherIndex+NumToSkip;
|
||||
NewEntry.NodeStackSize = NodeStack.size();
|
||||
NewEntry.NumRecordedNodes = RecordedNodes.size();
|
||||
MatchScopes.push_back(NewEntry);
|
||||
continue;
|
||||
}
|
||||
case OPC_Record:
|
||||
// Remember this node, it may end up being an operand in the pattern.
|
||||
RecordedNodes.push_back(N);
|
||||
continue;
|
||||
|
||||
case OPC_MoveChild: {
|
||||
unsigned Child = MatcherTable[MatcherIndex++];
|
||||
if (Child >= N.getNumOperands())
|
||||
break; // Match fails if out of range child #.
|
||||
N = N.getOperand(Child);
|
||||
NodeStack.push_back(N);
|
||||
continue;
|
||||
}
|
||||
|
||||
case OPC_MoveParent:
|
||||
// Pop the current node off the NodeStack.
|
||||
NodeStack.pop_back();
|
||||
assert(!NodeStack.empty() && "Node stack imbalance!");
|
||||
N = NodeStack.back();
|
||||
continue;
|
||||
|
||||
case OPC_CheckSame: {
|
||||
// Accept if it is exactly the same as a previously recorded node.
|
||||
unsigned RecNo = MatcherTable[MatcherIndex++];
|
||||
assert(RecNo < RecordedNodes.size() && "Invalid CheckSame");
|
||||
if (N != RecordedNodes[RecNo]) break;
|
||||
continue;
|
||||
}
|
||||
case OPC_CheckPatternPredicate:
|
||||
if (!CheckPatternPredicate(MatcherTable[MatcherIndex++])) break;
|
||||
continue;
|
||||
case OPC_CheckPredicate:
|
||||
if (!CheckNodePredicate(N.getNode(), MatcherTable[MatcherIndex++])) break;
|
||||
continue;
|
||||
case OPC_CheckComplexPat: {
|
||||
unsigned PatNo = MatcherTable[MatcherIndex++];
|
||||
(void)PatNo;
|
||||
// FIXME: CHECK IT.
|
||||
continue;
|
||||
}
|
||||
|
||||
case OPC_CheckOpcode:
|
||||
if (N->getOpcode() != MatcherTable[MatcherIndex++]) break;
|
||||
continue;
|
||||
case OPC_CheckType:
|
||||
if (N.getValueType() !=
|
||||
(MVT::SimpleValueType)MatcherTable[MatcherIndex++]) break;
|
||||
continue;
|
||||
case OPC_CheckCondCode:
|
||||
if (cast<CondCodeSDNode>(N)->get() !=
|
||||
(ISD::CondCode)MatcherTable[MatcherIndex++]) break;
|
||||
continue;
|
||||
case OPC_CheckValueType:
|
||||
if (cast<VTSDNode>(N)->getVT() !=
|
||||
(MVT::SimpleValueType)MatcherTable[MatcherIndex++]) break;
|
||||
continue;
|
||||
|
||||
case OPC_CheckInteger1:
|
||||
if (CheckInteger(N, GetInt1(MatcherTable, MatcherIndex))) break;
|
||||
continue;
|
||||
case OPC_CheckInteger2:
|
||||
if (CheckInteger(N, GetInt2(MatcherTable, MatcherIndex))) break;
|
||||
continue;
|
||||
case OPC_CheckInteger4:
|
||||
if (CheckInteger(N, GetInt4(MatcherTable, MatcherIndex))) break;
|
||||
continue;
|
||||
case OPC_CheckInteger8:
|
||||
if (CheckInteger(N, GetInt8(MatcherTable, MatcherIndex))) break;
|
||||
continue;
|
||||
|
||||
case OPC_CheckAndImm1:
|
||||
if (CheckAndImmediate(N, GetInt1(MatcherTable, MatcherIndex))) break;
|
||||
continue;
|
||||
case OPC_CheckAndImm2:
|
||||
if (CheckAndImmediate(N, GetInt2(MatcherTable, MatcherIndex))) break;
|
||||
continue;
|
||||
case OPC_CheckAndImm4:
|
||||
if (CheckAndImmediate(N, GetInt4(MatcherTable, MatcherIndex))) break;
|
||||
continue;
|
||||
case OPC_CheckAndImm8:
|
||||
if (CheckAndImmediate(N, GetInt8(MatcherTable, MatcherIndex))) break;
|
||||
continue;
|
||||
|
||||
case OPC_CheckOrImm1:
|
||||
if (CheckOrImmediate(N, GetInt1(MatcherTable, MatcherIndex))) break;
|
||||
continue;
|
||||
case OPC_CheckOrImm2:
|
||||
if (CheckOrImmediate(N, GetInt2(MatcherTable, MatcherIndex))) break;
|
||||
continue;
|
||||
case OPC_CheckOrImm4:
|
||||
if (CheckOrImmediate(N, GetInt4(MatcherTable, MatcherIndex))) break;
|
||||
continue;
|
||||
case OPC_CheckOrImm8:
|
||||
if (CheckOrImmediate(N, GetInt8(MatcherTable, MatcherIndex))) break;
|
||||
continue;
|
||||
|
||||
case OPC_IsProfitableToFold:
|
||||
assert(!NodeStack.size() == 1 && "No parent node");
|
||||
if (!IsProfitableToFold(N, NodeStack[NodeStack.size()-2].getNode(),
|
||||
NodeToMatch))
|
||||
break;
|
||||
continue;
|
||||
case OPC_IsLegalToFold:
|
||||
assert(!NodeStack.size() == 1 && "No parent node");
|
||||
if (!IsLegalToFold(N, NodeStack[NodeStack.size()-2].getNode(),
|
||||
NodeToMatch))
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
|
||||
// If the code reached this point, then the match failed pop out to the next
|
||||
// match scope.
|
||||
if (MatchScopes.empty()) {
|
||||
CannotYetSelect(NodeToMatch);
|
||||
return 0;
|
||||
}
|
||||
|
||||
RecordedNodes.resize(MatchScopes.back().NumRecordedNodes);
|
||||
NodeStack.resize(MatchScopes.back().NodeStackSize);
|
||||
MatcherIndex = MatchScopes.back().FailIndex;
|
||||
MatchScopes.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif /* LLVM_CODEGEN_DAGISEL_HEADER_H */
|
@ -569,6 +569,16 @@ namespace llvm {
|
||||
///
|
||||
unsigned getSize() const;
|
||||
|
||||
/// isSpillable - Can this interval be spilled?
|
||||
bool isSpillable() const {
|
||||
return weight != HUGE_VALF;
|
||||
}
|
||||
|
||||
/// markNotSpillable - Mark interval as not spillable
|
||||
void markNotSpillable() {
|
||||
weight = HUGE_VALF;
|
||||
}
|
||||
|
||||
/// ComputeJoinedWeight - Set the weight of a live interval after
|
||||
/// Other has been merged into it.
|
||||
void ComputeJoinedWeight(const LiveInterval &Other);
|
||||
|
@ -70,8 +70,15 @@ namespace llvm {
|
||||
static char ID; // Pass identification, replacement for typeid
|
||||
LiveIntervals() : MachineFunctionPass(&ID) {}
|
||||
|
||||
static float getSpillWeight(bool isDef, bool isUse, unsigned loopDepth) {
|
||||
return (isDef + isUse) * powf(10.0F, (float)loopDepth);
|
||||
// Calculate the spill weight to assign to a single instruction.
|
||||
static float getSpillWeight(bool isDef, bool isUse, unsigned loopDepth);
|
||||
|
||||
// After summing the spill weights of all defs and uses, the final weight
|
||||
// should be normalized, dividing the weight of the interval by its size.
|
||||
// This encourages spilling of intervals that are large and have few uses,
|
||||
// and discourages spilling of small intervals with many uses.
|
||||
void normalizeSpillWeight(LiveInterval &li) {
|
||||
li.weight /= getApproximateInstructionCount(li) + 25;
|
||||
}
|
||||
|
||||
typedef Reg2IntervalMap::iterator iterator;
|
||||
@ -409,6 +416,9 @@ namespace llvm {
|
||||
DenseMap<unsigned,unsigned> &MBBVRegsMap,
|
||||
std::vector<LiveInterval*> &NewLIs);
|
||||
|
||||
// Normalize the spill weight of all the intervals in NewLIs.
|
||||
void normalizeSpillWeights(std::vector<LiveInterval*> &NewLIs);
|
||||
|
||||
static LiveInterval* createInterval(unsigned Reg);
|
||||
|
||||
void printInstrs(raw_ostream &O) const;
|
||||
|
@ -124,6 +124,11 @@ private:
|
||||
///
|
||||
std::vector<VarInfo> VirtRegInfo;
|
||||
|
||||
/// PHIJoins - list of virtual registers that are PHI joins. These registers
|
||||
/// may have multiple definitions, and they require special handling when
|
||||
/// building live intervals.
|
||||
SparseBitVector<> PHIJoins;
|
||||
|
||||
/// ReservedRegisters - This vector keeps track of which registers
|
||||
/// are reserved register which are not allocatable by the target machine.
|
||||
/// We can not track liveness for values that are in this set.
|
||||
@ -295,6 +300,12 @@ public:
|
||||
void addNewBlock(MachineBasicBlock *BB,
|
||||
MachineBasicBlock *DomBB,
|
||||
MachineBasicBlock *SuccBB);
|
||||
|
||||
/// isPHIJoin - Return true if Reg is a phi join register.
|
||||
bool isPHIJoin(unsigned Reg) { return PHIJoins.test(Reg); }
|
||||
|
||||
/// setPHIJoin - Mark Reg as a phi join register.
|
||||
void setPHIJoin(unsigned Reg) { PHIJoins.set(Reg); }
|
||||
};
|
||||
|
||||
} // End llvm namespace
|
||||
|
@ -285,11 +285,6 @@ public:
|
||||
/// it returns end()
|
||||
iterator getFirstTerminator();
|
||||
|
||||
/// isOnlyReachableViaFallthough - Return true if this basic block has
|
||||
/// exactly one predecessor and the control transfer mechanism between
|
||||
/// the predecessor and this block is a fall-through.
|
||||
bool isOnlyReachableByFallthrough() const;
|
||||
|
||||
void pop_front() { Insts.pop_front(); }
|
||||
void pop_back() { Insts.pop_back(); }
|
||||
void push_back(MachineInstr *MI) { Insts.push_back(MI); }
|
||||
|
@ -179,17 +179,16 @@ public:
|
||||
return MemRefsEnd - MemRefs == 1;
|
||||
}
|
||||
|
||||
enum MICheckType {
|
||||
CheckDefs, // Check all operands for equality
|
||||
IgnoreDefs, // Ignore all definitions
|
||||
IgnoreVRegDefs // Ignore virtual register definitions
|
||||
};
|
||||
|
||||
/// isIdenticalTo - Return true if this instruction is identical to (same
|
||||
/// opcode and same operands as) the specified instruction.
|
||||
bool isIdenticalTo(const MachineInstr *Other) const {
|
||||
if (Other->getOpcode() != getOpcode() ||
|
||||
Other->getNumOperands() != getNumOperands())
|
||||
return false;
|
||||
for (unsigned i = 0, e = getNumOperands(); i != e; ++i)
|
||||
if (!getOperand(i).isIdenticalTo(Other->getOperand(i)))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
bool isIdenticalTo(const MachineInstr *Other,
|
||||
MICheckType Check = CheckDefs) const;
|
||||
|
||||
/// removeFromParent - This method unlinks 'this' from the containing basic
|
||||
/// block, and returns it, but does not delete it.
|
||||
@ -331,13 +330,13 @@ public:
|
||||
/// isSafeToMove - Return true if it is safe to move this instruction. If
|
||||
/// SawStore is set to true, it means that there is a store (or call) between
|
||||
/// the instruction's location and its intended destination.
|
||||
bool isSafeToMove(const TargetInstrInfo *TII, bool &SawStore,
|
||||
AliasAnalysis *AA) const;
|
||||
bool isSafeToMove(const TargetInstrInfo *TII, AliasAnalysis *AA,
|
||||
bool &SawStore) const;
|
||||
|
||||
/// isSafeToReMat - Return true if it's safe to rematerialize the specified
|
||||
/// instruction which defined the specified register instead of copying it.
|
||||
bool isSafeToReMat(const TargetInstrInfo *TII, unsigned DstReg,
|
||||
AliasAnalysis *AA) const;
|
||||
bool isSafeToReMat(const TargetInstrInfo *TII, AliasAnalysis *AA,
|
||||
unsigned DstReg) const;
|
||||
|
||||
/// hasVolatileMemoryRef - Return true if this instruction may have a
|
||||
/// volatile memory reference, or if the information describing the
|
||||
|
@ -127,7 +127,7 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
const MachineInstrBuilder &addMetadata(MDNode *MD) const {
|
||||
const MachineInstrBuilder &addMetadata(const MDNode *MD) const {
|
||||
MI->addOperand(MachineOperand::CreateMetadata(MD));
|
||||
return *this;
|
||||
}
|
||||
|
@ -19,14 +19,14 @@
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class ConstantFP;
|
||||
class BlockAddress;
|
||||
class MachineBasicBlock;
|
||||
class ConstantFP;
|
||||
class GlobalValue;
|
||||
class MachineBasicBlock;
|
||||
class MachineInstr;
|
||||
class TargetMachine;
|
||||
class MachineRegisterInfo;
|
||||
class MDNode;
|
||||
class TargetMachine;
|
||||
class raw_ostream;
|
||||
|
||||
/// MachineOperand class - Representation of each machine instruction operand.
|
||||
@ -100,7 +100,7 @@ private:
|
||||
MachineBasicBlock *MBB; // For MO_MachineBasicBlock.
|
||||
const ConstantFP *CFP; // For MO_FPImmediate.
|
||||
int64_t ImmVal; // For MO_Immediate.
|
||||
MDNode *MD; // For MO_Metadata.
|
||||
const MDNode *MD; // For MO_Metadata.
|
||||
|
||||
struct { // For MO_Register.
|
||||
unsigned RegNo;
|
||||
@ -467,7 +467,7 @@ public:
|
||||
Op.setTargetFlags(TargetFlags);
|
||||
return Op;
|
||||
}
|
||||
static MachineOperand CreateMetadata(MDNode *Meta) {
|
||||
static MachineOperand CreateMetadata(const MDNode *Meta) {
|
||||
MachineOperand Op(MachineOperand::MO_Metadata);
|
||||
Op.Contents.MD = Meta;
|
||||
return Op;
|
||||
|
@ -162,6 +162,10 @@ namespace llvm {
|
||||
///
|
||||
FunctionPass *createGCInfoPrinter(raw_ostream &OS);
|
||||
|
||||
/// createMachineCSEPass - This pass performs global CSE on machine
|
||||
/// instructions.
|
||||
FunctionPass *createMachineCSEPass();
|
||||
|
||||
/// createMachineLICMPass - This pass performs LICM on machine instructions.
|
||||
///
|
||||
FunctionPass *createMachineLICMPass();
|
||||
@ -187,7 +191,7 @@ namespace llvm {
|
||||
/// createMachineVerifierPass - This pass verifies cenerated machine code
|
||||
/// instructions for correctness.
|
||||
///
|
||||
/// @param allowPhysDoubleDefs ignore double definitions of
|
||||
/// @param allowDoubleDefs ignore double definitions of
|
||||
/// registers. Useful before LiveVariables has run.
|
||||
FunctionPass *createMachineVerifierPass(bool allowDoubleDefs);
|
||||
|
||||
|
@ -668,27 +668,8 @@ public:
|
||||
SDNode *SelectNodeTo(SDNode *N, unsigned TargetOpc, SDVTList VTs,
|
||||
const SDValue *Ops, unsigned NumOps);
|
||||
|
||||
/// MorphNodeTo - These *mutate* the specified node to have the specified
|
||||
/// MorphNodeTo - This *mutates* the specified node to have the specified
|
||||
/// return type, opcode, and operands.
|
||||
SDNode *MorphNodeTo(SDNode *N, unsigned Opc, EVT VT);
|
||||
SDNode *MorphNodeTo(SDNode *N, unsigned Opc, EVT VT, SDValue Op1);
|
||||
SDNode *MorphNodeTo(SDNode *N, unsigned Opc, EVT VT,
|
||||
SDValue Op1, SDValue Op2);
|
||||
SDNode *MorphNodeTo(SDNode *N, unsigned Opc, EVT VT,
|
||||
SDValue Op1, SDValue Op2, SDValue Op3);
|
||||
SDNode *MorphNodeTo(SDNode *N, unsigned Opc, EVT VT,
|
||||
const SDValue *Ops, unsigned NumOps);
|
||||
SDNode *MorphNodeTo(SDNode *N, unsigned Opc, EVT VT1, EVT VT2);
|
||||
SDNode *MorphNodeTo(SDNode *N, unsigned Opc, EVT VT1,
|
||||
EVT VT2, const SDValue *Ops, unsigned NumOps);
|
||||
SDNode *MorphNodeTo(SDNode *N, unsigned Opc, EVT VT1,
|
||||
EVT VT2, EVT VT3, const SDValue *Ops, unsigned NumOps);
|
||||
SDNode *MorphNodeTo(SDNode *N, unsigned Opc, EVT VT1,
|
||||
EVT VT2, SDValue Op1);
|
||||
SDNode *MorphNodeTo(SDNode *N, unsigned Opc, EVT VT1,
|
||||
EVT VT2, SDValue Op1, SDValue Op2);
|
||||
SDNode *MorphNodeTo(SDNode *N, unsigned Opc, EVT VT1,
|
||||
EVT VT2, SDValue Op1, SDValue Op2, SDValue Op3);
|
||||
SDNode *MorphNodeTo(SDNode *N, unsigned Opc, SDVTList VTs,
|
||||
const SDValue *Ops, unsigned NumOps);
|
||||
|
||||
@ -898,6 +879,15 @@ public:
|
||||
/// isKnownNeverNan - Test whether the given SDValue is known to never be NaN.
|
||||
bool isKnownNeverNaN(SDValue Op) const;
|
||||
|
||||
/// isKnownNeverZero - Test whether the given SDValue is known to never be
|
||||
/// positive or negative Zero.
|
||||
bool isKnownNeverZero(SDValue Op) const;
|
||||
|
||||
/// isEqualTo - Test whether two SDValues are known to compare equal. This
|
||||
/// is true if they are the same value, or if one is negative zero and the
|
||||
/// other positive zero.
|
||||
bool isEqualTo(SDValue A, SDValue B) const;
|
||||
|
||||
/// isVerifiedDebugInfoDesc - Returns true if the specified SDValue has
|
||||
/// been verified as a debug information descriptor.
|
||||
bool isVerifiedDebugInfoDesc(SDValue Op) const;
|
||||
|
@ -68,12 +68,18 @@ public:
|
||||
unsigned MakeReg(EVT VT);
|
||||
|
||||
virtual void EmitFunctionEntryCode(Function &Fn, MachineFunction &MF) {}
|
||||
virtual void InstructionSelect() = 0;
|
||||
|
||||
void SelectRootInit() {
|
||||
DAGSize = CurDAG->AssignTopologicalOrder();
|
||||
}
|
||||
|
||||
/// PreprocessISelDAG - This hook allows targets to hack on the graph before
|
||||
/// instruction selection starts.
|
||||
virtual void PreprocessISelDAG() {}
|
||||
|
||||
/// PostprocessISelDAG() - This hook allows the target to hack on the graph
|
||||
/// right after selection.
|
||||
virtual void PostprocessISelDAG() {}
|
||||
|
||||
/// Select - Main hook targets implement to select a node.
|
||||
virtual SDNode *Select(SDNode *N) = 0;
|
||||
|
||||
/// SelectInlineAsmMemoryOperand - Select the specified address as a target
|
||||
/// addressing mode, according to the specified constraint code. If this does
|
||||
/// not match or is not implemented, return true. The resultant operands
|
||||
@ -91,21 +97,138 @@ public:
|
||||
|
||||
/// IsLegalToFold - Returns true if the specific operand node N of
|
||||
/// U can be folded during instruction selection that starts at Root.
|
||||
virtual bool IsLegalToFold(SDValue N, SDNode *U, SDNode *Root) const;
|
||||
bool IsLegalToFold(SDValue N, SDNode *U, SDNode *Root,
|
||||
bool IgnoreChains = false) const;
|
||||
|
||||
/// CreateTargetHazardRecognizer - Return a newly allocated hazard recognizer
|
||||
/// to use for this target when scheduling the DAG.
|
||||
virtual ScheduleHazardRecognizer *CreateTargetHazardRecognizer();
|
||||
|
||||
|
||||
// Opcodes used by the DAG state machine:
|
||||
enum BuiltinOpcodes {
|
||||
OPC_Scope,
|
||||
OPC_RecordNode,
|
||||
OPC_RecordChild0, OPC_RecordChild1, OPC_RecordChild2, OPC_RecordChild3,
|
||||
OPC_RecordChild4, OPC_RecordChild5, OPC_RecordChild6, OPC_RecordChild7,
|
||||
OPC_RecordMemRef,
|
||||
OPC_CaptureFlagInput,
|
||||
OPC_MoveChild,
|
||||
OPC_MoveParent,
|
||||
OPC_CheckSame,
|
||||
OPC_CheckPatternPredicate,
|
||||
OPC_CheckPredicate,
|
||||
OPC_CheckOpcode,
|
||||
OPC_SwitchOpcode,
|
||||
OPC_CheckType,
|
||||
OPC_SwitchType,
|
||||
OPC_CheckChild0Type, OPC_CheckChild1Type, OPC_CheckChild2Type,
|
||||
OPC_CheckChild3Type, OPC_CheckChild4Type, OPC_CheckChild5Type,
|
||||
OPC_CheckChild6Type, OPC_CheckChild7Type,
|
||||
OPC_CheckInteger,
|
||||
OPC_CheckCondCode,
|
||||
OPC_CheckValueType,
|
||||
OPC_CheckComplexPat,
|
||||
OPC_CheckAndImm, OPC_CheckOrImm,
|
||||
OPC_CheckFoldableChainNode,
|
||||
|
||||
OPC_EmitInteger,
|
||||
OPC_EmitRegister,
|
||||
OPC_EmitConvertToTarget,
|
||||
OPC_EmitMergeInputChains,
|
||||
OPC_EmitCopyToReg,
|
||||
OPC_EmitNodeXForm,
|
||||
OPC_EmitNode,
|
||||
OPC_MorphNodeTo,
|
||||
OPC_MarkFlagResults,
|
||||
OPC_CompleteMatch
|
||||
};
|
||||
|
||||
enum {
|
||||
OPFL_None = 0, // Node has no chain or flag input and isn't variadic.
|
||||
OPFL_Chain = 1, // Node has a chain input.
|
||||
OPFL_FlagInput = 2, // Node has a flag input.
|
||||
OPFL_FlagOutput = 4, // Node has a flag output.
|
||||
OPFL_MemRefs = 8, // Node gets accumulated MemRefs.
|
||||
OPFL_Variadic0 = 1<<4, // Node is variadic, root has 0 fixed inputs.
|
||||
OPFL_Variadic1 = 2<<4, // Node is variadic, root has 1 fixed inputs.
|
||||
OPFL_Variadic2 = 3<<4, // Node is variadic, root has 2 fixed inputs.
|
||||
OPFL_Variadic3 = 4<<4, // Node is variadic, root has 3 fixed inputs.
|
||||
OPFL_Variadic4 = 5<<4, // Node is variadic, root has 4 fixed inputs.
|
||||
OPFL_Variadic5 = 6<<4, // Node is variadic, root has 5 fixed inputs.
|
||||
OPFL_Variadic6 = 7<<4, // Node is variadic, root has 6 fixed inputs.
|
||||
|
||||
OPFL_VariadicInfo = OPFL_Variadic6
|
||||
};
|
||||
|
||||
/// getNumFixedFromVariadicInfo - Transform an EmitNode flags word into the
|
||||
/// number of fixed arity values that should be skipped when copying from the
|
||||
/// root.
|
||||
static inline int getNumFixedFromVariadicInfo(unsigned Flags) {
|
||||
return ((Flags&OPFL_VariadicInfo) >> 4)-1;
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
/// DAGSize - Size of DAG being instruction selected.
|
||||
///
|
||||
unsigned DAGSize;
|
||||
|
||||
/// ISelPosition - Node iterator marking the current position of
|
||||
/// instruction selection as it procedes through the topologically-sorted
|
||||
/// node list.
|
||||
SelectionDAG::allnodes_iterator ISelPosition;
|
||||
|
||||
|
||||
/// ISelUpdater - helper class to handle updates of the
|
||||
/// instruction selection graph.
|
||||
class ISelUpdater : public SelectionDAG::DAGUpdateListener {
|
||||
SelectionDAG::allnodes_iterator &ISelPosition;
|
||||
public:
|
||||
explicit ISelUpdater(SelectionDAG::allnodes_iterator &isp)
|
||||
: ISelPosition(isp) {}
|
||||
|
||||
/// NodeDeleted - Handle nodes deleted from the graph. If the
|
||||
/// node being deleted is the current ISelPosition node, update
|
||||
/// ISelPosition.
|
||||
///
|
||||
virtual void NodeDeleted(SDNode *N, SDNode *E) {
|
||||
if (ISelPosition == SelectionDAG::allnodes_iterator(N))
|
||||
++ISelPosition;
|
||||
}
|
||||
|
||||
/// NodeUpdated - Ignore updates for now.
|
||||
virtual void NodeUpdated(SDNode *N) {}
|
||||
};
|
||||
|
||||
/// ReplaceUses - replace all uses of the old node F with the use
|
||||
/// of the new node T.
|
||||
void ReplaceUses(SDValue F, SDValue T) {
|
||||
ISelUpdater ISU(ISelPosition);
|
||||
CurDAG->ReplaceAllUsesOfValueWith(F, T, &ISU);
|
||||
}
|
||||
|
||||
/// ReplaceUses - replace all uses of the old nodes F with the use
|
||||
/// of the new nodes T.
|
||||
void ReplaceUses(const SDValue *F, const SDValue *T, unsigned Num) {
|
||||
ISelUpdater ISU(ISelPosition);
|
||||
CurDAG->ReplaceAllUsesOfValuesWith(F, T, Num, &ISU);
|
||||
}
|
||||
|
||||
/// ReplaceUses - replace all uses of the old node F with the use
|
||||
/// of the new node T.
|
||||
void ReplaceUses(SDNode *F, SDNode *T) {
|
||||
ISelUpdater ISU(ISelPosition);
|
||||
CurDAG->ReplaceAllUsesWith(F, T, &ISU);
|
||||
}
|
||||
|
||||
|
||||
/// SelectInlineAsmMemoryOperands - Calls to this are automatically generated
|
||||
/// by tblgen. Others should not call it.
|
||||
void SelectInlineAsmMemoryOperands(std::vector<SDValue> &Ops);
|
||||
|
||||
|
||||
public:
|
||||
// Calls to these predicates are generated by tblgen.
|
||||
bool CheckAndMask(SDValue LHS, ConstantSDNode *RHS,
|
||||
int64_t DesiredMaskS) const;
|
||||
@ -122,8 +245,8 @@ protected:
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// CheckNodePredicate - This function is generated by tblgen in the
|
||||
/// target. It runs node predicate #PredNo and returns true if it succeeds or
|
||||
/// CheckNodePredicate - This function is generated by tblgen in the target.
|
||||
/// It runs node predicate number PredNo and returns true if it succeeds or
|
||||
/// false if it fails. The number is a private implementation
|
||||
/// detail to the code tblgen produces.
|
||||
virtual bool CheckNodePredicate(SDNode *N, unsigned PredNo) const {
|
||||
@ -131,6 +254,23 @@ protected:
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual bool CheckComplexPattern(SDNode *Root, SDValue N, unsigned PatternNo,
|
||||
SmallVectorImpl<SDValue> &Result) {
|
||||
assert(0 && "Tblgen should generate the implementation of this!");
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual SDValue RunSDNodeXForm(SDValue V, unsigned XFormNo) {
|
||||
assert(0 && "Tblgen shoudl generate this!");
|
||||
return SDValue();
|
||||
}
|
||||
|
||||
SDNode *SelectCodeCommon(SDNode *NodeToMatch,
|
||||
const unsigned char *MatcherTable,
|
||||
unsigned TableSize);
|
||||
|
||||
private:
|
||||
|
||||
// Calls to these functions are generated by tblgen.
|
||||
SDNode *Select_INLINEASM(SDNode *N);
|
||||
SDNode *Select_UNDEF(SDNode *N);
|
||||
@ -139,6 +279,10 @@ protected:
|
||||
void CannotYetSelectIntrinsic(SDNode *N);
|
||||
|
||||
private:
|
||||
void DoInstructionSelection();
|
||||
SDNode *MorphNode(SDNode *Node, unsigned TargetOpc, SDVTList VTs,
|
||||
const SDValue *Ops, unsigned NumOps, unsigned EmitNodeInfo);
|
||||
|
||||
void SelectAllBasicBlocks(Function &Fn, MachineFunction &MF,
|
||||
MachineModuleInfo *MMI,
|
||||
DwarfWriter *DW,
|
||||
@ -164,6 +308,16 @@ private:
|
||||
/// one preferred by the target.
|
||||
///
|
||||
ScheduleDAGSDNodes *CreateScheduler();
|
||||
|
||||
/// OpcodeOffset - This is a cache used to dispatch efficiently into isel
|
||||
/// state machines that start with a OPC_SwitchOpcode node.
|
||||
std::vector<unsigned> OpcodeOffset;
|
||||
|
||||
void UpdateChainsAndFlags(SDNode *NodeToMatch, SDValue InputChain,
|
||||
const SmallVectorImpl<SDNode*> &ChainNodesMatched,
|
||||
SDValue InputFlag,const SmallVectorImpl<SDNode*> &F,
|
||||
bool isMorphNodeTo);
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -1595,8 +1595,10 @@ public:
|
||||
return SubclassData;
|
||||
}
|
||||
|
||||
// We access subclass data here so that we can check consistency
|
||||
// with MachineMemOperand information.
|
||||
bool isVolatile() const { return (SubclassData >> 5) & 1; }
|
||||
bool isNonTemporal() const { return MMO->isNonTemporal(); }
|
||||
bool isNonTemporal() const { return (SubclassData >> 6) & 1; }
|
||||
|
||||
/// Returns the SrcValue and offset that describes the location of the access
|
||||
const Value *getSrcValue() const { return MMO->getValue(); }
|
||||
@ -1762,7 +1764,12 @@ public:
|
||||
bool isSplat() const { return isSplatMask(Mask, getValueType(0)); }
|
||||
int getSplatIndex() const {
|
||||
assert(isSplat() && "Cannot get splat index for non-splat!");
|
||||
return Mask[0];
|
||||
EVT VT = getValueType(0);
|
||||
for (unsigned i = 0, e = VT.getVectorNumElements(); i != e; ++i) {
|
||||
if (Mask[i] != -1)
|
||||
return Mask[i];
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
static bool isSplatMask(const int *Mask, EVT VT);
|
||||
|
||||
@ -1808,6 +1815,12 @@ public:
|
||||
const APFloat& getValueAPF() const { return Value->getValueAPF(); }
|
||||
const ConstantFP *getConstantFPValue() const { return Value; }
|
||||
|
||||
/// isZero - Return true if the value is positive or negative zero.
|
||||
bool isZero() const { return Value->isZero(); }
|
||||
|
||||
/// isNaN - Return true if the value is a NaN.
|
||||
bool isNaN() const { return Value->isNaN(); }
|
||||
|
||||
/// isExactlyValue - We don't rely on operator== working on double values, as
|
||||
/// it returns true for things that are clearly not equal, like -0.0 and 0.0.
|
||||
/// As such, this method can be used to do an exact bit-for-bit comparison of
|
||||
|
@ -171,6 +171,11 @@ public:
|
||||
virtual const MCExpr *
|
||||
getSymbolForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang,
|
||||
MachineModuleInfo *MMI, unsigned Encoding) const;
|
||||
|
||||
virtual unsigned getPersonalityEncoding() const;
|
||||
virtual unsigned getLSDAEncoding() const;
|
||||
virtual unsigned getFDEEncoding() const;
|
||||
virtual unsigned getTTypeEncoding() const;
|
||||
};
|
||||
|
||||
|
||||
|
@ -20,9 +20,12 @@ class Tool<list<dag> l> {
|
||||
def in_language;
|
||||
def out_language;
|
||||
def output_suffix;
|
||||
def cmd_line;
|
||||
def command;
|
||||
def out_file_option;
|
||||
def in_file_option;
|
||||
def join;
|
||||
def sink;
|
||||
def works_on_empty;
|
||||
def actions;
|
||||
|
||||
// Possible option types.
|
||||
@ -46,6 +49,7 @@ def optional;
|
||||
def really_hidden;
|
||||
def required;
|
||||
def comma_separated;
|
||||
def forward_not_split;
|
||||
|
||||
// The 'case' construct.
|
||||
def case;
|
||||
@ -81,6 +85,7 @@ def forward_as;
|
||||
def forward_value;
|
||||
def forward_transformed_value;
|
||||
def stop_compilation;
|
||||
def no_out_file;
|
||||
def unpack_values;
|
||||
def warning;
|
||||
def error;
|
||||
|
@ -10,7 +10,7 @@
|
||||
// This tool provides a single point of access to the LLVM
|
||||
// compilation tools. It has many options. To discover the options
|
||||
// supported please refer to the tools' manual page or run the tool
|
||||
// with the --help option.
|
||||
// with the -help option.
|
||||
//
|
||||
// This file provides the default entry point for the driver executable.
|
||||
//
|
||||
|
@ -20,15 +20,19 @@
|
||||
#include "llvm/ADT/StringSet.h"
|
||||
#include "llvm/System/Path.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
|
||||
namespace llvmc {
|
||||
|
||||
class LanguageMap;
|
||||
typedef std::vector<std::pair<unsigned, std::string> > ArgsVector;
|
||||
typedef std::vector<llvm::sys::Path> PathVector;
|
||||
typedef std::vector<std::string> StrVector;
|
||||
typedef llvm::StringSet<> InputLanguagesSet;
|
||||
|
||||
/// Tool - A class
|
||||
/// Tool - Represents a single tool.
|
||||
class Tool : public llvm::RefCountedBaseVPTR<Tool> {
|
||||
public:
|
||||
|
||||
@ -51,6 +55,7 @@ namespace llvmc {
|
||||
virtual const char* OutputLanguage() const = 0;
|
||||
|
||||
virtual bool IsJoin() const = 0;
|
||||
virtual bool WorksOnEmpty() const = 0;
|
||||
|
||||
protected:
|
||||
/// OutFileName - Generate the output file name.
|
||||
@ -58,6 +63,8 @@ namespace llvmc {
|
||||
const llvm::sys::Path& TempDir,
|
||||
bool StopCompilation,
|
||||
const char* OutputSuffix) const;
|
||||
|
||||
StrVector SortArgs(ArgsVector& Args) const;
|
||||
};
|
||||
|
||||
/// JoinTool - A Tool that has an associated input file list.
|
||||
|
@ -276,6 +276,12 @@ public:
|
||||
return Val.isZero() && Val.isNegative();
|
||||
}
|
||||
|
||||
/// isZero - Return true if the value is positive or negative zero.
|
||||
bool isZero() const { return Val.isZero(); }
|
||||
|
||||
/// isNaN - Return true if the value is a NaN.
|
||||
bool isNaN() const { return Val.isNaN(); }
|
||||
|
||||
/// isExactlyValue - We don't rely on operator== working on double values, as
|
||||
/// it returns true for things that are clearly not equal, like -0.0 and 0.0.
|
||||
/// As such, this method can be used to do an exact bit-for-bit comparison of
|
||||
@ -692,8 +698,9 @@ public:
|
||||
/// independent way (Note: the return type is an i64).
|
||||
static Constant *getAlignOf(const Type* Ty);
|
||||
|
||||
/// getSizeOf constant expr - computes the size of a type in a target
|
||||
/// independent way (Note: the return type is an i64).
|
||||
/// getSizeOf constant expr - computes the (alloc) size of a type (in
|
||||
/// address-units, not bits) in a target independent way (Note: the return
|
||||
/// type is an i64).
|
||||
///
|
||||
static Constant *getSizeOf(const Type* Ty);
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user