Upgrade our Clang in base to r114020, from upstream's release_28 branch.

Approved-by:	rpaulo (mentor)
This commit is contained in:
dim 2010-09-20 16:43:17 +00:00
commit 154966ba66
1469 changed files with 93697 additions and 71919 deletions

View File

@ -1,10 +1,20 @@
# See docs/CMake.html for instructions about how to build LLVM with CMake. # See docs/CMake.html for instructions about how to build LLVM with CMake.
project(LLVM) project(LLVM)
cmake_minimum_required(VERSION 2.6.1) cmake_minimum_required(VERSION 2.8)
# Add path for custom modules
set(CMAKE_MODULE_PATH
${CMAKE_MODULE_PATH}
"${CMAKE_CURRENT_SOURCE_DIR}/cmake"
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules"
)
set(PACKAGE_VERSION "2.8")
include(VersionFromVCS)
add_version_info_from_vcs(PACKAGE_VERSION)
set(PACKAGE_NAME llvm) set(PACKAGE_NAME llvm)
set(PACKAGE_VERSION 2.8svn)
set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}") set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}")
set(PACKAGE_BUGREPORT "llvmbugs@cs.uiuc.edu") set(PACKAGE_BUGREPORT "llvmbugs@cs.uiuc.edu")
@ -53,7 +63,6 @@ set(LLVM_ALL_TARGETS
CppBackend CppBackend
Mips Mips
MBlaze MBlaze
MSIL
MSP430 MSP430
PIC16 PIC16
PowerPC PowerPC
@ -124,13 +133,6 @@ configure_file(
set(llvm_builded_incs_dir ${LLVM_BINARY_DIR}/include/llvm) set(llvm_builded_incs_dir ${LLVM_BINARY_DIR}/include/llvm)
# Add path for custom modules
set(CMAKE_MODULE_PATH
${CMAKE_MODULE_PATH}
"${LLVM_MAIN_SRC_DIR}/cmake"
"${LLVM_MAIN_SRC_DIR}/cmake/modules"
)
include(AddLLVMDefinitions) include(AddLLVMDefinitions)
if(WIN32) if(WIN32)
@ -214,14 +216,8 @@ if( CMAKE_SIZEOF_VOID_P EQUAL 8 AND NOT WIN32 )
endif( CMAKE_SIZEOF_VOID_P EQUAL 8 AND NOT WIN32 ) endif( CMAKE_SIZEOF_VOID_P EQUAL 8 AND NOT WIN32 )
if( MSVC ) if( MSVC )
# List of valid CRTs for MSVC include(ChooseMSVCCRT)
set(MSVC_CRT
MD
MDd
MT
MTd)
set(LLVM_USE_CRT "" CACHE STRING "Specify VC++ CRT to use for debug/release configurations.")
add_llvm_definitions( -D_CRT_SECURE_NO_DEPRECATE -D_CRT_SECURE_NO_WARNINGS ) add_llvm_definitions( -D_CRT_SECURE_NO_DEPRECATE -D_CRT_SECURE_NO_WARNINGS )
add_llvm_definitions( -D_SCL_SECURE_NO_WARNINGS -DCRT_NONSTDC_NO_WARNINGS ) add_llvm_definitions( -D_SCL_SECURE_NO_WARNINGS -DCRT_NONSTDC_NO_WARNINGS )
add_llvm_definitions( -D_SCL_SECURE_NO_DEPRECATE ) add_llvm_definitions( -D_SCL_SECURE_NO_DEPRECATE )
@ -231,15 +227,6 @@ if( MSVC )
# Suppress 'new behavior: elements of array 'array' will be default initialized' # Suppress 'new behavior: elements of array 'array' will be default initialized'
add_llvm_definitions( -wd4351 ) add_llvm_definitions( -wd4351 )
if (NOT ${LLVM_USE_CRT} STREQUAL "")
list(FIND MSVC_CRT ${LLVM_USE_CRT} idx)
if (idx LESS 0)
message(FATAL_ERROR "Invalid value for LLVM_USE_CRT: ${LLVM_USE_CRT}. Valid options are one of: ${MSVC_CRT}")
endif (idx LESS 0)
add_llvm_definitions("/${LLVM_USE_CRT}")
message(STATUS "Using VC++ CRT: ${LLVM_USE_CRT}")
endif (NOT ${LLVM_USE_CRT} STREQUAL "")
# Enable warnings # Enable warnings
if (LLVM_ENABLE_WARNINGS) if (LLVM_ENABLE_WARNINGS)
add_llvm_definitions( /W4 /Wall ) add_llvm_definitions( /W4 /Wall )
@ -308,6 +295,7 @@ add_subdirectory(lib/Analysis)
add_subdirectory(lib/Analysis/IPA) add_subdirectory(lib/Analysis/IPA)
add_subdirectory(lib/MC) add_subdirectory(lib/MC)
add_subdirectory(lib/MC/MCParser) add_subdirectory(lib/MC/MCParser)
add_subdirectory(lib/MC/MCDisassembler)
add_subdirectory(test) add_subdirectory(test)
add_subdirectory(utils/FileCheck) add_subdirectory(utils/FileCheck)
@ -372,6 +360,8 @@ add_subdirectory(tools)
option(LLVM_BUILD_EXAMPLES "Build LLVM example programs." OFF) option(LLVM_BUILD_EXAMPLES "Build LLVM example programs." OFF)
add_subdirectory(examples) add_subdirectory(examples)
add_subdirectory(cmake/modules)
install(DIRECTORY include/ install(DIRECTORY include/
DESTINATION include DESTINATION include
FILES_MATCHING FILES_MATCHING

View File

@ -134,6 +134,11 @@ N: Gabor Greif
E: ggreif@gmail.com E: ggreif@gmail.com
D: Improvements for space efficiency D: Improvements for space efficiency
N: James Grosbach
E: grosbach@apple.com
D: SjLj exception handling support
D: General fixes and improvements for the ARM back-end
N: Lang Hames N: Lang Hames
E: lhames@gmail.com E: lhames@gmail.com
D: PBQP-based register allocator D: PBQP-based register allocator
@ -247,6 +252,12 @@ N: Scott Michel
E: scottm@aero.org E: scottm@aero.org
D: Added STI Cell SPU backend. D: Added STI Cell SPU backend.
N: Takumi Nakamura
E: geek4civic@gmail.com
E: chapuni@hf.rim.or.jp
D: Cygwin and MinGW support.
S: Yokohama, Japan
N: Edward O'Callaghan N: Edward O'Callaghan
E: eocallaghan@auroraux.org E: eocallaghan@auroraux.org
W: http://www.auroraux.org W: http://www.auroraux.org
@ -277,6 +288,11 @@ N: Sandeep Patel
E: deeppatel1987@gmail.com E: deeppatel1987@gmail.com
D: ARM calling conventions rewrite, hard float support D: ARM calling conventions rewrite, hard float support
N: Wesley Peck
E: peckw@wesleypeck.com
W: http://wesleypeck.com/
D: MicroBlaze backend
N: Vladimir Prus N: Vladimir Prus
W: http://vladimir_prus.blogspot.com W: http://vladimir_prus.blogspot.com
E: ghost@cs.msu.su E: ghost@cs.msu.su
@ -288,7 +304,10 @@ D: MSIL backend
N: Duncan Sands N: Duncan Sands
E: baldrick@free.fr E: baldrick@free.fr
D: Ada front-end, exception handling improvements D: Ada support in llvm-gcc
D: Dragonegg plugin
D: Exception handling improvements
D: Type legalizer rewrite
N: Ruchira Sasanka N: Ruchira Sasanka
E: sasanka@uiuc.edu E: sasanka@uiuc.edu
@ -306,6 +325,10 @@ N: Anand Shukla
E: ashukla@cs.uiuc.edu E: ashukla@cs.uiuc.edu
D: The `paths' pass D: The `paths' pass
N: Michael J. Spencer
E: bigcheesegs@gmail.com
D: Shepherding Windows COFF support into MC.
N: Reid Spencer N: Reid Spencer
E: rspencer@reidspencer.com E: rspencer@reidspencer.com
W: http://reidspencer.com/ W: http://reidspencer.com/
@ -329,14 +352,9 @@ E: xerxes@zafena.se
D: Cmake dependency chain and various bug fixes D: Cmake dependency chain and various bug fixes
N: Bill Wendling N: Bill Wendling
E: isanbard@gmail.com E: wendling@apple.com
D: Bunches of stuff D: Bunches of stuff
N: Bob Wilson N: Bob Wilson
E: bob.wilson@acm.org E: bob.wilson@acm.org
D: Advanced SIMD (NEON) support in the ARM backend D: Advanced SIMD (NEON) support in the ARM backend
N: Wesley Peck
E: peckw@wesleypeck.com
W: http://wesleypeck.com/
D: MicroBlaze backend

View File

@ -64,7 +64,8 @@ endif
ifeq ($(MAKECMDGOALS),install-clang) ifeq ($(MAKECMDGOALS),install-clang)
DIRS := tools/clang/tools/driver tools/clang/lib/Headers \ DIRS := tools/clang/tools/driver tools/clang/lib/Headers \
tools/clang/runtime tools/clang/docs tools/clang/runtime tools/clang/docs \
tools/lto
OPTIONAL_DIRS := OPTIONAL_DIRS :=
NO_INSTALL = 1 NO_INSTALL = 1
endif endif
@ -78,7 +79,8 @@ ifeq ($(MAKECMDGOALS),install-clang-c)
endif endif
ifeq ($(MAKECMDGOALS),clang-only) ifeq ($(MAKECMDGOALS),clang-only)
DIRS := $(filter-out tools runtime docs unittests, $(DIRS)) tools/clang DIRS := $(filter-out tools runtime docs unittests, $(DIRS)) \
tools/clang tools/lto
OPTIONAL_DIRS := OPTIONAL_DIRS :=
endif endif
@ -110,7 +112,8 @@ cross-compile-build-tools:
--host=$(BUILD_TRIPLE) --target=$(BUILD_TRIPLE); \ --host=$(BUILD_TRIPLE) --target=$(BUILD_TRIPLE); \
cd .. ; \ cd .. ; \
fi; \ fi; \
($(MAKE) -C BuildTools \ (unset SDKROOT; \
$(MAKE) -C BuildTools \
BUILD_DIRS_ONLY=1 \ BUILD_DIRS_ONLY=1 \
UNIVERSAL= \ UNIVERSAL= \
ENABLE_OPTIMIZED=$(ENABLE_OPTIMIZED) \ ENABLE_OPTIMIZED=$(ENABLE_OPTIMIZED) \
@ -167,7 +170,7 @@ FilesToConfig := \
include/llvm/Config/AsmParsers.def \ include/llvm/Config/AsmParsers.def \
include/llvm/Config/Disassemblers.def \ include/llvm/Config/Disassemblers.def \
include/llvm/System/DataTypes.h \ include/llvm/System/DataTypes.h \
tools/llvmc/plugins/Base/Base.td tools/llvmc/src/Base.td
FilesToConfigPATH := $(addprefix $(LLVM_OBJ_ROOT)/,$(FilesToConfig)) FilesToConfigPATH := $(addprefix $(LLVM_OBJ_ROOT)/,$(FilesToConfig))
all-local:: $(FilesToConfigPATH) all-local:: $(FilesToConfigPATH)
@ -192,9 +195,6 @@ endif
check-llvm2cpp: check-llvm2cpp:
$(Verb)$(MAKE) check TESTSUITE=Feature RUNLLVM2CPP=1 $(Verb)$(MAKE) check TESTSUITE=Feature RUNLLVM2CPP=1
check-one:
$(Verb)$(MAKE) -C test check-one TESTONE=$(TESTONE)
srpm: $(LLVM_OBJ_ROOT)/llvm.spec srpm: $(LLVM_OBJ_ROOT)/llvm.spec
rpmbuild -bs $(LLVM_OBJ_ROOT)/llvm.spec rpmbuild -bs $(LLVM_OBJ_ROOT)/llvm.spec

View File

@ -39,14 +39,18 @@ ifndef PROJECT_NAME
PROJECT_NAME := $(LLVMPackageName) PROJECT_NAME := $(LLVMPackageName)
endif endif
PROJ_OBJ_DIR := $(shell $(PWD)) # The macro below is expanded when 'realpath' is not built-in.
PROJ_OBJ_ROOT := $(shell cd $(PROJ_OBJ_DIR)/$(LEVEL); $(PWD)) # Built-in 'realpath' is available on GNU Make 3.81.
realpath = $(shell cd $(1); $(PWD))
PROJ_OBJ_DIR := $(call realpath, .)
PROJ_OBJ_ROOT := $(call realpath, $(PROJ_OBJ_DIR)/$(LEVEL))
ifeq ($(PROJECT_NAME),llvm) ifeq ($(PROJECT_NAME),llvm)
LLVM_SRC_ROOT := $(shell cd @abs_top_srcdir@; $(PWD)) LLVM_SRC_ROOT := $(call realpath, @abs_top_srcdir@)
LLVM_OBJ_ROOT := $(shell cd @abs_top_builddir@; $(PWD)) LLVM_OBJ_ROOT := $(call realpath, @abs_top_builddir@)
PROJ_SRC_ROOT := $(shell cd $(LLVM_SRC_ROOT); $(PWD)) PROJ_SRC_ROOT := $(LLVM_SRC_ROOT)
PROJ_SRC_DIR := $(shell cd $(LLVM_SRC_ROOT)/$(patsubst $(PROJ_OBJ_ROOT)%,%,$(PROJ_OBJ_DIR)); $(PWD)) PROJ_SRC_DIR := $(call realpath, $(LLVM_SRC_ROOT)/$(patsubst $(PROJ_OBJ_ROOT)%,%,$(PROJ_OBJ_DIR)))
prefix := @prefix@ prefix := @prefix@
PROJ_prefix := $(prefix) PROJ_prefix := $(prefix)
PROJ_VERSION := $(LLVMVersion) PROJ_VERSION := $(LLVMVersion)
@ -66,7 +70,7 @@ endif
ifndef LLVM_OBJ_ROOT ifndef LLVM_OBJ_ROOT
$(error Projects must define LLVM_OBJ_ROOT) $(error Projects must define LLVM_OBJ_ROOT)
endif endif
PROJ_SRC_DIR := $(shell cd $(PROJ_SRC_ROOT)/$(patsubst $(PROJ_OBJ_ROOT)%,%,$(PROJ_OBJ_DIR)); $(PWD)) PROJ_SRC_DIR := $(call realpath, $(PROJ_SRC_ROOT)/$(patsubst $(PROJ_OBJ_ROOT)%,%,$(PROJ_OBJ_DIR)))
prefix := $(PROJ_INSTALL_ROOT) prefix := $(PROJ_INSTALL_ROOT)
PROJ_prefix := $(prefix) PROJ_prefix := $(prefix)
ifndef PROJ_VERSION ifndef PROJ_VERSION

View File

@ -196,105 +196,15 @@ install-local:: all-local
install-bytecode:: install-bytecode-local install-bytecode:: install-bytecode-local
############################################################################### ###############################################################################
# LLVMC: Provide rules for compiling llvmc plugins # LLVMC: Provide rules for compiling llvmc-based driver
############################################################################### ###############################################################################
ifdef LLVMC_PLUGIN
LIBRARYNAME := $(patsubst %,plugin_llvmc_%,$(LLVMC_PLUGIN))
CPP.Flags += -DLLVMC_PLUGIN_NAME=$(LLVMC_PLUGIN)
REQUIRES_EH := 1
ifeq ($(ENABLE_LLVMC_DYNAMIC),1)
LD.Flags += -lCompilerDriver
endif
# Build a dynamic library if the user runs `make` directly from the plugin
# directory.
ifndef LLVMC_BUILTIN_PLUGIN
LOADABLE_MODULE = 1
endif
# TableGen stuff...
ifneq ($(BUILT_SOURCES),)
LLVMC_BUILD_AUTOGENERATED_INC=1
endif
endif # LLVMC_PLUGIN
ifdef LLVMC_BASED_DRIVER ifdef LLVMC_BASED_DRIVER
TOOLNAME = $(LLVMC_BASED_DRIVER) TOOLNAME = $(LLVMC_BASED_DRIVER)
REQUIRES_EH := 1 LLVMLIBS = CompilerDriver.a
LINK_COMPONENTS = support system
ifeq ($(ENABLE_LLVMC_DYNAMIC),1)
LD.Flags += -lCompilerDriver
else
LLVMLIBS = CompilerDriver.a
LINK_COMPONENTS = support system
endif
# Preprocessor magic that generates references to static variables in built-in
# plugins.
ifneq ($(LLVMC_BUILTIN_PLUGINS),)
USEDLIBS += $(patsubst %,plugin_llvmc_%.a,$(LLVMC_BUILTIN_PLUGINS))
LLVMC_BUILTIN_PLUGIN_1 = $(word 1, $(LLVMC_BUILTIN_PLUGINS))
LLVMC_BUILTIN_PLUGIN_2 = $(word 2, $(LLVMC_BUILTIN_PLUGINS))
LLVMC_BUILTIN_PLUGIN_3 = $(word 3, $(LLVMC_BUILTIN_PLUGINS))
LLVMC_BUILTIN_PLUGIN_4 = $(word 4, $(LLVMC_BUILTIN_PLUGINS))
LLVMC_BUILTIN_PLUGIN_5 = $(word 5, $(LLVMC_BUILTIN_PLUGINS))
LLVMC_BUILTIN_PLUGIN_6 = $(word 6, $(LLVMC_BUILTIN_PLUGINS))
LLVMC_BUILTIN_PLUGIN_7 = $(word 7, $(LLVMC_BUILTIN_PLUGINS))
LLVMC_BUILTIN_PLUGIN_8 = $(word 8, $(LLVMC_BUILTIN_PLUGINS))
LLVMC_BUILTIN_PLUGIN_9 = $(word 9, $(LLVMC_BUILTIN_PLUGINS))
LLVMC_BUILTIN_PLUGIN_10 = $(word 10, $(LLVMC_BUILTIN_PLUGINS))
ifneq ($(LLVMC_BUILTIN_PLUGIN_1),)
CPP.Flags += -DLLVMC_BUILTIN_PLUGIN_1=$(LLVMC_BUILTIN_PLUGIN_1)
endif
ifneq ($(LLVMC_BUILTIN_PLUGIN_2),)
CPP.Flags += -DLLVMC_BUILTIN_PLUGIN_2=$(LLVMC_BUILTIN_PLUGIN_2)
endif
ifneq ($(LLVMC_BUILTIN_PLUGIN_3),)
CPP.Flags += -DLLVMC_BUILTIN_PLUGIN_3=$(LLVMC_BUILTIN_PLUGIN_3)
endif
ifneq ($(LLVMC_BUILTIN_PLUGIN_4),)
CPP.Flags += -DLLVMC_BUILTIN_PLUGIN_4=$(LLVMC_BUILTIN_PLUGIN_4)
endif
ifneq ($(LLVMC_BUILTIN_PLUGIN_5),)
CPP.Flags += -DLLVMC_BUILTIN_PLUGIN_5=$(LLVMC_BUILTIN_PLUGIN_5)
endif
ifneq ($(LLVMC_BUILTIN_PLUGIN_6),)
CPP.Flags += -DLLVMC_BUILTIN_PLUGIN_5=$(LLVMC_BUILTIN_PLUGIN_6)
endif
ifneq ($(LLVMC_BUILTIN_PLUGIN_7),)
CPP.Flags += -DLLVMC_BUILTIN_PLUGIN_5=$(LLVMC_BUILTIN_PLUGIN_7)
endif
ifneq ($(LLVMC_BUILTIN_PLUGIN_8),)
CPP.Flags += -DLLVMC_BUILTIN_PLUGIN_5=$(LLVMC_BUILTIN_PLUGIN_8)
endif
ifneq ($(LLVMC_BUILTIN_PLUGIN_9),)
CPP.Flags += -DLLVMC_BUILTIN_PLUGIN_5=$(LLVMC_BUILTIN_PLUGIN_9)
endif
ifneq ($(LLVMC_BUILTIN_PLUGIN_10),)
CPP.Flags += -DLLVMC_BUILTIN_PLUGIN_5=$(LLVMC_BUILTIN_PLUGIN_10)
endif
endif
endif # LLVMC_BASED_DRIVER endif # LLVMC_BASED_DRIVER
@ -500,6 +410,26 @@ LLVMLibDir := $(LLVM_OBJ_ROOT)/$(BuildMode)/lib
LLVMToolDir := $(LLVM_OBJ_ROOT)/$(BuildMode)/bin LLVMToolDir := $(LLVM_OBJ_ROOT)/$(BuildMode)/bin
LLVMExmplDir:= $(LLVM_OBJ_ROOT)/$(BuildMode)/examples LLVMExmplDir:= $(LLVM_OBJ_ROOT)/$(BuildMode)/examples
#--------------------------------------------------------------------
# Locations of shared libraries
#--------------------------------------------------------------------
SharedPrefix := lib
SharedLibDir := $(LibDir)
LLVMSharedLibDir := $(LLVMLibDir)
# Win32.DLL prefers to be located on the "PATH" of binaries.
ifeq ($(HOST_OS), $(filter $(HOST_OS), Cygwin MingW))
SharedLibDir := $(ToolDir)
LLVMSharedLibDir := $(LLVMToolDir)
ifeq ($(HOST_OS),Cygwin)
SharedPrefix := cyg
else
SharedPrefix :=
endif
endif
#-------------------------------------------------------------------- #--------------------------------------------------------------------
# LLVM Capable Compiler # LLVM Capable Compiler
#-------------------------------------------------------------------- #--------------------------------------------------------------------
@ -573,12 +503,7 @@ ifeq ($(HOST_OS),Darwin)
SharedLinkOptions += -mmacosx-version-min=$(DARWIN_VERSION) SharedLinkOptions += -mmacosx-version-min=$(DARWIN_VERSION)
endif endif
else else
ifeq ($(HOST_OS),Cygwin) SharedLinkOptions=-shared
SharedLinkOptions=-shared -nostdlib -Wl,--export-all-symbols \
-Wl,--enable-auto-import -Wl,--enable-auto-image-base
else
SharedLinkOptions=-shared
endif
endif endif
ifeq ($(TARGET_OS),Darwin) ifeq ($(TARGET_OS),Darwin)
@ -588,11 +513,13 @@ ifeq ($(TARGET_OS),Darwin)
endif endif
ifdef SHARED_LIBRARY ifdef SHARED_LIBRARY
ifneq ($(HOST_OS), $(filter $(HOST_OS), Cygwin MingW))
ifneq ($(HOST_OS),Darwin) ifneq ($(HOST_OS),Darwin)
LD.Flags += $(RPATH) -Wl,'$$ORIGIN' LD.Flags += $(RPATH) -Wl,'$$ORIGIN'
else else
ifneq ($(DARWIN_MAJVERS),4) ifneq ($(DARWIN_MAJVERS),4)
LD.Flags += $(RPATH) -Wl,$(LibDir) LD.Flags += $(RPATH) -Wl,$(SharedLibDir)
endif
endif endif
endif endif
endif endif
@ -621,8 +548,8 @@ ifndef KEEP_SYMBOLS
endif endif
# Adjust linker flags for building an executable # Adjust linker flags for building an executable
ifneq ($(HOST_OS),Darwin) ifneq ($(HOST_OS), $(filter $(HOST_OS), Cygwin MingW))
ifneq ($(DARWIN_MAJVERS),4) ifneq ($(HOST_OS), Darwin)
ifdef TOOLNAME ifdef TOOLNAME
LD.Flags += $(RPATH) -Wl,'$$ORIGIN/../lib' LD.Flags += $(RPATH) -Wl,'$$ORIGIN/../lib'
ifdef EXAMPLE_TOOL ifdef EXAMPLE_TOOL
@ -631,12 +558,12 @@ ifdef TOOLNAME
LD.Flags += $(RPATH) -Wl,$(ToolDir) $(RDYNAMIC) LD.Flags += $(RPATH) -Wl,$(ToolDir) $(RDYNAMIC)
endif endif
endif endif
endif
else else
ifneq ($(DARWIN_MAJVERS),4) ifneq ($(DARWIN_MAJVERS),4)
LD.Flags += $(RPATH) -Wl,@executable_path/../lib LD.Flags += $(RPATH) -Wl,@executable_path/../lib
endif endif
endif endif
endif
#---------------------------------------------------------- #----------------------------------------------------------
@ -963,6 +890,13 @@ LLVMUsedLibs := $(patsubst %.a.o, lib%.a, $(addsuffix .o, $(LLVMLIBS)))
LLVMLibsPaths := $(addprefix $(LLVMLibDir)/,$(LLVMUsedLibs)) LLVMLibsPaths := $(addprefix $(LLVMLibDir)/,$(LLVMUsedLibs))
endif endif
# Win32.DLL may refer to other components.
ifeq ($(HOST_OS), $(filter $(HOST_OS), Cygwin MingW))
ifdef LOADABLE_MODULE
LINK_COMPONENTS := all
endif
endif
ifndef IS_CLEANING_TARGET ifndef IS_CLEANING_TARGET
ifdef LINK_COMPONENTS ifdef LINK_COMPONENTS
@ -975,12 +909,28 @@ $(LLVM_CONFIG):
$(ToolDir)/$(strip $(TOOLNAME))$(EXEEXT): $(LLVM_CONFIG) $(ToolDir)/$(strip $(TOOLNAME))$(EXEEXT): $(LLVM_CONFIG)
ifeq ($(ENABLE_SHARED), 1) ifeq ($(ENABLE_SHARED), 1)
# We can take the "auto-import" feature to get rid of using dllimport.
ifeq ($(HOST_OS), $(filter $(HOST_OS), Cygwin MingW))
LLVMLibsOptions += -Wl,--enable-auto-import,--enable-runtime-pseudo-reloc \
-L $(SharedLibDir)
endif
LLVMLibsOptions += -lLLVM-$(LLVMVersion) LLVMLibsOptions += -lLLVM-$(LLVMVersion)
LLVMLibsPaths += $(LibDir)/libLLVM-$(LLVMVersion)$(SHLIBEXT) LLVMLibsPaths += $(SharedLibDir)/$(SharedPrefix)LLVM-$(LLVMVersion)$(SHLIBEXT)
else else
LLVMLibsOptions += $(shell $(LLVM_CONFIG) --libs $(LINK_COMPONENTS))
LLVMLibsPaths += $(LLVM_CONFIG) \ ifndef NO_LLVM_CONFIG
$(shell $(LLVM_CONFIG) --libfiles $(LINK_COMPONENTS)) LLVMConfigLibs := $(shell $(LLVM_CONFIG) --libs $(LINK_COMPONENTS) || echo Error)
ifeq ($(LLVMConfigLibs),Error)
$(error llvm-config --libs failed)
endif
LLVMLibsOptions += $(LLVMConfigLibs)
LLVMConfigLibfiles := $(shell $(LLVM_CONFIG) --libfiles $(LINK_COMPONENTS) || echo Error)
ifeq ($(LLVMConfigLibfiles),Error)
$(error llvm-config --libfiles failed)
endif
LLVMLibsPaths += $(LLVM_CONFIG) $(LLVMConfigLibfiles)
endif
endif endif
endif endif
endif endif
@ -1011,12 +961,25 @@ $(NativeExportsFile): $(EXPORTED_SYMBOL_FILE) $(ObjDir)/.dir
clean-local:: clean-local::
-$(Verb) $(RM) -f $(NativeExportsFile) -$(Verb) $(RM) -f $(NativeExportsFile)
else else
ifeq ($(HOST_OS), $(filter $(HOST_OS), Cygwin MingW))
# GNU ld Win32 accepts .DEF files that contain "DATA" entries.
NativeExportsFile := $(ObjDir)/$(notdir $(EXPORTED_SYMBOL_FILE:.exports=.def))
$(NativeExportsFile): $(EXPORTED_SYMBOL_FILE) $(ObjDir)/.dir
$(Echo) Generating $(notdir $@)
$(Verb) $(ECHO) "EXPORTS" > $@
$(Verb) $(CAT) $< >> $@
clean-local::
-$(Verb) $(RM) -f $(NativeExportsFile)
else
# Default behavior: just use the exports file verbatim.
NativeExportsFile := $(EXPORTED_SYMBOL_FILE) NativeExportsFile := $(EXPORTED_SYMBOL_FILE)
endif endif
endif endif
endif
# Now add the linker command-line options to use the native export file. # Now add the linker command-line options to use the native export file.
# Darwin
ifeq ($(HOST_OS),Darwin) ifeq ($(HOST_OS),Darwin)
LLVMLibsOptions += -Wl,-exported_symbols_list,$(NativeExportsFile) LLVMLibsOptions += -Wl,-exported_symbols_list,$(NativeExportsFile)
endif endif
@ -1026,6 +989,12 @@ ifeq ($(HAVE_LINK_VERSION_SCRIPT),1)
LLVMLibsOptions += -Wl,--version-script,$(NativeExportsFile) LLVMLibsOptions += -Wl,--version-script,$(NativeExportsFile)
endif endif
# Windows
ifeq ($(HOST_OS), $(filter $(HOST_OS), Cygwin MingW))
# LLVMLibsOptions is invalidated at processing tools/llvm-shlib.
SharedLinkOptions += $(NativeExportsFile)
endif
endif endif
############################################################################### ###############################################################################
@ -1100,10 +1069,10 @@ ifdef LIBRARYNAME
LIBRARYNAME := $(strip $(LIBRARYNAME)) LIBRARYNAME := $(strip $(LIBRARYNAME))
ifdef LOADABLE_MODULE ifdef LOADABLE_MODULE
LibName.A := $(LibDir)/$(LIBRARYNAME).a LibName.A := $(LibDir)/$(LIBRARYNAME).a
LibName.SO := $(LibDir)/$(LIBRARYNAME)$(SHLIBEXT) LibName.SO := $(SharedLibDir)/$(LIBRARYNAME)$(SHLIBEXT)
else else
LibName.A := $(LibDir)/lib$(LIBRARYNAME).a LibName.A := $(LibDir)/lib$(LIBRARYNAME).a
LibName.SO := $(LibDir)/lib$(LIBRARYNAME)$(SHLIBEXT) LibName.SO := $(SharedLibDir)/$(SharedPrefix)$(LIBRARYNAME)$(SHLIBEXT)
endif endif
LibName.O := $(LibDir)/$(LIBRARYNAME).o LibName.O := $(LibDir)/$(LIBRARYNAME).o
LibName.BCA:= $(LibDir)/lib$(LIBRARYNAME).bca LibName.BCA:= $(LibDir)/lib$(LIBRARYNAME).bca
@ -1128,14 +1097,14 @@ SharedLibKindMessage := "Loadable Module"
else else
SharedLibKindMessage := "Shared Library" SharedLibKindMessage := "Shared Library"
endif endif
$(LibName.SO): $(ObjectsO) $(ProjLibsPaths) $(LLVMLibsPaths) $(LibDir)/.dir $(LibName.SO): $(ObjectsO) $(ProjLibsPaths) $(LLVMLibsPaths) $(SharedLibDir)/.dir
$(Echo) Linking $(BuildMode) $(SharedLibKindMessage) \ $(Echo) Linking $(BuildMode) $(SharedLibKindMessage) \
$(LIBRARYNAME)$(SHLIBEXT) $(notdir $@)
$(Verb) $(Link) $(SharedLinkOptions) -o $@ $(ObjectsO) \ $(Verb) $(Link) $(SharedLinkOptions) -o $@ $(ObjectsO) \
$(ProjLibsOptions) $(LLVMLibsOptions) $(LIBS) $(ProjLibsOptions) $(LLVMLibsOptions) $(LIBS)
else else
$(LibName.SO): $(ObjectsO) $(LibDir)/.dir $(LibName.SO): $(ObjectsO) $(SharedLibDir)/.dir
$(Echo) Linking $(BuildMode) Shared Library $(basename $@) $(Echo) Linking $(BuildMode) Shared Library $(notdir $@)
$(Verb) $(Link) $(SharedLinkOptions) -o $@ $(ObjectsO) $(Verb) $(Link) $(SharedLinkOptions) -o $@ $(ObjectsO)
endif endif
@ -1151,21 +1120,23 @@ uninstall-local::
$(Echo) Uninstall circumvented with NO_INSTALL $(Echo) Uninstall circumvented with NO_INSTALL
else else
ifdef LOADABLE_MODULE # Win32.DLL prefers to be located on the "PATH" of binaries.
DestSharedLib = $(DESTDIR)$(PROJ_libdir)/$(LIBRARYNAME)$(SHLIBEXT) ifeq ($(HOST_OS), $(filter $(HOST_OS), Cygwin MingW))
DestSharedLibDir := $(DESTDIR)$(PROJ_bindir)
else else
DestSharedLib = $(DESTDIR)$(PROJ_libdir)/lib$(LIBRARYNAME)$(SHLIBEXT) DestSharedLibDir := $(DESTDIR)$(PROJ_libdir)
endif endif
DestSharedLib := $(DestSharedLibDir)/$(SharedPrefix)$(LIBRARYNAME)$(SHLIBEXT)
install-local:: $(DestSharedLib) install-local:: $(DestSharedLib)
$(DestSharedLib): $(LibName.SO) $(DESTDIR)$(PROJ_libdir) $(DestSharedLib): $(LibName.SO) $(DestSharedLibDir)
$(Echo) Installing $(BuildMode) Shared Library $(DestSharedLib) $(Echo) Installing $(BuildMode) Shared Library $(DestSharedLib)
$(Verb) $(INSTALL) $(LibName.SO) $(DestSharedLib) $(Verb) $(INSTALL) $(LibName.SO) $(DestSharedLib)
uninstall-local:: uninstall-local::
$(Echo) Uninstalling $(BuildMode) Shared Library $(DestSharedLib) $(Echo) Uninstalling $(BuildMode) Shared Library $(DestSharedLib)
-$(Verb) $(RM) -f $(DESTDIR)$(PROJ_libdir)/lib$(LIBRARYNAME).* -$(Verb) $(RM) -f $(DestSharedLibDir)/$(SharedPrefix)$(LIBRARYNAME).*
endif endif
endif endif
@ -1341,10 +1312,33 @@ endif
endif endif
ifeq ($(HOST_OS), $(filter $(HOST_OS), Linux NetBSD FreeBSD)) ifeq ($(HOST_OS), $(filter $(HOST_OS), Linux NetBSD FreeBSD))
ifneq ($(ARCH), Mips)
LD.Flags += -Wl,--version-script=$(LLVM_SRC_ROOT)/autoconf/ExportMap.map LD.Flags += -Wl,--version-script=$(LLVM_SRC_ROOT)/autoconf/ExportMap.map
endif endif
endif endif
endif
#---------------------------------------------------------
# Tool Version Info Support
#---------------------------------------------------------
ifeq ($(HOST_OS),Darwin)
ifdef TOOL_INFO_PLIST
LD.Flags += -Wl,-sectcreate,__TEXT,__info_plist,$(ObjDir)/$(TOOL_INFO_PLIST)
$(ToolBuildPath): $(ObjDir)/$(TOOL_INFO_PLIST)
$(ObjDir)/$(TOOL_INFO_PLIST): $(PROJ_SRC_DIR)/$(TOOL_INFO_PLIST).in $(ObjDir)/.dir
$(Echo) "Creating $(TOOLNAME) '$(TOOL_INFO_PLIST)' file..."
$(Verb)sed -e "s#@TOOL_INFO_UTI@#$(TOOL_INFO_UTI)#g" \
-e "s#@TOOL_INFO_NAME@#$(TOOL_INFO_NAME)#g" \
-e "s#@TOOL_INFO_VERSION@#$(TOOL_INFO_VERSION)#g" \
-e "s#@TOOL_INFO_BUILD_VERSION@#$(TOOL_INFO_BUILD_VERSION)#g" \
$< > $@
endif
endif
#--------------------------------------------------------- #---------------------------------------------------------
# Provide targets for building the tools # Provide targets for building the tools
@ -1377,7 +1371,7 @@ $(ToolAliasBuildPath): $(ToolBuildPath)
$(Echo) Creating $(BuildMode) Alias $(TOOLALIAS) $(StripWarnMsg) $(Echo) Creating $(BuildMode) Alias $(TOOLALIAS) $(StripWarnMsg)
$(Verb) $(RM) -f $(ToolAliasBuildPath) $(Verb) $(RM) -f $(ToolAliasBuildPath)
$(Verb) $(AliasTool) $(TOOLEXENAME) $(ToolAliasBuildPath) $(Verb) $(AliasTool) $(TOOLEXENAME) $(ToolAliasBuildPath)
$(Echo) ======= Finished Creating $(BuildMode) Alias $(TOOLNAME) \ $(Echo) ======= Finished Creating $(BuildMode) Alias $(TOOLALIAS) \
$(StripWarnMsg) $(StripWarnMsg)
endif endif
@ -1626,7 +1620,7 @@ ifdef TARGET
TABLEGEN_INC_FILES_COMMON = 1 TABLEGEN_INC_FILES_COMMON = 1
endif endif
ifdef LLVMC_BUILD_AUTOGENERATED_INC ifdef LLVMC_BASED_DRIVER
TABLEGEN_INC_FILES_COMMON = 1 TABLEGEN_INC_FILES_COMMON = 1
endif endif
@ -1750,20 +1744,26 @@ clean-local::
endif # TARGET endif # TARGET
ifdef LLVMC_BUILD_AUTOGENERATED_INC ifdef LLVMC_BASED_DRIVER
LLVMCPluginSrc := $(sort $(strip $(wildcard $(PROJ_SRC_DIR)/*.td)) \ TDSrc := $(sort $(strip $(wildcard $(PROJ_SRC_DIR)/*.td)) \
$(strip $(wildcard $(PROJ_OBJ_DIR)/*.td))) $(strip $(wildcard $(PROJ_OBJ_DIR)/*.td)))
TDFiles := $(LLVMCPluginSrc) \ TDCommon := $(strip $(wildcard \
$(strip $(wildcard $(LLVM_SRC_ROOT)/include/llvm/CompilerDriver/*.td)) $(LLVM_SRC_ROOT)/include/llvm/CompilerDriver/*.td))
$(ObjDir)/AutoGenerated.inc.tmp: $(LLVMCPluginSrc) $(ObjDir)/.dir \ TDFiles := $(TDSrc) $(TDCommon)
$(TBLGEN) $(TD_COMMON)
$(Echo) "Building LLVMC configuration library with tblgen" $(INCTMPFiles) : $(TBLGEN) $(TDFiles)
$(ObjDir)/%.inc.tmp: %.td $(ObjDir)/.dir
$(Echo) "Building LLVMC compilation graph description with tblgen"
$(Verb) $(TableGen) -gen-llvmc -o $(call SYSPATH, $@) $< $(Verb) $(TableGen) -gen-llvmc -o $(call SYSPATH, $@) $<
endif # LLVMC_BUILD_AUTOGENERATED_INC clean-local::
-$(Verb) $(RM) -f $(INCFiles)
endif # LLVMC_BASED_DRIVER
############################################################################### ###############################################################################
# OTHER RULES: Other rules needed # OTHER RULES: Other rules needed
@ -1840,11 +1840,13 @@ check::
$(EchoCmd) No test directory ; \ $(EchoCmd) No test directory ; \
fi fi
check-lit:: check-lit:: check
check-dg::
$(Verb) if test -d "$(PROJ_OBJ_ROOT)/test" ; then \ $(Verb) if test -d "$(PROJ_OBJ_ROOT)/test" ; then \
if test -f "$(PROJ_OBJ_ROOT)/test/Makefile" ; then \ if test -f "$(PROJ_OBJ_ROOT)/test/Makefile" ; then \
$(EchoCmd) Running test suite ; \ $(EchoCmd) Running test suite ; \
$(MAKE) -C $(PROJ_OBJ_ROOT)/test check-local-lit ; \ $(MAKE) -C $(PROJ_OBJ_ROOT)/test check-local-dg ; \
else \ else \
$(EchoCmd) No Makefile in test directory ; \ $(EchoCmd) No Makefile in test directory ; \
fi ; \ fi ; \

View File

@ -1,4 +1,4 @@
Low Level Virtual Machine (LLVM) \Low Level Virtual Machine (LLVM)
================================ ================================
This directory and its subdirectories contain source code for the Low Level This directory and its subdirectories contain source code for the Low Level
@ -13,3 +13,4 @@ assistance with LLVM.
If you're writing a package for LLVM, see docs/Packaging.html for our If you're writing a package for LLVM, see docs/Packaging.html for our
suggestions. suggestions.

View File

@ -31,7 +31,7 @@ dnl===
dnl===-----------------------------------------------------------------------=== dnl===-----------------------------------------------------------------------===
dnl Initialize autoconf and define the package name, version number and dnl Initialize autoconf and define the package name, version number and
dnl email address for reporting bugs. dnl email address for reporting bugs.
AC_INIT([[llvm]],[[2.8svn]],[llvmbugs@cs.uiuc.edu]) AC_INIT([[llvm]],[[2.8rc]],[llvmbugs@cs.uiuc.edu])
dnl Provide a copyright substitution and ensure the copyright notice is included dnl Provide a copyright substitution and ensure the copyright notice is included
dnl in the output of --version option of the generated configure script. dnl in the output of --version option of the generated configure script.
@ -101,7 +101,6 @@ for i in `ls ${srcdir}/projects`
do do
if test -d ${srcdir}/projects/${i} ; then if test -d ${srcdir}/projects/${i} ; then
case ${i} in case ${i} in
CVS) ;;
sample) AC_CONFIG_SUBDIRS([projects/sample]) ;; sample) AC_CONFIG_SUBDIRS([projects/sample]) ;;
privbracket) AC_CONFIG_SUBDIRS([projects/privbracket]) ;; privbracket) AC_CONFIG_SUBDIRS([projects/privbracket]) ;;
llvm-stacker) AC_CONFIG_SUBDIRS([projects/llvm-stacker]) ;; llvm-stacker) AC_CONFIG_SUBDIRS([projects/llvm-stacker]) ;;
@ -299,7 +298,7 @@ dnl Set the LINKALL and NOLINKALL Makefile variables based on the platform
AC_SUBST(LINKALL,$llvm_cv_link_all_option) AC_SUBST(LINKALL,$llvm_cv_link_all_option)
AC_SUBST(NOLINKALL,$llvm_cv_no_link_all_option) AC_SUBST(NOLINKALL,$llvm_cv_no_link_all_option)
dnl Set the "LLVM_ON_*" variables based on llvm_cvs_platform_type dnl Set the "LLVM_ON_*" variables based on llvm_cv_platform_type
dnl This is used by lib/System to determine the basic kind of implementation dnl This is used by lib/System to determine the basic kind of implementation
dnl to use. dnl to use.
case $llvm_cv_platform_type in case $llvm_cv_platform_type in
@ -369,13 +368,13 @@ else
AC_SUBST(LLVM_CROSS_COMPILING, [0]) AC_SUBST(LLVM_CROSS_COMPILING, [0])
fi fi
dnl Check to see if there's a "CVS" (or .svn or .git) directory indicating dnl Check to see if there's a .svn or .git directory indicating that this
dnl that this build is being done from a checkout. This sets up several dnl build is being done from a checkout. This sets up several defaults for
dnl defaults for the command line switches. When we build with a CVS directory, dnl the command line switches. When we build with a checkout directory,
dnl we get a debug with assertions turned on. Without, we assume a source dnl we get a debug with assertions turned on. Without, we assume a source
dnl release and we get an optimized build without assertions. dnl release and we get an optimized build without assertions.
dnl See --enable-optimized and --enable-assertions below dnl See --enable-optimized and --enable-assertions below
if test -d "CVS" -o -d "${srcdir}/CVS" -o -d ".svn" -o -d "${srcdir}/.svn" -o -d ".git" -o -d "${srcdir}/.git"; then if test -d ".svn" -o -d "${srcdir}/.svn" -o -d ".git" -o -d "${srcdir}/.git"; then
cvsbuild="yes" cvsbuild="yes"
optimize="no" optimize="no"
AC_SUBST(CVSBUILD,[[CVSBUILD=1]]) AC_SUBST(CVSBUILD,[[CVSBUILD=1]])
@ -392,7 +391,7 @@ dnl===-----------------------------------------------------------------------===
dnl --enable-optimized : check whether they want to do an optimized build: dnl --enable-optimized : check whether they want to do an optimized build:
AC_ARG_ENABLE(optimized, AS_HELP_STRING( AC_ARG_ENABLE(optimized, AS_HELP_STRING(
--enable-optimized,[Compile with optimizations enabled (default is NO)]),,enableval=$optimize) --enable-optimized,[Compile with optimizations enabled (default is YES)]),,enableval="yes")
if test ${enableval} = "no" ; then if test ${enableval} = "no" ; then
AC_SUBST(ENABLE_OPTIMIZED,[[]]) AC_SUBST(ENABLE_OPTIMIZED,[[]])
else else
@ -410,7 +409,7 @@ fi
dnl --enable-assertions : check whether they want to turn on assertions or not: dnl --enable-assertions : check whether they want to turn on assertions or not:
AC_ARG_ENABLE(assertions,AS_HELP_STRING( AC_ARG_ENABLE(assertions,AS_HELP_STRING(
--enable-assertions,[Compile with assertion checks enabled (default is YES)]),, enableval="yes") --enable-assertions,[Compile with assertion checks enabled (default is NO)]),, enableval="no")
if test ${enableval} = "yes" ; then if test ${enableval} = "yes" ; then
AC_SUBST(DISABLE_ASSERTIONS,[[]]) AC_SUBST(DISABLE_ASSERTIONS,[[]])
else else
@ -544,13 +543,13 @@ TARGETS_TO_BUILD=""
AC_ARG_ENABLE([targets],AS_HELP_STRING([--enable-targets], AC_ARG_ENABLE([targets],AS_HELP_STRING([--enable-targets],
[Build specific host targets: all or target1,target2,... Valid targets are: [Build specific host targets: all or target1,target2,... Valid targets are:
host, x86, x86_64, sparc, powerpc, alpha, arm, mips, spu, pic16, host, x86, x86_64, sparc, powerpc, alpha, arm, mips, spu, pic16,
xcore, msp430, systemz, blackfin, cbe, msil, and cpp (default=all)]),, xcore, msp430, systemz, blackfin, cbe, and cpp (default=all)]),,
enableval=all) enableval=all)
if test "$enableval" = host-only ; then if test "$enableval" = host-only ; then
enableval=host enableval=host
fi fi
case "$enableval" in case "$enableval" in
all) TARGETS_TO_BUILD="X86 Sparc PowerPC Alpha ARM Mips CellSPU PIC16 XCore MSP430 SystemZ Blackfin CBackend MSIL CppBackend MBlaze" ;; all) TARGETS_TO_BUILD="X86 Sparc PowerPC Alpha ARM Mips CellSPU PIC16 XCore MSP430 SystemZ Blackfin CBackend CppBackend MBlaze" ;;
*)for a_target in `echo $enableval|sed -e 's/,/ /g' ` ; do *)for a_target in `echo $enableval|sed -e 's/,/ /g' ` ; do
case "$a_target" in case "$a_target" in
x86) TARGETS_TO_BUILD="X86 $TARGETS_TO_BUILD" ;; x86) TARGETS_TO_BUILD="X86 $TARGETS_TO_BUILD" ;;
@ -567,7 +566,6 @@ case "$enableval" in
systemz) TARGETS_TO_BUILD="SystemZ $TARGETS_TO_BUILD" ;; systemz) TARGETS_TO_BUILD="SystemZ $TARGETS_TO_BUILD" ;;
blackfin) TARGETS_TO_BUILD="Blackfin $TARGETS_TO_BUILD" ;; blackfin) TARGETS_TO_BUILD="Blackfin $TARGETS_TO_BUILD" ;;
cbe) TARGETS_TO_BUILD="CBackend $TARGETS_TO_BUILD" ;; cbe) TARGETS_TO_BUILD="CBackend $TARGETS_TO_BUILD" ;;
msil) TARGETS_TO_BUILD="MSIL $TARGETS_TO_BUILD" ;;
cpp) TARGETS_TO_BUILD="CppBackend $TARGETS_TO_BUILD" ;; cpp) TARGETS_TO_BUILD="CppBackend $TARGETS_TO_BUILD" ;;
mblaze) TARGETS_TO_BUILD="MBlaze $TARGETS_TO_BUILD" ;; mblaze) TARGETS_TO_BUILD="MBlaze $TARGETS_TO_BUILD" ;;
host) case "$llvm_cv_target_arch" in host) case "$llvm_cv_target_arch" in
@ -598,9 +596,17 @@ AC_SUBST(TARGETS_TO_BUILD,$TARGETS_TO_BUILD)
# If so, define LLVM_NATIVE_ARCH to that LLVM target. # If so, define LLVM_NATIVE_ARCH to that LLVM target.
for a_target in $TARGETS_TO_BUILD; do for a_target in $TARGETS_TO_BUILD; do
if test "$a_target" = "$LLVM_NATIVE_ARCH"; then if test "$a_target" = "$LLVM_NATIVE_ARCH"; then
LLVM_NATIVE_ARCHTARGET="${LLVM_NATIVE_ARCH}Target" AC_DEFINE_UNQUOTED(LLVM_NATIVE_ARCH, $LLVM_NATIVE_ARCH,
AC_DEFINE_UNQUOTED(LLVM_NATIVE_ARCH,$LLVM_NATIVE_ARCHTARGET,
[LLVM architecture name for the native architecture, if available]) [LLVM architecture name for the native architecture, if available])
LLVM_NATIVE_TARGET="LLVMInitialize${LLVM_NATIVE_ARCH}Target"
LLVM_NATIVE_TARGETINFO="LLVMInitialize${LLVM_NATIVE_ARCH}TargetInfo"
LLVM_NATIVE_ASMPRINTER="LLVMInitialize${LLVM_NATIVE_ARCH}AsmPrinter"
AC_DEFINE_UNQUOTED(LLVM_NATIVE_TARGET, $LLVM_NATIVE_TARGET,
[LLVM name for the native Target init function, if available])
AC_DEFINE_UNQUOTED(LLVM_NATIVE_TARGETINFO, $LLVM_NATIVE_TARGETINFO,
[LLVM name for the native TargetInfo init function, if available])
AC_DEFINE_UNQUOTED(LLVM_NATIVE_ASMPRINTER, $LLVM_NATIVE_ASMPRINTER,
[LLVM name for the native AsmPrinter init function, if available])
fi fi
done done
@ -857,35 +863,6 @@ AC_ARG_ENABLE(libffi,AS_HELP_STRING(
esac], esac],
llvm_cv_enable_libffi=no) llvm_cv_enable_libffi=no)
dnl Only Windows needs dynamic libCompilerDriver to support plugins.
if test "$llvm_cv_os_type" = "Win32" ; then
llvmc_dynamic="yes"
else
llvmc_dynamic="no"
fi
dnl --enable-llvmc-dynamic : should LLVMC link libCompilerDriver dynamically?
AC_ARG_ENABLE(llvmc-dynamic,AS_HELP_STRING(
--enable-llvmc-dynamic,
[Link LLVMC dynamically (default is NO, unless on Win32)]),,
enableval=$llvmc_dynamic)
if test ${enableval} = "yes" && test "$ENABLE_PIC" -eq 1 ; then
AC_SUBST(ENABLE_LLVMC_DYNAMIC,[[ENABLE_LLVMC_DYNAMIC=1]])
else
AC_SUBST(ENABLE_LLVMC_DYNAMIC,[[]])
fi
dnl --enable-llvmc-dynamic-plugins : should LLVMC support dynamic plugins?
AC_ARG_ENABLE(llvmc-dynamic-plugins,AS_HELP_STRING(
--enable-llvmc-dynamic-plugins,
[Enable dynamic LLVMC plugins (default is YES)]),,
enableval=yes)
if test ${enableval} = "yes" ; then
AC_SUBST(ENABLE_LLVMC_DYNAMIC_PLUGINS,[[ENABLE_LLVMC_DYNAMIC_PLUGINS=1]])
else
AC_SUBST(ENABLE_LLVMC_DYNAMIC_PLUGINS,[[]])
fi
dnl===-----------------------------------------------------------------------=== dnl===-----------------------------------------------------------------------===
dnl=== dnl===
dnl=== SECTION 4: Check for programs we need and that they are the right version dnl=== SECTION 4: Check for programs we need and that they are the right version
@ -1011,6 +988,13 @@ fi
dnl Find the install program dnl Find the install program
AC_PROG_INSTALL AC_PROG_INSTALL
dnl Prepend src dir to install path dir if it's a relative path
dnl This is a hack for installs that take place in something other
dnl than the top level.
case "$INSTALL" in
[[\\/$]]* | ?:[[\\/]]* ) ;;
*) INSTALL="\\\$(TOPSRCDIR)/$INSTALL" ;;
esac
dnl Checks for documentation and testing tools that we can do without. If these dnl Checks for documentation and testing tools that we can do without. If these
dnl are not found then they are set to "true" which always succeeds but does dnl are not found then they are set to "true" which always succeeds but does
@ -1033,6 +1017,9 @@ AC_PATH_PROGS(OCAMLDEP, [ocamldep])
AC_PATH_PROGS(OCAMLDOC, [ocamldoc]) AC_PATH_PROGS(OCAMLDOC, [ocamldoc])
AC_PATH_PROGS(GAS, [gas as]) AC_PATH_PROGS(GAS, [gas as])
dnl Get the version of the linker in use.
AC_LINK_GET_VERSION
dnl Determine whether the linker supports the -R option. dnl Determine whether the linker supports the -R option.
AC_LINK_USE_R AC_LINK_USE_R
@ -1345,6 +1332,9 @@ fi
dnl atomic builtins are required for threading support. dnl atomic builtins are required for threading support.
AC_MSG_CHECKING(for GCC atomic builtins) AC_MSG_CHECKING(for GCC atomic builtins)
dnl Since we'll be using these atomic builtins in C++ files we should test
dnl the C++ compiler.
AC_LANG_PUSH([C++])
AC_LINK_IFELSE( AC_LINK_IFELSE(
AC_LANG_SOURCE( AC_LANG_SOURCE(
[[int main() { [[int main() {
@ -1356,13 +1346,13 @@ AC_LINK_IFELSE(
return 0; return 0;
} }
]]), ]]),
AC_LANG_POP([C++])
AC_MSG_RESULT(yes) AC_MSG_RESULT(yes)
AC_DEFINE(LLVM_MULTITHREADED, 1, Build multithreading support into LLVM), AC_DEFINE(LLVM_MULTITHREADED, 1, Build multithreading support into LLVM),
AC_MSG_RESULT(no) AC_MSG_RESULT(no)
AC_DEFINE(LLVM_MULTITHREADED, 0, Build multithreading support into LLVM) AC_DEFINE(LLVM_MULTITHREADED, 0, Build multithreading support into LLVM)
AC_MSG_WARN([LLVM will be built thread-unsafe because atomic builtins are missing])) AC_MSG_WARN([LLVM will be built thread-unsafe because atomic builtins are missing]))
dnl===-----------------------------------------------------------------------=== dnl===-----------------------------------------------------------------------===
dnl=== dnl===
dnl=== SECTION 9: Additional checks, variables, etc. dnl=== SECTION 9: Additional checks, variables, etc.
@ -1549,7 +1539,11 @@ dnl WARNING: dnl If you add or remove any of the following config headers, then
dnl you MUST also update Makefile.rules so that the variable FilesToConfig dnl you MUST also update Makefile.rules so that the variable FilesToConfig
dnl contains the same list of files as AC_CONFIG_HEADERS below. This ensures the dnl contains the same list of files as AC_CONFIG_HEADERS below. This ensures the
dnl files can be updated automatically when their *.in sources change. dnl files can be updated automatically when their *.in sources change.
AC_CONFIG_HEADERS([include/llvm/Config/config.h]) AC_CONFIG_HEADERS([include/llvm/Config/config.h include/llvm/Config/llvm-config.h])
AH_TOP([#ifndef CONFIG_H
#define CONFIG_H])
AH_BOTTOM([#endif])
AC_CONFIG_FILES([include/llvm/Config/Targets.def]) AC_CONFIG_FILES([include/llvm/Config/Targets.def])
AC_CONFIG_FILES([include/llvm/Config/AsmPrinters.def]) AC_CONFIG_FILES([include/llvm/Config/AsmPrinters.def])
AC_CONFIG_FILES([include/llvm/Config/AsmParsers.def]) AC_CONFIG_FILES([include/llvm/Config/AsmParsers.def])
@ -1563,7 +1557,7 @@ dnl Configure the RPM spec file for LLVM
AC_CONFIG_FILES([llvm.spec]) AC_CONFIG_FILES([llvm.spec])
dnl Configure llvmc's Base plugin dnl Configure llvmc's Base plugin
AC_CONFIG_FILES([tools/llvmc/plugins/Base/Base.td]) AC_CONFIG_FILES([tools/llvmc/src/Base.td])
dnl Do the first stage of configuration for llvm-config.in. dnl Do the first stage of configuration for llvm-config.in.
AC_CONFIG_FILES([tools/llvm-config/llvm-config.in]) AC_CONFIG_FILES([tools/llvm-config/llvm-config.in])

View File

@ -1,15 +0,0 @@
#
# Check for Bison.
#
# This macro verifies that Bison is installed. If successful, then
# 1) YACC is set to bison -y (to emulate YACC calls)
# 2) BISON is set to bison
#
AC_DEFUN([AC_PROG_BISON],
[AC_CACHE_CHECK([],[llvm_cv_has_bison],[AC_PROG_YACC()])
if test "$YACC" != "bison -y"; then
AC_SUBST(BISON,[])
AC_MSG_WARN([bison not found, can't rebuild grammars])
else
AC_SUBST(BISON,[bison])
fi])

View File

@ -1,22 +0,0 @@
#
# Check for bidirectional iterator extension. This is modified from
# http://www.gnu.org/software/ac-archive/htmldoc/ac_cxx_have_ext_hash_set.html
#
AC_DEFUN([AC_CXX_HAVE_BI_ITERATOR],
[AC_CACHE_CHECK(whether the compiler has the bidirectional iterator,
ac_cv_cxx_have_bi_iterator,
[AC_REQUIRE([AC_CXX_NAMESPACES])
AC_LANG_PUSH([C++])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <iterator>
#ifdef HAVE_NAMESPACES
using namespace std;
#endif]], [[bidirectional_iterator<int,int> t; return 0;]])],[ac_cv_cxx_have_bi_iterator=yes],[ac_cv_cxx_have_bi_iterator=no])
AC_LANG_POP([C++])
])
if test "$ac_cv_cxx_have_bi_iterator" = yes
then
AC_DEFINE(HAVE_BI_ITERATOR,1,[Have bi-directional iterator])
else
AC_DEFINE(HAVE_BI_ITERATOR,0,[Does not have bi-directional iterator])
fi
])

View File

@ -1,22 +0,0 @@
# Check for forward iterator extension. This is modified from
# http://www.gnu.org/software/ac-archive/htmldoc/ac_cxx_have_ext_hash_set.html
AC_DEFUN([AC_CXX_HAVE_FWD_ITERATOR],
[AC_CACHE_CHECK(whether the compiler has forward iterators,
ac_cv_cxx_have_fwd_iterator,
[AC_REQUIRE([AC_CXX_NAMESPACES])
AC_LANG_PUSH([C++])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <iterator>
#ifdef HAVE_NAMESPACES
using namespace std;
#endif]], [[forward_iterator<int,int> t; return 0;]])],[ac_cv_cxx_have_fwd_iterator=yes],[ac_cv_cxx_have_fwd_iterator=no])
AC_LANG_POP([C++])
])
if test "$ac_cv_cxx_have_fwd_iterator" = yes
then
AC_DEFINE(HAVE_FWD_ITERATOR,1,[Have forward iterator])
else
AC_DEFINE(HAVE_FWD_ITERATOR,0,[Does not have forward iterator])
fi
])

View File

@ -1,19 +0,0 @@
# Check for C++ namespace support. This is from
# http://www.gnu.org/software/ac-archive/htmldoc/ac_cxx_namespaces.html
#
AC_DEFUN([AC_CXX_NAMESPACES],
[AC_CACHE_CHECK(whether the compiler implements namespaces,
ac_cv_cxx_namespaces,
[AC_LANG_PUSH([C++])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
[[namespace Outer { namespace Inner { int i = 0; }}]],
[[using namespace Outer::Inner; return i;]])],
ac_cv_cxx_namespaces=yes,
ac_cv_cxx_namespaces=no)
AC_LANG_POP([C++])
])
if test "$ac_cv_cxx_namespaces" = yes; then
AC_DEFINE(HAVE_NAMESPACES,,[define if the compiler implements namespaces])
fi
])

View File

@ -1,26 +0,0 @@
# Check for standard iterator extension. This is modified from
# http://www.gnu.org/software/ac-archive/htmldoc/ac_cxx_have_ext_hash_set.html
AC_DEFUN([AC_CXX_HAVE_STD_ITERATOR],
[AC_CACHE_CHECK(whether the compiler has the standard iterator,
ac_cv_cxx_have_std_iterator,
[AC_REQUIRE([AC_CXX_NAMESPACES])
AC_LANG_PUSH([C++])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
[[#include <iterator>
#ifdef HAVE_NAMESPACES
using namespace std;
#endif]],
[[iterator<int,int,int> t; return 0;]])],
ac_cv_cxx_have_std_iterator=yes,
ac_cv_cxx_have_std_iterator=no)
AC_LANG_POP([C++])
])
if test "$ac_cv_cxx_have_std_iterator" = yes
then
AC_DEFINE(HAVE_STD_ITERATOR,1,[Have std namespace iterator])
else
AC_DEFINE(HAVE_STD_ITERATOR,0,[Does not have std namespace iterator])
fi
])

View File

@ -1,17 +0,0 @@
#
# Check for FLEX.
#
# This macro verifies that flex is installed. If successful, then
# 1) $LEX is set to "flex" (to emulate lex calls)
# 2) BISON is set to bison
AC_DEFUN([AC_PROG_FLEX],
[AC_CACHE_CHECK(,
ac_cv_has_flex,
[AC_PROG_LEX()
])
if test "$LEX" != "flex"; then
AC_MSG_ERROR([flex not found but required])
else
AC_SUBST(FLEX,[flex],[location of flex])
fi
])

View File

@ -1,3 +1,24 @@
#
# Get the linker version string.
#
# This macro is specific to LLVM.
#
AC_DEFUN([AC_LINK_GET_VERSION],
[AC_CACHE_CHECK([for linker version],[llvm_cv_link_version],
[
version_string="$(ld -v 2>&1 | head -1)"
# Check for ld64.
if (echo "$version_string" | grep -q "ld64"); then
llvm_cv_link_version=$(echo "$version_string" | sed -e "s#.*ld64-\([^ ]*\)#\1#")
else
llvm_cv_link_version=$(echo "$version_string" | sed -e "s#[^0-9]*\([0-9.]*\).*#\1#")
fi
])
AC_DEFINE_UNQUOTED([HOST_LINK_VERSION],"$llvm_cv_link_version",
[Linker version detected at compile time.])
])
# #
# Determine if the system can handle the -R option being passed to the linker. # Determine if the system can handle the -R option being passed to the linker.
# #

View File

@ -317,25 +317,27 @@ package llvm is
LLVMGhostLinkage, LLVMGhostLinkage,
LLVMCommonLinkage, LLVMCommonLinkage,
LLVMLinkerPrivateLinkage, LLVMLinkerPrivateLinkage,
LLVMLinkerPrivateWeakLinkage); LLVMLinkerPrivateWeakLinkage,
LinkerPrivateWeakDefAutoLinkage);
for LLVMLinkage use for LLVMLinkage use
(LLVMExternalLinkage => 0, (LLVMExternalLinkage => 0,
LLVMAvailableExternallyLinkage => 1, LLVMAvailableExternallyLinkage => 1,
LLVMLinkOnceAnyLinkage => 2, LLVMLinkOnceAnyLinkage => 2,
LLVMLinkOnceODRLinkage => 3, LLVMLinkOnceODRLinkage => 3,
LLVMWeakAnyLinkage => 4, LLVMWeakAnyLinkage => 4,
LLVMWeakODRLinkage => 5, LLVMWeakODRLinkage => 5,
LLVMAppendingLinkage => 6, LLVMAppendingLinkage => 6,
LLVMInternalLinkage => 7, LLVMInternalLinkage => 7,
LLVMPrivateLinkage => 8, LLVMPrivateLinkage => 8,
LLVMDLLImportLinkage => 9, LLVMDLLImportLinkage => 9,
LLVMDLLExportLinkage => 10, LLVMDLLExportLinkage => 10,
LLVMExternalWeakLinkage => 11, LLVMExternalWeakLinkage => 11,
LLVMGhostLinkage => 12, LLVMGhostLinkage => 12,
LLVMCommonLinkage => 13, LLVMCommonLinkage => 13,
LLVMLinkerPrivateLinkage => 14, LLVMLinkerPrivateLinkage => 14,
LLVMLinkerPrivateWeakLinkage => 15); LLVMLinkerPrivateWeakLinkage => 15,
LinkerPrivateWeakDefAutoLinkage => 16);
pragma Convention (C, LLVMLinkage); pragma Convention (C, LLVMLinkage);

View File

@ -35,7 +35,6 @@ module TypeKind = struct
| Opaque | Opaque
| Vector | Vector
| Metadata | Metadata
| Union
end end
module Linkage = struct module Linkage = struct
@ -210,11 +209,6 @@ external struct_element_types : lltype -> lltype array
= "llvm_struct_element_types" = "llvm_struct_element_types"
external is_packed : lltype -> bool = "llvm_is_packed" 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 .....................--*) (*--... Operations on pointer, vector, and array types .....................--*)
external array_type : lltype -> int -> lltype = "llvm_array_type" external array_type : lltype -> int -> lltype = "llvm_array_type"
external pointer_type : lltype -> lltype = "llvm_pointer_type" external pointer_type : lltype -> lltype = "llvm_pointer_type"
@ -280,6 +274,8 @@ let fold_right_uses f v init =
(*--... Operations on users ................................................--*) (*--... Operations on users ................................................--*)
external operand : llvalue -> int -> llvalue = "llvm_operand" external operand : llvalue -> int -> llvalue = "llvm_operand"
external set_operand : llvalue -> int -> llvalue -> unit = "llvm_set_operand"
external num_operands : llvalue -> int = "llvm_num_operands"
(*--... Operations on constants of (mostly) any type .......................--*) (*--... Operations on constants of (mostly) any type .......................--*)
external is_constant : llvalue -> bool = "llvm_is_constant" external is_constant : llvalue -> bool = "llvm_is_constant"
@ -319,7 +315,6 @@ external const_struct : llcontext -> llvalue array -> llvalue
external const_packed_struct : llcontext -> llvalue array -> llvalue external const_packed_struct : llcontext -> llvalue array -> llvalue
= "llvm_const_packed_struct" = "llvm_const_packed_struct"
external const_vector : llvalue array -> llvalue = "llvm_const_vector" external const_vector : llvalue array -> llvalue = "llvm_const_vector"
external const_union : lltype -> llvalue -> llvalue = "LLVMConstUnion"
(*--... Constant expressions ...............................................--*) (*--... Constant expressions ...............................................--*)
external align_of : lltype -> llvalue = "LLVMAlignOf" external align_of : lltype -> llvalue = "LLVMAlignOf"
@ -1050,9 +1045,6 @@ let rec string_of_lltype ty =
if is_packed ty if is_packed ty
then "<" ^ s ^ ">" then "<" ^ s ^ ">"
else s else s
| TypeKind.Union -> "union { " ^ (concat2 ", " (
Array.map string_of_lltype (union_element_types ty)
)) ^ " }"
| TypeKind.Array -> "[" ^ (string_of_int (array_length ty)) ^ | TypeKind.Array -> "[" ^ (string_of_int (array_length ty)) ^
" x " ^ (string_of_lltype (element_type ty)) ^ "]" " x " ^ (string_of_lltype (element_type ty)) ^ "]"
| TypeKind.Vector -> "<" ^ (string_of_int (vector_size ty)) ^ | TypeKind.Vector -> "<" ^ (string_of_int (vector_size ty)) ^

View File

@ -72,7 +72,6 @@ module TypeKind : sig
| Opaque | Opaque
| Vector | Vector
| Metadata | Metadata
| Union
end end
(** The linkage of a global value, accessed with {!linkage} and (** The linkage of a global value, accessed with {!linkage} and
@ -408,19 +407,6 @@ external struct_element_types : lltype -> lltype array
external is_packed : lltype -> bool = "llvm_is_packed" 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} *) (** {7 Operations on pointer, vector, and array types} *)
(** [array_type ty n] returns the array type containing [n] elements of type (** [array_type ty n] returns the array type containing [n] elements of type
@ -557,6 +543,14 @@ val fold_right_uses : (lluse -> 'a -> 'a) -> llvalue -> 'a -> 'a
method [llvm::User::getOperand]. *) method [llvm::User::getOperand]. *)
external operand : llvalue -> int -> llvalue = "llvm_operand" external operand : llvalue -> int -> llvalue = "llvm_operand"
(** [set_operand v i o] sets the operand of the value [v] at the index [i] to
the value [o].
See the method [llvm::User::setOperand]. *)
external set_operand : llvalue -> int -> llvalue -> unit = "llvm_set_operand"
(** [num_operands v] returns the number of operands for the value [v].
See the method [llvm::User::getNumOperands]. *)
external num_operands : llvalue -> int = "llvm_num_operands"
(** {7 Operations on constants of (mostly) any type} *) (** {7 Operations on constants of (mostly) any type} *)
@ -689,10 +683,6 @@ external const_packed_struct : llcontext -> llvalue array -> llvalue
values [elts]. See the method [llvm::ConstantVector::get]. *) values [elts]. See the method [llvm::ConstantVector::get]. *)
external const_vector : llvalue array -> llvalue = "llvm_const_vector" 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} *) (** {7 Constant expressions} *)
@ -991,7 +981,7 @@ external const_insertelement : llvalue -> llvalue -> llvalue -> llvalue
= "LLVMConstInsertElement" = "LLVMConstInsertElement"
(** [const_shufflevector a b mask] returns a constant [shufflevector]. (** [const_shufflevector a b mask] returns a constant [shufflevector].
See the LLVM Language Reference for details on the [sufflevector] See the LLVM Language Reference for details on the [shufflevector]
instruction. instruction.
See the method [llvm::ConstantExpr::getShuffleVector]. *) See the method [llvm::ConstantExpr::getShuffleVector]. *)
external const_shufflevector : llvalue -> llvalue -> llvalue -> llvalue external const_shufflevector : llvalue -> llvalue -> llvalue -> llvalue

View File

@ -318,21 +318,6 @@ CAMLprim value llvm_is_packed(LLVMTypeRef StructTy) {
return Val_bool(LLVMIsPackedStruct(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 .....................--*/ /*--... Operations on array, pointer, and vector types .....................--*/
/* lltype -> int -> lltype */ /* lltype -> int -> lltype */
@ -452,6 +437,17 @@ CAMLprim LLVMValueRef llvm_operand(LLVMValueRef V, value I) {
return LLVMGetOperand(V, Int_val(I)); return LLVMGetOperand(V, Int_val(I));
} }
/* llvalue -> int -> llvalue -> unit */
CAMLprim value llvm_set_operand(LLVMValueRef U, value I, LLVMValueRef V) {
LLVMSetOperand(U, Int_val(I), V);
return Val_unit;
}
/* llvalue -> int */
CAMLprim value llvm_num_operands(LLVMValueRef V) {
return Val_int(LLVMGetNumOperands(V));
}
/*--... Operations on constants of (mostly) any type .......................--*/ /*--... Operations on constants of (mostly) any type .......................--*/
/* llvalue -> bool */ /* llvalue -> bool */
@ -964,8 +960,8 @@ CAMLprim LLVMValueRef llvm_param(LLVMValueRef Fn, value Index) {
return LLVMGetParam(Fn, Int_val(Index)); return LLVMGetParam(Fn, Int_val(Index));
} }
/* llvalue -> int -> llvalue */ /* llvalue -> llvalue */
CAMLprim value llvm_params(LLVMValueRef Fn, value Index) { CAMLprim value llvm_params(LLVMValueRef Fn) {
value Params = alloc(LLVMCountParams(Fn), 0); value Params = alloc(LLVMCountParams(Fn), 0);
LLVMGetParams(Fn, (LLVMValueRef *) Op_val(Params)); LLVMGetParams(Fn, (LLVMValueRef *) Op_val(Params));
return Params; return Params;

155
contrib/llvm/configure vendored
View File

@ -1,6 +1,6 @@
#! /bin/sh #! /bin/sh
# Guess values for system-dependent variables and create Makefiles. # Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.60 for llvm 2.8svn. # Generated by GNU Autoconf 2.60 for llvm 2.8rc.
# #
# Report bugs to <llvmbugs@cs.uiuc.edu>. # Report bugs to <llvmbugs@cs.uiuc.edu>.
# #
@ -561,8 +561,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
# Identity of this package. # Identity of this package.
PACKAGE_NAME='llvm' PACKAGE_NAME='llvm'
PACKAGE_TARNAME='-llvm-' PACKAGE_TARNAME='-llvm-'
PACKAGE_VERSION='2.8svn' PACKAGE_VERSION='2.8rc'
PACKAGE_STRING='llvm 2.8svn' PACKAGE_STRING='llvm 2.8rc'
PACKAGE_BUGREPORT='llvmbugs@cs.uiuc.edu' PACKAGE_BUGREPORT='llvmbugs@cs.uiuc.edu'
ac_unique_file="lib/VMCore/Module.cpp" ac_unique_file="lib/VMCore/Module.cpp"
@ -703,8 +703,6 @@ ENABLE_BUILT_CLANG
OPTIMIZE_OPTION OPTIMIZE_OPTION
EXTRA_OPTIONS EXTRA_OPTIONS
BINUTILS_INCDIR BINUTILS_INCDIR
ENABLE_LLVMC_DYNAMIC
ENABLE_LLVMC_DYNAMIC_PLUGINS
CXX CXX
CXXFLAGS CXXFLAGS
ac_ct_CXX ac_ct_CXX
@ -1320,7 +1318,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing. # Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh. # This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF cat <<_ACEOF
\`configure' configures llvm 2.8svn to adapt to many kinds of systems. \`configure' configures llvm 2.8rc to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]... Usage: $0 [OPTION]... [VAR=VALUE]...
@ -1386,7 +1384,7 @@ fi
if test -n "$ac_init_help"; then if test -n "$ac_init_help"; then
case $ac_init_help in case $ac_init_help in
short | recursive ) echo "Configuration of llvm 2.8svn:";; short | recursive ) echo "Configuration of llvm 2.8rc:";;
esac esac
cat <<\_ACEOF cat <<\_ACEOF
@ -1416,17 +1414,13 @@ Optional Features:
--enable-targets Build specific host targets: all or --enable-targets Build specific host targets: all or
target1,target2,... Valid targets are: host, x86, target1,target2,... Valid targets are: host, x86,
x86_64, sparc, powerpc, alpha, arm, mips, spu, x86_64, sparc, powerpc, alpha, arm, mips, spu,
pic16, xcore, msp430, systemz, blackfin, cbe, msil, pic16, xcore, msp430, systemz, blackfin, cbe, and
and cpp (default=all) cpp (default=all)
--enable-cbe-printf-a Enable C Backend output with hex floating point via --enable-cbe-printf-a Enable C Backend output with hex floating point via
%a (default is YES) %a (default is YES)
--enable-bindings Build specific language bindings: --enable-bindings Build specific language bindings:
all,auto,none,{binding-name} (default=auto) all,auto,none,{binding-name} (default=auto)
--enable-libffi Check for the presence of libffi (default is NO) --enable-libffi Check for the presence of libffi (default is NO)
--enable-llvmc-dynamic Link LLVMC dynamically (default is NO, unless on
Win32)
--enable-llvmc-dynamic-plugins
Enable dynamic LLVMC plugins (default is YES)
--enable-ltdl-install install libltdl --enable-ltdl-install install libltdl
Optional Packages: Optional Packages:
@ -1539,7 +1533,7 @@ fi
test -n "$ac_init_help" && exit $ac_status test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then if $ac_init_version; then
cat <<\_ACEOF cat <<\_ACEOF
llvm configure 2.8svn llvm configure 2.8rc
generated by GNU Autoconf 2.60 generated by GNU Autoconf 2.60
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
@ -1555,7 +1549,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake. running configure, to aid debugging if configure makes a mistake.
It was created by llvm $as_me 2.8svn, which was It was created by llvm $as_me 2.8rc, which was
generated by GNU Autoconf 2.60. Invocation command line was generated by GNU Autoconf 2.60. Invocation command line was
$ $0 $@ $ $0 $@
@ -1988,7 +1982,6 @@ for i in `ls ${srcdir}/projects`
do do
if test -d ${srcdir}/projects/${i} ; then if test -d ${srcdir}/projects/${i} ; then
case ${i} in case ${i} in
CVS) ;;
sample) subdirs="$subdirs projects/sample" sample) subdirs="$subdirs projects/sample"
;; ;;
privbracket) subdirs="$subdirs projects/privbracket" privbracket) subdirs="$subdirs projects/privbracket"
@ -4691,7 +4684,7 @@ else
fi fi
if test -d "CVS" -o -d "${srcdir}/CVS" -o -d ".svn" -o -d "${srcdir}/.svn" -o -d ".git" -o -d "${srcdir}/.git"; then if test -d ".svn" -o -d "${srcdir}/.svn" -o -d ".git" -o -d "${srcdir}/.git"; then
cvsbuild="yes" cvsbuild="yes"
optimize="no" optimize="no"
CVSBUILD=CVSBUILD=1 CVSBUILD=CVSBUILD=1
@ -4706,7 +4699,7 @@ fi
if test "${enable_optimized+set}" = set; then if test "${enable_optimized+set}" = set; then
enableval=$enable_optimized; enableval=$enable_optimized;
else else
enableval=$optimize enableval="yes"
fi fi
if test ${enableval} = "no" ; then if test ${enableval} = "no" ; then
@ -4736,7 +4729,7 @@ fi
if test "${enable_assertions+set}" = set; then if test "${enable_assertions+set}" = set; then
enableval=$enable_assertions; enableval=$enable_assertions;
else else
enableval="yes" enableval="no"
fi fi
if test ${enableval} = "yes" ; then if test ${enableval} = "yes" ; then
@ -4962,7 +4955,7 @@ if test "$enableval" = host-only ; then
enableval=host enableval=host
fi fi
case "$enableval" in case "$enableval" in
all) TARGETS_TO_BUILD="X86 Sparc PowerPC Alpha ARM Mips CellSPU PIC16 XCore MSP430 SystemZ Blackfin CBackend MSIL CppBackend MBlaze" ;; all) TARGETS_TO_BUILD="X86 Sparc PowerPC Alpha ARM Mips CellSPU PIC16 XCore MSP430 SystemZ Blackfin CBackend CppBackend MBlaze" ;;
*)for a_target in `echo $enableval|sed -e 's/,/ /g' ` ; do *)for a_target in `echo $enableval|sed -e 's/,/ /g' ` ; do
case "$a_target" in case "$a_target" in
x86) TARGETS_TO_BUILD="X86 $TARGETS_TO_BUILD" ;; x86) TARGETS_TO_BUILD="X86 $TARGETS_TO_BUILD" ;;
@ -4979,7 +4972,6 @@ case "$enableval" in
systemz) TARGETS_TO_BUILD="SystemZ $TARGETS_TO_BUILD" ;; systemz) TARGETS_TO_BUILD="SystemZ $TARGETS_TO_BUILD" ;;
blackfin) TARGETS_TO_BUILD="Blackfin $TARGETS_TO_BUILD" ;; blackfin) TARGETS_TO_BUILD="Blackfin $TARGETS_TO_BUILD" ;;
cbe) TARGETS_TO_BUILD="CBackend $TARGETS_TO_BUILD" ;; cbe) TARGETS_TO_BUILD="CBackend $TARGETS_TO_BUILD" ;;
msil) TARGETS_TO_BUILD="MSIL $TARGETS_TO_BUILD" ;;
cpp) TARGETS_TO_BUILD="CppBackend $TARGETS_TO_BUILD" ;; cpp) TARGETS_TO_BUILD="CppBackend $TARGETS_TO_BUILD" ;;
mblaze) TARGETS_TO_BUILD="MBlaze $TARGETS_TO_BUILD" ;; mblaze) TARGETS_TO_BUILD="MBlaze $TARGETS_TO_BUILD" ;;
host) case "$llvm_cv_target_arch" in host) case "$llvm_cv_target_arch" in
@ -5015,10 +5007,27 @@ TARGETS_TO_BUILD=$TARGETS_TO_BUILD
# If so, define LLVM_NATIVE_ARCH to that LLVM target. # If so, define LLVM_NATIVE_ARCH to that LLVM target.
for a_target in $TARGETS_TO_BUILD; do for a_target in $TARGETS_TO_BUILD; do
if test "$a_target" = "$LLVM_NATIVE_ARCH"; then if test "$a_target" = "$LLVM_NATIVE_ARCH"; then
LLVM_NATIVE_ARCHTARGET="${LLVM_NATIVE_ARCH}Target"
cat >>confdefs.h <<_ACEOF cat >>confdefs.h <<_ACEOF
#define LLVM_NATIVE_ARCH $LLVM_NATIVE_ARCHTARGET #define LLVM_NATIVE_ARCH $LLVM_NATIVE_ARCH
_ACEOF
LLVM_NATIVE_TARGET="LLVMInitialize${LLVM_NATIVE_ARCH}Target"
LLVM_NATIVE_TARGETINFO="LLVMInitialize${LLVM_NATIVE_ARCH}TargetInfo"
LLVM_NATIVE_ASMPRINTER="LLVMInitialize${LLVM_NATIVE_ARCH}AsmPrinter"
cat >>confdefs.h <<_ACEOF
#define LLVM_NATIVE_TARGET $LLVM_NATIVE_TARGET
_ACEOF
cat >>confdefs.h <<_ACEOF
#define LLVM_NATIVE_TARGETINFO $LLVM_NATIVE_TARGETINFO
_ACEOF
cat >>confdefs.h <<_ACEOF
#define LLVM_NATIVE_ASMPRINTER $LLVM_NATIVE_ASMPRINTER
_ACEOF _ACEOF
fi fi
@ -5374,42 +5383,6 @@ else
fi fi
if test "$llvm_cv_os_type" = "Win32" ; then
llvmc_dynamic="yes"
else
llvmc_dynamic="no"
fi
# Check whether --enable-llvmc-dynamic was given.
if test "${enable_llvmc_dynamic+set}" = set; then
enableval=$enable_llvmc_dynamic;
else
enableval=$llvmc_dynamic
fi
if test ${enableval} = "yes" && test "$ENABLE_PIC" -eq 1 ; then
ENABLE_LLVMC_DYNAMIC=ENABLE_LLVMC_DYNAMIC=1
else
ENABLE_LLVMC_DYNAMIC=
fi
# Check whether --enable-llvmc-dynamic-plugins was given.
if test "${enable_llvmc_dynamic_plugins+set}" = set; then
enableval=$enable_llvmc_dynamic_plugins;
else
enableval=yes
fi
if test ${enableval} = "yes" ; then
ENABLE_LLVMC_DYNAMIC_PLUGINS=ENABLE_LLVMC_DYNAMIC_PLUGINS=1
else
ENABLE_LLVMC_DYNAMIC_PLUGINS=
fi
ac_ext=c ac_ext=c
ac_cpp='$CPP $CPPFLAGS' ac_cpp='$CPP $CPPFLAGS'
@ -8004,6 +7977,10 @@ test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
case "$INSTALL" in
[\\/$]* | ?:[\\/]* ) ;;
*) INSTALL="\\\$(TOPSRCDIR)/$INSTALL" ;;
esac
# Extract the first word of "bzip2", so it can be a program name with args. # Extract the first word of "bzip2", so it can be a program name with args.
set dummy bzip2; ac_word=$2 set dummy bzip2; ac_word=$2
@ -8721,6 +8698,31 @@ fi
done done
{ echo "$as_me:$LINENO: checking for linker version" >&5
echo $ECHO_N "checking for linker version... $ECHO_C" >&6; }
if test "${llvm_cv_link_version+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
version_string="$(ld -v 2>&1 | head -1)"
# Check for ld64.
if (echo "$version_string" | grep -q "ld64"); then
llvm_cv_link_version=$(echo "$version_string" | sed -e "s#.*ld64-\([^ ]*\)#\1#")
else
llvm_cv_link_version=$(echo "$version_string" | sed -e "s#[^0-9]*\([0-9.]*\).*#\1#")
fi
fi
{ echo "$as_me:$LINENO: result: $llvm_cv_link_version" >&5
echo "${ECHO_T}$llvm_cv_link_version" >&6; }
cat >>confdefs.h <<_ACEOF
#define HOST_LINK_VERSION "$llvm_cv_link_version"
_ACEOF
{ echo "$as_me:$LINENO: checking for compiler -Wl,-R<path> option" >&5 { echo "$as_me:$LINENO: checking for compiler -Wl,-R<path> option" >&5
echo $ECHO_N "checking for compiler -Wl,-R<path> option... $ECHO_C" >&6; } echo $ECHO_N "checking for compiler -Wl,-R<path> option... $ECHO_C" >&6; }
if test "${llvm_cv_link_use_r+set}" = set; then if test "${llvm_cv_link_use_r+set}" = set; then
@ -11387,7 +11389,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 11390 "configure" #line 11392 "configure"
#include "confdefs.h" #include "confdefs.h"
#if HAVE_DLFCN_H #if HAVE_DLFCN_H
@ -19991,6 +19993,12 @@ fi
{ echo "$as_me:$LINENO: checking for GCC atomic builtins" >&5 { echo "$as_me:$LINENO: checking for GCC atomic builtins" >&5
echo $ECHO_N "checking for GCC atomic builtins... $ECHO_C" >&6; } echo $ECHO_N "checking for GCC atomic builtins... $ECHO_C" >&6; }
ac_ext=cpp
ac_cpp='$CXXCPP $CPPFLAGS'
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
cat >conftest.$ac_ext <<_ACEOF cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */ /* confdefs.h. */
_ACEOF _ACEOF
@ -20041,6 +20049,12 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
ac_status=$? ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then (exit $ac_status); }; }; then
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu
{ echo "$as_me:$LINENO: result: yes" >&5 { echo "$as_me:$LINENO: result: yes" >&5
echo "${ECHO_T}yes" >&6; } echo "${ECHO_T}yes" >&6; }
@ -20067,7 +20081,6 @@ rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext conftest$ac_exeext conftest.$ac_ext
if test "$llvm_cv_os_type" = "Linux" -a "$llvm_cv_target_arch" = "x86_64" ; then if test "$llvm_cv_os_type" = "Linux" -a "$llvm_cv_target_arch" = "x86_64" ; then
{ echo "$as_me:$LINENO: checking for 32-bit userspace on 64-bit system" >&5 { echo "$as_me:$LINENO: checking for 32-bit userspace on 64-bit system" >&5
echo $ECHO_N "checking for 32-bit userspace on 64-bit system... $ECHO_C" >&6; } echo $ECHO_N "checking for 32-bit userspace on 64-bit system... $ECHO_C" >&6; }
@ -20563,7 +20576,12 @@ fi
ac_config_headers="$ac_config_headers include/llvm/Config/config.h" ac_config_headers="$ac_config_headers include/llvm/Config/config.h include/llvm/Config/llvm-config.h"
ac_config_files="$ac_config_files include/llvm/Config/Targets.def" ac_config_files="$ac_config_files include/llvm/Config/Targets.def"
@ -20582,7 +20600,7 @@ ac_config_files="$ac_config_files Makefile.config"
ac_config_files="$ac_config_files llvm.spec" ac_config_files="$ac_config_files llvm.spec"
ac_config_files="$ac_config_files tools/llvmc/plugins/Base/Base.td" ac_config_files="$ac_config_files tools/llvmc/src/Base.td"
ac_config_files="$ac_config_files tools/llvm-config/llvm-config.in" ac_config_files="$ac_config_files tools/llvm-config/llvm-config.in"
@ -21027,7 +21045,7 @@ exec 6>&1
# report actual input values of CONFIG_FILES etc. instead of their # report actual input values of CONFIG_FILES etc. instead of their
# values after options handling. # values after options handling.
ac_log=" ac_log="
This file was extended by llvm $as_me 2.8svn, which was This file was extended by llvm $as_me 2.8rc, which was
generated by GNU Autoconf 2.60. Invocation command line was generated by GNU Autoconf 2.60. Invocation command line was
CONFIG_FILES = $CONFIG_FILES CONFIG_FILES = $CONFIG_FILES
@ -21080,7 +21098,7 @@ Report bugs to <bug-autoconf@gnu.org>."
_ACEOF _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF cat >>$CONFIG_STATUS <<_ACEOF
ac_cs_version="\\ ac_cs_version="\\
llvm config.status 2.8svn llvm config.status 2.8rc
configured by $0, generated by GNU Autoconf 2.60, configured by $0, generated by GNU Autoconf 2.60,
with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
@ -21194,6 +21212,7 @@ for ac_config_target in $ac_config_targets
do do
case $ac_config_target in case $ac_config_target in
"include/llvm/Config/config.h") CONFIG_HEADERS="$CONFIG_HEADERS include/llvm/Config/config.h" ;; "include/llvm/Config/config.h") CONFIG_HEADERS="$CONFIG_HEADERS include/llvm/Config/config.h" ;;
"include/llvm/Config/llvm-config.h") CONFIG_HEADERS="$CONFIG_HEADERS include/llvm/Config/llvm-config.h" ;;
"include/llvm/Config/Targets.def") CONFIG_FILES="$CONFIG_FILES include/llvm/Config/Targets.def" ;; "include/llvm/Config/Targets.def") CONFIG_FILES="$CONFIG_FILES include/llvm/Config/Targets.def" ;;
"include/llvm/Config/AsmPrinters.def") CONFIG_FILES="$CONFIG_FILES include/llvm/Config/AsmPrinters.def" ;; "include/llvm/Config/AsmPrinters.def") CONFIG_FILES="$CONFIG_FILES include/llvm/Config/AsmPrinters.def" ;;
"include/llvm/Config/AsmParsers.def") CONFIG_FILES="$CONFIG_FILES include/llvm/Config/AsmParsers.def" ;; "include/llvm/Config/AsmParsers.def") CONFIG_FILES="$CONFIG_FILES include/llvm/Config/AsmParsers.def" ;;
@ -21201,7 +21220,7 @@ do
"include/llvm/System/DataTypes.h") CONFIG_HEADERS="$CONFIG_HEADERS include/llvm/System/DataTypes.h" ;; "include/llvm/System/DataTypes.h") CONFIG_HEADERS="$CONFIG_HEADERS include/llvm/System/DataTypes.h" ;;
"Makefile.config") CONFIG_FILES="$CONFIG_FILES Makefile.config" ;; "Makefile.config") CONFIG_FILES="$CONFIG_FILES Makefile.config" ;;
"llvm.spec") CONFIG_FILES="$CONFIG_FILES llvm.spec" ;; "llvm.spec") CONFIG_FILES="$CONFIG_FILES llvm.spec" ;;
"tools/llvmc/plugins/Base/Base.td") CONFIG_FILES="$CONFIG_FILES tools/llvmc/plugins/Base/Base.td" ;; "tools/llvmc/src/Base.td") CONFIG_FILES="$CONFIG_FILES tools/llvmc/src/Base.td" ;;
"tools/llvm-config/llvm-config.in") CONFIG_FILES="$CONFIG_FILES tools/llvm-config/llvm-config.in" ;; "tools/llvm-config/llvm-config.in") CONFIG_FILES="$CONFIG_FILES tools/llvm-config/llvm-config.in" ;;
"setup") CONFIG_COMMANDS="$CONFIG_COMMANDS setup" ;; "setup") CONFIG_COMMANDS="$CONFIG_COMMANDS setup" ;;
"Makefile") CONFIG_COMMANDS="$CONFIG_COMMANDS Makefile" ;; "Makefile") CONFIG_COMMANDS="$CONFIG_COMMANDS Makefile" ;;
@ -21421,8 +21440,6 @@ ENABLE_BUILT_CLANG!$ENABLE_BUILT_CLANG$ac_delim
OPTIMIZE_OPTION!$OPTIMIZE_OPTION$ac_delim OPTIMIZE_OPTION!$OPTIMIZE_OPTION$ac_delim
EXTRA_OPTIONS!$EXTRA_OPTIONS$ac_delim EXTRA_OPTIONS!$EXTRA_OPTIONS$ac_delim
BINUTILS_INCDIR!$BINUTILS_INCDIR$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 CXX!$CXX$ac_delim
CXXFLAGS!$CXXFLAGS$ac_delim CXXFLAGS!$CXXFLAGS$ac_delim
ac_ct_CXX!$ac_ct_CXX$ac_delim ac_ct_CXX!$ac_ct_CXX$ac_delim
@ -21514,7 +21531,7 @@ LIBOBJS!$LIBOBJS$ac_delim
LTLIBOBJS!$LTLIBOBJS$ac_delim LTLIBOBJS!$LTLIBOBJS$ac_delim
_ACEOF _ACEOF
if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 95; then if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 93; then
break break
elif $ac_last_try; then elif $ac_last_try; then
{ { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5

View File

@ -204,8 +204,7 @@ typedef enum {
LLVMPointerTypeKind, /**< Pointers */ LLVMPointerTypeKind, /**< Pointers */
LLVMOpaqueTypeKind, /**< Opaque: type with unknown structure */ LLVMOpaqueTypeKind, /**< Opaque: type with unknown structure */
LLVMVectorTypeKind, /**< SIMD 'packed' format, or other vector type */ LLVMVectorTypeKind, /**< SIMD 'packed' format, or other vector type */
LLVMMetadataTypeKind, /**< Metadata */ LLVMMetadataTypeKind /**< Metadata */
LLVMUnionTypeKind /**< Unions */
} LLVMTypeKind; } LLVMTypeKind;
typedef enum { typedef enum {
@ -227,7 +226,9 @@ typedef enum {
LLVMGhostLinkage, /**< Obsolete */ LLVMGhostLinkage, /**< Obsolete */
LLVMCommonLinkage, /**< Tentative definitions */ LLVMCommonLinkage, /**< Tentative definitions */
LLVMLinkerPrivateLinkage, /**< Like Private, but linker removes. */ LLVMLinkerPrivateLinkage, /**< Like Private, but linker removes. */
LLVMLinkerPrivateWeakLinkage /**< Like LinkerPrivate, but is weak. */ LLVMLinkerPrivateWeakLinkage, /**< Like LinkerPrivate, but is weak. */
LLVMLinkerPrivateWeakDefAutoLinkage /**< Like LinkerPrivateWeak, but possibly
hidden. */
} LLVMLinkage; } LLVMLinkage;
typedef enum { typedef enum {
@ -393,13 +394,6 @@ unsigned LLVMCountStructElementTypes(LLVMTypeRef StructTy);
void LLVMGetStructElementTypes(LLVMTypeRef StructTy, LLVMTypeRef *Dest); void LLVMGetStructElementTypes(LLVMTypeRef StructTy, LLVMTypeRef *Dest);
LLVMBool LLVMIsPackedStruct(LLVMTypeRef StructTy); LLVMBool LLVMIsPackedStruct(LLVMTypeRef StructTy);
/* Operations on union types */
LLVMTypeRef LLVMUnionTypeInContext(LLVMContextRef C, LLVMTypeRef *ElementTypes,
unsigned ElementCount);
LLVMTypeRef LLVMUnionType(LLVMTypeRef *ElementTypes, unsigned ElementCount);
unsigned LLVMCountUnionElementTypes(LLVMTypeRef UnionTy);
void LLVMGetUnionElementTypes(LLVMTypeRef UnionTy, LLVMTypeRef *Dest);
/* Operations on array, pointer, and vector types (sequence types) */ /* Operations on array, pointer, and vector types (sequence types) */
LLVMTypeRef LLVMArrayType(LLVMTypeRef ElementType, unsigned ElementCount); LLVMTypeRef LLVMArrayType(LLVMTypeRef ElementType, unsigned ElementCount);
LLVMTypeRef LLVMPointerType(LLVMTypeRef ElementType, unsigned AddressSpace); LLVMTypeRef LLVMPointerType(LLVMTypeRef ElementType, unsigned AddressSpace);
@ -523,6 +517,8 @@ LLVMValueRef LLVMGetUsedValue(LLVMUseRef U);
/* Operations on Users */ /* Operations on Users */
LLVMValueRef LLVMGetOperand(LLVMValueRef Val, unsigned Index); LLVMValueRef LLVMGetOperand(LLVMValueRef Val, unsigned Index);
void LLVMSetOperand(LLVMValueRef User, unsigned Index, LLVMValueRef Val);
int LLVMGetNumOperands(LLVMValueRef Val);
/* Operations on constants of any type */ /* Operations on constants of any type */
LLVMValueRef LLVMConstNull(LLVMTypeRef Ty); /* all zeroes */ LLVMValueRef LLVMConstNull(LLVMTypeRef Ty); /* all zeroes */
@ -570,7 +566,6 @@ LLVMValueRef LLVMConstArray(LLVMTypeRef ElementTy,
LLVMValueRef LLVMConstStruct(LLVMValueRef *ConstantVals, unsigned Count, LLVMValueRef LLVMConstStruct(LLVMValueRef *ConstantVals, unsigned Count,
LLVMBool Packed); LLVMBool Packed);
LLVMValueRef LLVMConstVector(LLVMValueRef *ScalarConstantVals, unsigned Size); LLVMValueRef LLVMConstVector(LLVMValueRef *ScalarConstantVals, unsigned Size);
LLVMValueRef LLVMConstUnion(LLVMTypeRef Ty, LLVMValueRef Val);
/* Constant expressions */ /* Constant expressions */
LLVMOpcode LLVMGetConstOpcode(LLVMValueRef ConstantVal); LLVMOpcode LLVMGetConstOpcode(LLVMValueRef ConstantVal);
@ -750,6 +745,9 @@ LLVMBasicBlockRef LLVMInsertBasicBlock(LLVMBasicBlockRef InsertBeforeBB,
const char *Name); const char *Name);
void LLVMDeleteBasicBlock(LLVMBasicBlockRef BB); void LLVMDeleteBasicBlock(LLVMBasicBlockRef BB);
void LLVMMoveBasicBlockBefore(LLVMBasicBlockRef BB, LLVMBasicBlockRef MovePos);
void LLVMMoveBasicBlockAfter(LLVMBasicBlockRef BB, LLVMBasicBlockRef MovePos);
/* Operations on instructions */ /* Operations on instructions */
LLVMBasicBlockRef LLVMGetInstructionParent(LLVMValueRef Inst); LLVMBasicBlockRef LLVMGetInstructionParent(LLVMValueRef Inst);
LLVMValueRef LLVMGetFirstInstruction(LLVMBasicBlockRef BB); LLVMValueRef LLVMGetFirstInstruction(LLVMBasicBlockRef BB);

View File

@ -51,41 +51,38 @@ typedef int (*EDRegisterReaderCallback)(uint64_t *value, unsigned regID,
@typedef EDAssemblySyntax_t @typedef EDAssemblySyntax_t
An assembly syntax for use in tokenizing instructions. An assembly syntax for use in tokenizing instructions.
*/ */
typedef enum { enum {
/*! @constant kEDAssemblySyntaxX86Intel Intel syntax for i386 and x86_64. */ /*! @constant kEDAssemblySyntaxX86Intel Intel syntax for i386 and x86_64. */
kEDAssemblySyntaxX86Intel = 0, kEDAssemblySyntaxX86Intel = 0,
/*! @constant kEDAssemblySyntaxX86ATT AT&T syntax for i386 and x86_64. */ /*! @constant kEDAssemblySyntaxX86ATT AT&T syntax for i386 and x86_64. */
kEDAssemblySyntaxX86ATT = 1, kEDAssemblySyntaxX86ATT = 1,
kEDAssemblySyntaxARMUAL = 2 kEDAssemblySyntaxARMUAL = 2
} EDAssemblySyntax_t; };
typedef unsigned EDAssemblySyntax_t;
/*! /*!
@typedef EDDisassemblerRef @typedef EDDisassemblerRef
Encapsulates a disassembler for a single CPU architecture. Encapsulates a disassembler for a single CPU architecture.
*/ */
struct EDDisassembler; typedef void *EDDisassemblerRef;
typedef struct EDDisassembler *EDDisassemblerRef;
/*! /*!
@typedef EDInstRef @typedef EDInstRef
Encapsulates a single disassembled instruction in one assembly syntax. Encapsulates a single disassembled instruction in one assembly syntax.
*/ */
struct EDInst; typedef void *EDInstRef;
typedef struct EDInst *EDInstRef;
/*! /*!
@typedef EDTokenRef @typedef EDTokenRef
Encapsulates a token from the disassembly of an instruction. Encapsulates a token from the disassembly of an instruction.
*/ */
struct EDToken; typedef void *EDTokenRef;
typedef struct EDToken *EDTokenRef;
/*! /*!
@typedef EDOperandRef @typedef EDOperandRef
Encapsulates an operand of an instruction. Encapsulates an operand of an instruction.
*/ */
struct EDOperand; typedef void *EDOperandRef;
typedef struct EDOperand *EDOperandRef;
/*! /*!
@functiongroup Getting a disassembler @functiongroup Getting a disassembler

View File

@ -116,6 +116,8 @@ LLVMBool LLVMRemoveModuleProvider(LLVMExecutionEngineRef EE,
LLVMBool LLVMFindFunction(LLVMExecutionEngineRef EE, const char *Name, LLVMBool LLVMFindFunction(LLVMExecutionEngineRef EE, const char *Name,
LLVMValueRef *OutFn); LLVMValueRef *OutFn);
void *LLVMRecompileAndRelinkFunction(LLVMExecutionEngineRef EE, LLVMValueRef Fn);
LLVMTargetDataRef LLVMGetExecutionEngineTargetData(LLVMExecutionEngineRef EE); LLVMTargetDataRef LLVMGetExecutionEngineTargetData(LLVMExecutionEngineRef EE);
void LLVMAddGlobalMapping(LLVMExecutionEngineRef EE, LLVMValueRef Global, void LLVMAddGlobalMapping(LLVMExecutionEngineRef EE, LLVMValueRef Global,

View File

@ -1,26 +1,26 @@
/*===-- llvm-c/Target.h - Target Lib C Iface --------------------*- C++ -*-===*\ /*===-- llvm-c/Target.h - Target Lib C Iface --------------------*- C++ -*-===*/
|* *| /* */
|* The LLVM Compiler Infrastructure *| /* The LLVM Compiler Infrastructure */
|* *| /* */
|* This file is distributed under the University of Illinois Open Source *| /* This file is distributed under the University of Illinois Open Source */
|* License. See LICENSE.TXT for details. *| /* License. See LICENSE.TXT for details. */
|* *| /* */
|*===----------------------------------------------------------------------===*| /*===----------------------------------------------------------------------===*/
|* *| /* */
|* This header declares the C interface to libLLVMTarget.a, which *| /* This header declares the C interface to libLLVMTarget.a, which */
|* implements target information. *| /* implements target information. */
|* *| /* */
|* Many exotic languages can interoperate with C code but have a harder time *| /* Many exotic languages can interoperate with C code but have a harder time */
|* with C++ due to name mangling. So in addition to C, this interface enables *| /* with C++ due to name mangling. So in addition to C, this interface enables */
|* tools written in such languages. *| /* tools written in such languages. */
|* *| /* */
\*===----------------------------------------------------------------------===*/ /*===----------------------------------------------------------------------===*/
#ifndef LLVM_C_TARGET_H #ifndef LLVM_C_TARGET_H
#define LLVM_C_TARGET_H #define LLVM_C_TARGET_H
#include "llvm-c/Core.h" #include "llvm-c/Core.h"
#include "llvm/Config/config.h" #include "llvm/Config/llvm-config.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -64,15 +64,10 @@ static inline void LLVMInitializeAllTargets(void) {
for JIT applications to ensure that the target gets linked in correctly. */ for JIT applications to ensure that the target gets linked in correctly. */
static inline LLVMBool LLVMInitializeNativeTarget(void) { static inline LLVMBool LLVMInitializeNativeTarget(void) {
/* If we have a native target, initialize it to ensure it is linked in. */ /* If we have a native target, initialize it to ensure it is linked in. */
#ifdef LLVM_NATIVE_ARCH #ifdef LLVM_NATIVE_TARGET
#define DoInit2(TARG) \ LLVM_NATIVE_TARGETINFO();
LLVMInitialize ## TARG ## Info (); \ LLVM_NATIVE_TARGET();
LLVMInitialize ## TARG ()
#define DoInit(T) DoInit2(T)
DoInit(LLVM_NATIVE_ARCH);
return 0; return 0;
#undef DoInit
#undef DoInit2
#else #else
return 1; return 1;
#endif #endif

View File

@ -18,6 +18,7 @@
#include <stdbool.h> #include <stdbool.h>
#include <stddef.h> #include <stddef.h>
#include "llvm/System/DataTypes.h"
#define LTO_API_VERSION 3 #define LTO_API_VERSION 3
@ -135,11 +136,17 @@ lto_module_dispose(lto_module_t mod);
extern const char* extern const char*
lto_module_get_target_triple(lto_module_t mod); lto_module_get_target_triple(lto_module_t mod);
/**
* Sets triple string with which the object will be codegened.
*/
extern void
lto_module_set_target_triple(lto_module_t mod, const char *triple);
/** /**
* Returns the number of symbols in the object module. * Returns the number of symbols in the object module.
*/ */
extern unsigned int extern uint32_t
lto_module_get_num_symbols(lto_module_t mod); lto_module_get_num_symbols(lto_module_t mod);
@ -147,14 +154,14 @@ lto_module_get_num_symbols(lto_module_t mod);
* Returns the name of the ith symbol in the object module. * Returns the name of the ith symbol in the object module.
*/ */
extern const char* extern const char*
lto_module_get_symbol_name(lto_module_t mod, unsigned int index); lto_module_get_symbol_name(lto_module_t mod, uint32_t index);
/** /**
* Returns the attributes of the ith symbol in the object module. * Returns the attributes of the ith symbol in the object module.
*/ */
extern lto_symbol_attributes extern lto_symbol_attributes
lto_module_get_symbol_attribute(lto_module_t mod, unsigned int index); lto_module_get_symbol_attribute(lto_module_t mod, uint32_t index);
/** /**
@ -200,11 +207,10 @@ lto_codegen_set_pic_model(lto_code_gen_t cg, lto_codegen_model);
/** /**
* Sets the location of the "gcc" to run. If not set, libLTO will search for * Sets the cpu to generate code for.
* "gcc" on the path.
*/ */
extern void extern void
lto_codegen_set_gcc_path(lto_code_gen_t cg, const char* path); lto_codegen_set_cpu(lto_code_gen_t cg, const char *cpu);
/** /**
@ -214,6 +220,12 @@ lto_codegen_set_gcc_path(lto_code_gen_t cg, const char* path);
extern void extern void
lto_codegen_set_assembler_path(lto_code_gen_t cg, const char* path); lto_codegen_set_assembler_path(lto_code_gen_t cg, const char* path);
/**
* Sets extra arguments that libLTO should pass to the assembler.
*/
extern void
lto_codegen_set_assembler_args(lto_code_gen_t cg, const char **args,
int nargs);
/** /**
* Adds to a list of all global symbols that must exist in the final * Adds to a list of all global symbols that must exist in the final

View File

@ -464,7 +464,7 @@ public:
// For small values, return quickly // For small values, return quickly
if (numBits <= APINT_BITS_PER_WORD) if (numBits <= APINT_BITS_PER_WORD)
return APInt(numBits, ~0ULL << shiftAmt); return APInt(numBits, ~0ULL << shiftAmt);
return (~APInt(numBits, 0)).shl(shiftAmt); return getAllOnesValue(numBits).shl(shiftAmt);
} }
/// Constructs an APInt value that has the bottom loBitsSet bits set. /// Constructs an APInt value that has the bottom loBitsSet bits set.
@ -481,7 +481,7 @@ public:
// For small values, return quickly. // For small values, return quickly.
if (numBits < APINT_BITS_PER_WORD) if (numBits < APINT_BITS_PER_WORD)
return APInt(numBits, (1ULL << loBitsSet) - 1); return APInt(numBits, (1ULL << loBitsSet) - 1);
return (~APInt(numBits, 0)).lshr(numBits - loBitsSet); return getAllOnesValue(numBits).lshr(numBits - loBitsSet);
} }
/// The hash value is computed as the sum of the words and the bit width. /// The hash value is computed as the sum of the words and the bit width.

View File

@ -185,13 +185,12 @@ public:
++NumTombstones; ++NumTombstones;
return true; return true;
} }
bool erase(iterator I) { void erase(iterator I) {
BucketT *TheBucket = &*I; BucketT *TheBucket = &*I;
TheBucket->second.~ValueT(); TheBucket->second.~ValueT();
TheBucket->first = getTombstoneKey(); TheBucket->first = getTombstoneKey();
--NumEntries; --NumEntries;
++NumTombstones; ++NumTombstones;
return true;
} }
void swap(DenseMap& RHS) { void swap(DenseMap& RHS) {

View File

@ -58,6 +58,7 @@ public:
class Iterator { class Iterator {
typename MapTy::iterator I; typename MapTy::iterator I;
friend class DenseSet;
public: public:
typedef typename MapTy::iterator::difference_type difference_type; typedef typename MapTy::iterator::difference_type difference_type;
typedef ValueT value_type; typedef ValueT value_type;
@ -77,6 +78,7 @@ public:
class ConstIterator { class ConstIterator {
typename MapTy::const_iterator I; typename MapTy::const_iterator I;
friend class DenseSet;
public: public:
typedef typename MapTy::const_iterator::difference_type difference_type; typedef typename MapTy::const_iterator::difference_type difference_type;
typedef ValueT value_type; typedef ValueT value_type;
@ -103,6 +105,10 @@ public:
const_iterator begin() const { return ConstIterator(TheMap.begin()); } const_iterator begin() const { return ConstIterator(TheMap.begin()); }
const_iterator end() const { return ConstIterator(TheMap.end()); } const_iterator end() const { return ConstIterator(TheMap.end()); }
iterator find(const ValueT &V) { return Iterator(TheMap.find(V)); }
void erase(Iterator I) { return TheMap.erase(I.I); }
void erase(ConstIterator CI) { return TheMap.erase(CI.I); }
std::pair<iterator, bool> insert(const ValueT &V) { std::pair<iterator, bool> insert(const ValueT &V) {
return TheMap.insert(std::make_pair(V, 0)); return TheMap.insert(std::make_pair(V, 0));
} }

View File

@ -183,6 +183,16 @@ public:
inline bool nodeVisited(NodeType *Node) const { inline bool nodeVisited(NodeType *Node) const {
return this->Visited.count(Node) != 0; return this->Visited.count(Node) != 0;
} }
/// getPathLength - Return the length of the path from the entry node to the
/// current node, counting both nodes.
unsigned getPathLength() const { return VisitStack.size(); }
/// getPath - Return the n'th node in the path from the the entry node to the
/// current node.
NodeType *getPath(unsigned n) const {
return VisitStack[n].first.getPointer();
}
}; };

View File

@ -54,9 +54,9 @@ namespace llvm {
/// void Profile(FoldingSetNodeID &ID) const { /// void Profile(FoldingSetNodeID &ID) const {
/// ID.AddString(Name); /// ID.AddString(Name);
/// ID.AddInteger(Value); /// ID.AddInteger(Value);
/// } /// }
/// ... /// ...
/// }; /// };
/// ///
/// To define the folding set itself use the FoldingSet template; /// To define the folding set itself use the FoldingSet template;
/// ///
@ -190,26 +190,76 @@ protected:
/// GetNodeProfile - Instantiations of the FoldingSet template implement /// GetNodeProfile - Instantiations of the FoldingSet template implement
/// this function to gather data bits for the given node. /// this function to gather data bits for the given node.
virtual void GetNodeProfile(FoldingSetNodeID &ID, Node *N) const = 0; virtual void GetNodeProfile(Node *N, FoldingSetNodeID &ID) const = 0;
/// NodeEquals - Instantiations of the FoldingSet template implement
/// this function to compare the given node with the given ID.
virtual bool NodeEquals(Node *N, const FoldingSetNodeID &ID,
FoldingSetNodeID &TempID) const=0;
/// NodeEquals - Instantiations of the FoldingSet template implement
/// this function to compute a hash value for the given node.
virtual unsigned ComputeNodeHash(Node *N,
FoldingSetNodeID &TempID) const = 0;
}; };
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
/// FoldingSetTrait - This trait class is used to define behavior of how
/// to "profile" (in the FoldingSet parlance) an object of a given type. template<typename T> struct FoldingSetTrait;
/// The default behavior is to invoke a 'Profile' method on an object, but
/// through template specialization the behavior can be tailored for specific /// DefaultFoldingSetTrait - This class provides default implementations
/// types. Combined with the FoldingSetNodeWrapper classs, one can add objects /// for FoldingSetTrait implementations.
/// to FoldingSets that were not originally designed to have that behavior.
/// ///
template<typename T> struct FoldingSetTrait { template<typename T> struct DefaultFoldingSetTrait {
static inline void Profile(const T& X, FoldingSetNodeID& ID) { X.Profile(ID);} static void Profile(const T& X, FoldingSetNodeID& ID) {
static inline void Profile(T& X, FoldingSetNodeID& ID) { X.Profile(ID); } X.Profile(ID);
template <typename Ctx> }
static inline void Profile(T &X, FoldingSetNodeID &ID, Ctx Context) { static void Profile(T& X, FoldingSetNodeID& ID) {
X.Profile(ID);
}
// Equals - Test if the profile for X would match ID, using TempID
// to compute a temporary ID if necessary. The default implementation
// just calls Profile and does a regular comparison. Implementations
// can override this to provide more efficient implementations.
static inline bool Equals(T &X, const FoldingSetNodeID &ID,
FoldingSetNodeID &TempID);
// ComputeHash - Compute a hash value for X, using TempID to
// compute a temporary ID if necessary. The default implementation
// just calls Profile and does a regular hash computation.
// Implementations can override this to provide more efficient
// implementations.
static inline unsigned ComputeHash(T &X, FoldingSetNodeID &TempID);
};
/// FoldingSetTrait - This trait class is used to define behavior of how
/// to "profile" (in the FoldingSet parlance) an object of a given type.
/// The default behavior is to invoke a 'Profile' method on an object, but
/// through template specialization the behavior can be tailored for specific
/// types. Combined with the FoldingSetNodeWrapper class, one can add objects
/// to FoldingSets that were not originally designed to have that behavior.
template<typename T> struct FoldingSetTrait
: public DefaultFoldingSetTrait<T> {};
template<typename T, typename Ctx> struct ContextualFoldingSetTrait;
/// DefaultContextualFoldingSetTrait - Like DefaultFoldingSetTrait, but
/// for ContextualFoldingSets.
template<typename T, typename Ctx>
struct DefaultContextualFoldingSetTrait {
static void Profile(T &X, FoldingSetNodeID &ID, Ctx Context) {
X.Profile(ID, Context); X.Profile(ID, Context);
} }
static inline bool Equals(T &X, const FoldingSetNodeID &ID,
FoldingSetNodeID &TempID, Ctx Context);
static inline unsigned ComputeHash(T &X, FoldingSetNodeID &TempID,
Ctx Context);
}; };
/// ContextualFoldingSetTrait - Like FoldingSetTrait, but for
/// ContextualFoldingSets.
template<typename T, typename Ctx> struct ContextualFoldingSetTrait
: public DefaultContextualFoldingSetTrait<T, Ctx> {};
//===--------------------------------------------------------------------===// //===--------------------------------------------------------------------===//
/// FoldingSetNodeIDRef - This class describes a reference to an interned /// FoldingSetNodeIDRef - This class describes a reference to an interned
/// FoldingSetNodeID, which can be a useful to store node id data rather /// FoldingSetNodeID, which can be a useful to store node id data rather
@ -217,13 +267,19 @@ template<typename T> struct FoldingSetTrait {
/// is often much larger than necessary, and the possibility of heap /// is often much larger than necessary, and the possibility of heap
/// allocation means it requires a non-trivial destructor call. /// allocation means it requires a non-trivial destructor call.
class FoldingSetNodeIDRef { class FoldingSetNodeIDRef {
unsigned* Data; const unsigned* Data;
size_t Size; size_t Size;
public: public:
FoldingSetNodeIDRef() : Data(0), Size(0) {} FoldingSetNodeIDRef() : Data(0), Size(0) {}
FoldingSetNodeIDRef(unsigned *D, size_t S) : Data(D), Size(S) {} FoldingSetNodeIDRef(const unsigned *D, size_t S) : Data(D), Size(S) {}
unsigned *getData() const { return Data; } /// ComputeHash - Compute a strong hash value for this FoldingSetNodeIDRef,
/// used to lookup the node in the FoldingSetImpl.
unsigned ComputeHash() const;
bool operator==(FoldingSetNodeIDRef) const;
const unsigned *getData() const { return Data; }
size_t getSize() const { return Size; } size_t getSize() const { return Size; }
}; };
@ -259,16 +315,17 @@ public:
inline void Add(const T& x) { FoldingSetTrait<T>::Profile(x, *this); } inline void Add(const T& x) { FoldingSetTrait<T>::Profile(x, *this); }
/// clear - Clear the accumulated profile, allowing this FoldingSetNodeID /// clear - Clear the accumulated profile, allowing this FoldingSetNodeID
/// object to be used to compute a new profile. /// object to be used to compute a new profile.
inline void clear() { Bits.clear(); } inline void clear() { Bits.clear(); }
/// ComputeHash - Compute a strong hash value for this FoldingSetNodeID, used /// ComputeHash - Compute a strong hash value for this FoldingSetNodeID, used
/// to lookup the node in the FoldingSetImpl. /// to lookup the node in the FoldingSetImpl.
unsigned ComputeHash() const; unsigned ComputeHash() const;
/// operator== - Used to compare two nodes to each other. /// operator== - Used to compare two nodes to each other.
/// ///
bool operator==(const FoldingSetNodeID &RHS) const; bool operator==(const FoldingSetNodeID &RHS) const;
bool operator==(const FoldingSetNodeIDRef RHS) const;
/// Intern - Copy this node's data to a memory region allocated from the /// Intern - Copy this node's data to a memory region allocated from the
/// given allocator and return a FoldingSetNodeIDRef describing the /// given allocator and return a FoldingSetNodeIDRef describing the
@ -281,6 +338,39 @@ typedef FoldingSetImpl::Node FoldingSetNode;
template<class T> class FoldingSetIterator; template<class T> class FoldingSetIterator;
template<class T> class FoldingSetBucketIterator; template<class T> class FoldingSetBucketIterator;
// Definitions of FoldingSetTrait and ContextualFoldingSetTrait functions, which
// require the definition of FoldingSetNodeID.
template<typename T>
inline bool
DefaultFoldingSetTrait<T>::Equals(T &X, const FoldingSetNodeID &ID,
FoldingSetNodeID &TempID) {
FoldingSetTrait<T>::Profile(X, TempID);
return TempID == ID;
}
template<typename T>
inline unsigned
DefaultFoldingSetTrait<T>::ComputeHash(T &X, FoldingSetNodeID &TempID) {
FoldingSetTrait<T>::Profile(X, TempID);
return TempID.ComputeHash();
}
template<typename T, typename Ctx>
inline bool
DefaultContextualFoldingSetTrait<T, Ctx>::Equals(T &X,
const FoldingSetNodeID &ID,
FoldingSetNodeID &TempID,
Ctx Context) {
ContextualFoldingSetTrait<T, Ctx>::Profile(X, TempID, Context);
return TempID == ID;
}
template<typename T, typename Ctx>
inline unsigned
DefaultContextualFoldingSetTrait<T, Ctx>::ComputeHash(T &X,
FoldingSetNodeID &TempID,
Ctx Context) {
ContextualFoldingSetTrait<T, Ctx>::Profile(X, TempID, Context);
return TempID.ComputeHash();
}
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
/// FoldingSet - This template class is used to instantiate a specialized /// FoldingSet - This template class is used to instantiate a specialized
/// implementation of the folding set to the node class T. T must be a /// implementation of the folding set to the node class T. T must be a
@ -290,9 +380,23 @@ template<class T> class FoldingSet : public FoldingSetImpl {
private: private:
/// GetNodeProfile - Each instantiatation of the FoldingSet needs to provide a /// GetNodeProfile - Each instantiatation of the FoldingSet needs to provide a
/// way to convert nodes into a unique specifier. /// way to convert nodes into a unique specifier.
virtual void GetNodeProfile(FoldingSetNodeID &ID, Node *N) const { virtual void GetNodeProfile(Node *N, FoldingSetNodeID &ID) const {
T *TN = static_cast<T *>(N); T *TN = static_cast<T *>(N);
FoldingSetTrait<T>::Profile(*TN,ID); FoldingSetTrait<T>::Profile(*TN, ID);
}
/// NodeEquals - Instantiations may optionally provide a way to compare a
/// node with a specified ID.
virtual bool NodeEquals(Node *N, const FoldingSetNodeID &ID,
FoldingSetNodeID &TempID) const {
T *TN = static_cast<T *>(N);
return FoldingSetTrait<T>::Equals(*TN, ID, TempID);
}
/// NodeEquals - Instantiations may optionally provide a way to compute a
/// hash value directly from a node.
virtual unsigned ComputeNodeHash(Node *N,
FoldingSetNodeID &TempID) const {
T *TN = static_cast<T *>(N);
return FoldingSetTrait<T>::ComputeHash(*TN, TempID);
} }
public: public:
@ -354,13 +458,21 @@ private:
/// GetNodeProfile - Each instantiatation of the FoldingSet needs to provide a /// GetNodeProfile - Each instantiatation of the FoldingSet needs to provide a
/// way to convert nodes into a unique specifier. /// way to convert nodes into a unique specifier.
virtual void GetNodeProfile(FoldingSetNodeID &ID, virtual void GetNodeProfile(FoldingSetImpl::Node *N,
FoldingSetImpl::Node *N) const { FoldingSetNodeID &ID) const {
T *TN = static_cast<T *>(N); T *TN = static_cast<T *>(N);
ContextualFoldingSetTrait<T, Ctx>::Profile(*TN, ID, Context);
// We must use explicit template arguments in case Ctx is a }
// reference type. virtual bool NodeEquals(FoldingSetImpl::Node *N,
FoldingSetTrait<T>::template Profile<Ctx>(*TN, ID, Context); const FoldingSetNodeID &ID,
FoldingSetNodeID &TempID) const {
T *TN = static_cast<T *>(N);
return ContextualFoldingSetTrait<T, Ctx>::Equals(*TN, ID, TempID, Context);
}
virtual unsigned ComputeNodeHash(FoldingSetImpl::Node *N,
FoldingSetNodeID &TempID) const {
T *TN = static_cast<T *>(N);
return ContextualFoldingSetTrait<T, Ctx>::ComputeHash(*TN, TempID, Context);
} }
public: public:
@ -447,8 +559,8 @@ public:
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
/// FoldingSetBucketIteratorImpl - This is the common bucket iterator support /// FoldingSetBucketIteratorImpl - This is the common bucket iterator support
/// shared by all folding sets, which knows how to walk a particular bucket /// shared by all folding sets, which knows how to walk a particular bucket
/// of a folding set hash table. /// of a folding set hash table.
class FoldingSetBucketIteratorImpl { class FoldingSetBucketIteratorImpl {
protected: protected:
@ -549,7 +661,7 @@ class FastFoldingSetNode : public FoldingSetNode {
protected: protected:
explicit FastFoldingSetNode(const FoldingSetNodeID &ID) : FastID(ID) {} explicit FastFoldingSetNode(const FoldingSetNodeID &ID) : FastID(ID) {}
public: public:
void Profile(FoldingSetNodeID& ID) { ID = FastID; } void Profile(FoldingSetNodeID& ID) const { ID = FastID; }
}; };
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
@ -559,9 +671,6 @@ template<typename T> struct FoldingSetTrait<T*> {
static inline void Profile(const T* X, FoldingSetNodeID& ID) { static inline void Profile(const T* X, FoldingSetNodeID& ID) {
ID.AddPointer(X); ID.AddPointer(X);
} }
static inline void Profile(T* X, FoldingSetNodeID& ID) {
ID.AddPointer(X);
}
}; };
template<typename T> struct FoldingSetTrait<const T*> { template<typename T> struct FoldingSetTrait<const T*> {

View File

@ -16,14 +16,14 @@ namespace llvm {
class Interval { class Interval {
private: private:
uint64_t Start; int64_t Start;
uint64_t End; int64_t End;
public: public:
Interval(uint64_t S, uint64_t E) : Start(S), End(E) {} Interval(int64_t S, int64_t E) : Start(S), End(E) {}
uint64_t getStart() const { return Start; } int64_t getStart() const { return Start; }
uint64_t getEnd() const { return End; } int64_t getEnd() const { return End; }
}; };
template <typename T> template <typename T>

View File

@ -0,0 +1,52 @@
//===- llvm/ADT/NullablePtr.h - A pointer that allows null ------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines and implements the NullablePtr class.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ADT_NULLABLE_PTR_H
#define LLVM_ADT_NULLABLE_PTR_H
#include <cassert>
#include <cstddef>
namespace llvm {
/// NullablePtr pointer wrapper - NullablePtr is used for APIs where a
/// potentially-null pointer gets passed around that must be explicitly handled
/// in lots of places. By putting a wrapper around the null pointer, it makes
/// it more likely that the null pointer case will be handled correctly.
template<class T>
class NullablePtr {
T *Ptr;
public:
NullablePtr(T *P = 0) : Ptr(P) {}
bool isNull() const { return Ptr == 0; }
bool isNonNull() const { return Ptr != 0; }
/// get - Return the pointer if it is non-null.
const T *get() const {
assert(Ptr && "Pointer wasn't checked for null!");
return Ptr;
}
/// get - Return the pointer if it is non-null.
T *get() {
assert(Ptr && "Pointer wasn't checked for null!");
return Ptr;
}
T *getPtrOrNull() { return Ptr; }
const T *getPtrOrNull() const { return Ptr; }
};
} // end namespace llvm
#endif

View File

@ -225,7 +225,7 @@ inline T *array_endof(T (&x)[N]) {
/// Find the length of an array. /// Find the length of an array.
template<class T, std::size_t N> template<class T, std::size_t N>
inline size_t array_lengthof(T (&x)[N]) { inline size_t array_lengthof(T (&)[N]) {
return N; return N;
} }
@ -243,7 +243,7 @@ static inline int array_pod_sort_comparator(const void *P1, const void *P2) {
/// get_array_pad_sort_comparator - This is an internal helper function used to /// get_array_pad_sort_comparator - This is an internal helper function used to
/// get type deduction of T right. /// get type deduction of T right.
template<typename T> template<typename T>
static int (*get_array_pad_sort_comparator(const T &X)) static int (*get_array_pad_sort_comparator(const T &))
(const void*, const void*) { (const void*, const void*) {
return array_pod_sort_comparator<T>; return array_pod_sort_comparator<T>;
} }

View File

@ -139,7 +139,12 @@ public:
} }
V lookup(const K &Key) { V lookup(const K &Key) {
return TopLevelMap[Key]->getValue(); typename DenseMap<K, ScopedHashTableVal<K, V, KInfo>*, KInfo>::iterator
I = TopLevelMap.find(Key);
if (I != TopLevelMap.end())
return I->second->getValue();
return V();
} }
void insert(const K &Key, const V &Val) { void insert(const K &Key, const V &Val) {

View File

@ -206,7 +206,7 @@ template <typename T, bool isPodLike>
void SmallVectorTemplateBase<T, isPodLike>::grow(size_t MinSize) { void SmallVectorTemplateBase<T, isPodLike>::grow(size_t MinSize) {
size_t CurCapacity = this->capacity(); size_t CurCapacity = this->capacity();
size_t CurSize = this->size(); size_t CurSize = this->size();
size_t NewCapacity = 2*CurCapacity; size_t NewCapacity = 2*CurCapacity + 1; // Always grow, even from zero.
if (NewCapacity < MinSize) if (NewCapacity < MinSize)
NewCapacity = MinSize; NewCapacity = MinSize;
T *NewElts = static_cast<T*>(malloc(NewCapacity*sizeof(T))); T *NewElts = static_cast<T*>(malloc(NewCapacity*sizeof(T)));
@ -707,6 +707,36 @@ public:
}; };
/// Specialize SmallVector at N=0. This specialization guarantees
/// that it can be instantiated at an incomplete T if none of its
/// members are required.
template <typename T>
class SmallVector<T,0> : public SmallVectorImpl<T> {
public:
SmallVector() : SmallVectorImpl<T>(0) {}
explicit SmallVector(unsigned Size, const T &Value = T())
: SmallVectorImpl<T>(0) {
this->reserve(Size);
while (Size--)
this->push_back(Value);
}
template<typename ItTy>
SmallVector(ItTy S, ItTy E) : SmallVectorImpl<T>(0) {
this->append(S, E);
}
SmallVector(const SmallVector &RHS) : SmallVectorImpl<T>(0) {
SmallVectorImpl<T>::operator=(RHS);
}
SmallVector &operator=(const SmallVectorImpl<T> &RHS) {
return SmallVectorImpl<T>::operator=(RHS);
}
};
} // End llvm namespace } // End llvm namespace
namespace std { namespace std {

View File

@ -254,6 +254,10 @@ public:
StringMap() : StringMapImpl(static_cast<unsigned>(sizeof(MapEntryTy))) {} StringMap() : StringMapImpl(static_cast<unsigned>(sizeof(MapEntryTy))) {}
explicit StringMap(unsigned InitialSize) explicit StringMap(unsigned InitialSize)
: StringMapImpl(InitialSize, static_cast<unsigned>(sizeof(MapEntryTy))) {} : StringMapImpl(InitialSize, static_cast<unsigned>(sizeof(MapEntryTy))) {}
explicit StringMap(AllocatorTy A)
: StringMapImpl(static_cast<unsigned>(sizeof(MapEntryTy))), Allocator(A) {}
explicit StringMap(const StringMap &RHS) explicit StringMap(const StringMap &RHS)
: StringMapImpl(static_cast<unsigned>(sizeof(MapEntryTy))) { : StringMapImpl(static_cast<unsigned>(sizeof(MapEntryTy))) {
assert(RHS.empty() && assert(RHS.empty() &&

View File

@ -149,7 +149,10 @@ namespace llvm {
unsigned edit_distance(StringRef Other, bool AllowReplacements = true); unsigned edit_distance(StringRef Other, bool AllowReplacements = true);
/// str - Get the contents as an std::string. /// str - Get the contents as an std::string.
std::string str() const { return std::string(Data, Length); } std::string str() const {
if (Data == 0) return std::string();
return std::string(Data, Length);
}
/// @} /// @}
/// @name Operator Overloads /// @name Operator Overloads
@ -228,12 +231,14 @@ namespace llvm {
/// find_first_of - Find the first character in the string that is \arg C, /// find_first_of - Find the first character in the string that is \arg C,
/// or npos if not found. Same as find. /// or npos if not found. Same as find.
size_type find_first_of(char C, size_t = 0) const { return find(C); } size_type find_first_of(char C, size_t From = 0) const {
return find(C, From);
}
/// find_first_of - Find the first character in the string that is in \arg /// find_first_of - Find the first character in the string that is in \arg
/// Chars, or npos if not found. /// Chars, or npos if not found.
/// ///
/// Note: O(size() * Chars.size()) /// Note: O(size() + Chars.size())
size_type find_first_of(StringRef Chars, size_t From = 0) const; size_type find_first_of(StringRef Chars, size_t From = 0) const;
/// find_first_not_of - Find the first character in the string that is not /// find_first_not_of - Find the first character in the string that is not
@ -243,7 +248,7 @@ namespace llvm {
/// find_first_not_of - Find the first character in the string that is not /// find_first_not_of - Find the first character in the string that is not
/// in the string \arg Chars, or npos if not found. /// in the string \arg Chars, or npos if not found.
/// ///
/// Note: O(size() * Chars.size()) /// Note: O(size() + Chars.size())
size_type find_first_not_of(StringRef Chars, size_t From = 0) const; size_type find_first_not_of(StringRef Chars, size_t From = 0) const;
/// @} /// @}

View File

@ -15,7 +15,6 @@
#define LLVM_ADT_STRINGSET_H #define LLVM_ADT_STRINGSET_H
#include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringMap.h"
#include <cassert>
namespace llvm { namespace llvm {
@ -26,10 +25,10 @@ namespace llvm {
class StringSet : public llvm::StringMap<char, AllocatorTy> { class StringSet : public llvm::StringMap<char, AllocatorTy> {
typedef llvm::StringMap<char, AllocatorTy> base; typedef llvm::StringMap<char, AllocatorTy> base;
public: public:
bool insert(const std::string& InLang) { bool insert(StringRef InLang) {
assert(!InLang.empty()); assert(!InLang.empty());
const char* KeyStart = &InLang[0]; const char *KeyStart = InLang.data();
const char* KeyEnd = KeyStart + InLang.size(); const char *KeyEnd = KeyStart + InLang.size();
return base::insert(llvm::StringMapEntry<char>:: return base::insert(llvm::StringMapEntry<char>::
Create(KeyStart, KeyEnd, base::getAllocator(), '+')); Create(KeyStart, KeyEnd, base::getAllocator(), '+'));
} }

View File

@ -61,6 +61,26 @@ public:
return *this; return *this;
} }
template<unsigned N>
StringSwitch& EndsWith(const char (&S)[N], const T &Value) {
if (!Result && Str.size() >= N-1 &&
std::memcmp(S, Str.data() + Str.size() + 1 - N, N-1) == 0) {
Result = &Value;
}
return *this;
}
template<unsigned N>
StringSwitch& StartsWith(const char (&S)[N], const T &Value) {
if (!Result && Str.size() >= N-1 &&
std::memcmp(S, Str.data(), N-1) == 0) {
Result = &Value;
}
return *this;
}
template<unsigned N0, unsigned N1> template<unsigned N0, unsigned N1>
StringSwitch& Cases(const char (&S0)[N0], const char (&S1)[N1], StringSwitch& Cases(const char (&S0)[N0], const char (&S1)[N1],
const T& Value) { const T& Value) {

View File

@ -24,7 +24,7 @@ class Twine;
/// Triple - Helper class for working with target triples. /// Triple - Helper class for working with target triples.
/// ///
/// Target triples are strings in the format of: /// Target triples are strings in the canonical form:
/// ARCHITECTURE-VENDOR-OPERATING_SYSTEM /// ARCHITECTURE-VENDOR-OPERATING_SYSTEM
/// or /// or
/// ARCHITECTURE-VENDOR-OPERATING_SYSTEM-ENVIRONMENT /// ARCHITECTURE-VENDOR-OPERATING_SYSTEM-ENVIRONMENT
@ -35,20 +35,11 @@ class Twine;
/// from the components of the target triple to well known IDs. /// from the components of the target triple to well known IDs.
/// ///
/// At its core the Triple class is designed to be a wrapper for a triple /// At its core the Triple class is designed to be a wrapper for a triple
/// string; it does not normally change or normalize the triple string, instead /// string; the constructor does not change or normalize the triple string.
/// it provides additional APIs to parse normalized parts out of the triple. /// Clients that need to handle the non-canonical triples that users often
/// specify should use the normalize method.
/// ///
/// One curiosity this implies is that for some odd triples the results of, /// See autoconf/config.guess for a glimpse into what triples look like in
/// e.g., getOSName() can be very different from the result of getOS(). For
/// example, for 'i386-mingw32', getOS() will return MinGW32, but since
/// getOSName() is purely based on the string structure that will return the
/// empty string.
///
/// Clients should generally avoid using getOSName() and related APIs unless
/// they are familiar with the triple format (this is particularly true when
/// rewriting a triple).
///
/// See autoconf/config.guess for a glimpse into what they look like in
/// practice. /// practice.
class Triple { class Triple {
public: public:
@ -117,6 +108,9 @@ private:
mutable OSType OS; mutable OSType OS;
bool isInitialized() const { return Arch != InvalidArch; } bool isInitialized() const { return Arch != InvalidArch; }
static ArchType ParseArch(StringRef ArchName);
static VendorType ParseVendor(StringRef VendorName);
static OSType ParseOS(StringRef OSName);
void Parse() const; void Parse() const;
public: public:
@ -133,6 +127,16 @@ public:
Data += OSStr; Data += OSStr;
} }
/// @}
/// @name Normalization
/// @{
/// normalize - Turn an arbitrary machine specification into the canonical
/// triple form (or something sensible that the Triple class understands if
/// nothing better can reasonably be done). In particular, it handles the
/// common case in which otherwise valid components are in the wrong order.
static std::string normalize(StringRef Str);
/// @} /// @}
/// @name Typed Component Access /// @name Typed Component Access
/// @{ /// @{

View File

@ -82,13 +82,13 @@ class ValueMap {
typedef typename Config::ExtraData ExtraData; typedef typename Config::ExtraData ExtraData;
MapT Map; MapT Map;
ExtraData Data; ExtraData Data;
ValueMap(const ValueMap&); // DO NOT IMPLEMENT
ValueMap& operator=(const ValueMap&); // DO NOT IMPLEMENT
public: public:
typedef KeyT key_type; typedef KeyT key_type;
typedef ValueT mapped_type; typedef ValueT mapped_type;
typedef std::pair<KeyT, ValueT> value_type; typedef std::pair<KeyT, ValueT> value_type;
ValueMap(const ValueMap& Other) : Map(Other.Map), Data(Other.Data) {}
explicit ValueMap(unsigned NumInitBuckets = 64) explicit ValueMap(unsigned NumInitBuckets = 64)
: Map(NumInitBuckets), Data() {} : Map(NumInitBuckets), Data() {}
explicit ValueMap(const ExtraData &Data, unsigned NumInitBuckets = 64) explicit ValueMap(const ExtraData &Data, unsigned NumInitBuckets = 64)
@ -149,7 +149,7 @@ public:
bool erase(const KeyT &Val) { bool erase(const KeyT &Val) {
return Map.erase(Wrap(Val)); return Map.erase(Wrap(Val));
} }
bool erase(iterator I) { void erase(iterator I) {
return Map.erase(I.base()); return Map.erase(I.base());
} }
@ -161,12 +161,6 @@ public:
return Map[Wrap(Key)]; return Map[Wrap(Key)];
} }
ValueMap& operator=(const ValueMap& Other) {
Map = Other.Map;
Data = Other.Data;
return *this;
}
/// isPointerIntoBucketsArray - Return true if the specified pointer points /// isPointerIntoBucketsArray - Return true if the specified pointer points
/// somewhere into the ValueMap's array of buckets (i.e. either to a key or /// somewhere into the ValueMap's array of buckets (i.e. either to a key or
/// value in the ValueMap). /// value in the ValueMap).
@ -250,12 +244,6 @@ public:
} }
}; };
template<typename KeyT, typename ValueT, typename Config, typename ValueInfoT>
struct isPodLike<ValueMapCallbackVH<KeyT, ValueT, Config, ValueInfoT> > {
static const bool value = true;
};
template<typename KeyT, typename ValueT, typename Config, typename ValueInfoT> template<typename KeyT, typename ValueT, typename Config, typename ValueInfoT>
struct DenseMapInfo<ValueMapCallbackVH<KeyT, ValueT, Config, ValueInfoT> > { struct DenseMapInfo<ValueMapCallbackVH<KeyT, ValueT, Config, ValueInfoT> > {
typedef ValueMapCallbackVH<KeyT, ValueT, Config, ValueInfoT> VH; typedef ValueMapCallbackVH<KeyT, ValueT, Config, ValueInfoT> VH;

View File

@ -614,7 +614,6 @@ public:
template<class Pr3> void sort(Pr3 pred); template<class Pr3> void sort(Pr3 pred);
void sort() { sort(op_less); } void sort() { sort(op_less); }
void reverse();
}; };

View File

@ -1,79 +0,0 @@
//===-- llvm/ADT/iterator - Portable wrapper around <iterator> --*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file provides a wrapper around the mysterious <iterator> header file.
// In GCC 2.95.3, the file defines a bidirectional_iterator class (and other
// friends), instead of the standard iterator class. In GCC 3.1, the
// bidirectional_iterator class got moved out and the new, standards compliant,
// iterator<> class was added. Because there is nothing that we can do to get
// correct behavior on both compilers, we have this header with #ifdef's. Gross
// huh?
//
// By #includ'ing this file, you get the contents of <iterator> plus the
// following classes in the global namespace:
//
// 1. bidirectional_iterator
// 2. forward_iterator
//
// The #if directives' expressions are filled in by Autoconf.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ADT_ITERATOR
#define LLVM_ADT_ITERATOR
#include <iterator>
#undef HAVE_BI_ITERATOR
#undef HAVE_STD_ITERATOR
#undef HAVE_FWD_ITERATOR
// defined by Kevin
#define HAVE_STD_ITERATOR 1
#ifdef _MSC_VER
# define HAVE_BI_ITERATOR 0
# define HAVE_STD_ITERATOR 1
# define HAVE_FWD_ITERATOR 0
#endif
#if !HAVE_BI_ITERATOR
# if HAVE_STD_ITERATOR
/// If the bidirectional iterator is not defined, we attempt to define it in
/// terms of the C++ standard iterator. Otherwise, we import it with a "using"
/// statement.
///
template<class Ty, class PtrDiffTy>
struct bidirectional_iterator
: public std::iterator<std::bidirectional_iterator_tag, Ty, PtrDiffTy> {
};
# else
# error "Need to have standard iterator to define bidirectional iterator!"
# endif
#else
using std::bidirectional_iterator;
#endif
#if !HAVE_FWD_ITERATOR
# if HAVE_STD_ITERATOR
/// If the forward iterator is not defined, attempt to define it in terms of
/// the C++ standard iterator. Otherwise, we import it with a "using" statement.
///
template<class Ty, class PtrDiffTy>
struct forward_iterator
: public std::iterator<std::forward_iterator_tag, Ty, PtrDiffTy> {
};
# else
# error "Need to have standard iterator to define forward iterator!"
# endif
#else
using std::forward_iterator;
#endif
#endif

View File

@ -1,76 +0,0 @@
//==-- llvm/ADT/iterator.h - Portable wrapper around <iterator> --*- 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 a wrapper around the mysterious <iterator> header file.
// In GCC 2.95.3, the file defines a bidirectional_iterator class (and other
// friends), instead of the standard iterator class. In GCC 3.1, the
// bidirectional_iterator class got moved out and the new, standards compliant,
// iterator<> class was added. Because there is nothing that we can do to get
// correct behavior on both compilers, we have this header with #ifdef's. Gross
// huh?
//
// By #includ'ing this file, you get the contents of <iterator> plus the
// following classes in the global namespace:
//
// 1. bidirectional_iterator
// 2. forward_iterator
//
// The #if directives' expressions are filled in by Autoconf.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ADT_ITERATOR_H
#define LLVM_ADT_ITERATOR_H
#include <iterator>
#undef HAVE_BI_ITERATOR
#undef HAVE_STD_ITERATOR
#undef HAVE_FWD_ITERATOR
#ifdef _MSC_VER
# define HAVE_BI_ITERATOR 0
# define HAVE_STD_ITERATOR 1
# define HAVE_FWD_ITERATOR 0
#endif
#if !HAVE_BI_ITERATOR
# if HAVE_STD_ITERATOR
/// If the bidirectional iterator is not defined, we attempt to define it in
/// terms of the C++ standard iterator. Otherwise, we import it with a "using"
/// statement.
///
template<class Ty, class PtrDiffTy>
struct bidirectional_iterator
: public std::iterator<std::bidirectional_iterator_tag, Ty, PtrDiffTy> {
};
# else
# error "Need to have standard iterator to define bidirectional iterator!"
# endif
#else
using std::bidirectional_iterator;
#endif
#if !HAVE_FWD_ITERATOR
# if HAVE_STD_ITERATOR
/// If the forward iterator is not defined, attempt to define it in terms of
/// the C++ standard iterator. Otherwise, we import it with a "using" statement.
///
template<class Ty, class PtrDiffTy>
struct forward_iterator
: public std::iterator<std::forward_iterator_tag, Ty, PtrDiffTy> {
};
# else
# error "Need to have standard iterator to define forward iterator!"
# endif
#else
using std::forward_iterator;
#endif
#endif // LLVM_ADT_ITERATOR_H

View File

@ -18,12 +18,9 @@
// //
// This API represents memory as a (Pointer, Size) pair. The Pointer component // This API represents memory as a (Pointer, Size) pair. The Pointer component
// specifies the base memory address of the region, the Size specifies how large // specifies the base memory address of the region, the Size specifies how large
// of an area is being queried. If Size is 0, two pointers only alias if they // of an area is being queried, or UnknownSize if the size is not known.
// are exactly equal. If size is greater than zero, but small, the two pointers // Pointers that point to two completely different objects in memory never
// alias if the areas pointed to overlap. If the size is very large (ie, ~0U), // alias, regardless of the value of the Size component.
// then the two pointers alias if they may be pointing to components of the same
// memory object. Pointers that point to two completely different objects in
// memory never alias, regardless of the value of the Size component.
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
@ -46,8 +43,11 @@ class AnalysisUsage;
class AliasAnalysis { class AliasAnalysis {
protected: protected:
const TargetData *TD; const TargetData *TD;
private:
AliasAnalysis *AA; // Previous Alias Analysis to chain to. AliasAnalysis *AA; // Previous Alias Analysis to chain to.
protected:
/// InitializeAliasAnalysis - Subclasses must call this method to initialize /// InitializeAliasAnalysis - Subclasses must call this method to initialize
/// the AliasAnalysis interface before any other methods are called. This is /// the AliasAnalysis interface before any other methods are called. This is
/// typically called by the run* methods of these subclasses. This may be /// typically called by the run* methods of these subclasses. This may be
@ -64,6 +64,11 @@ public:
AliasAnalysis() : TD(0), AA(0) {} AliasAnalysis() : TD(0), AA(0) {}
virtual ~AliasAnalysis(); // We want to be subclassed virtual ~AliasAnalysis(); // We want to be subclassed
/// UnknownSize - This is a special value which can be used with the
/// size arguments in alias queries to indicate that the caller does not
/// know the sizes of the potential memory references.
static unsigned const UnknownSize = ~0u;
/// getTargetData - Return a pointer to the current TargetData object, or /// getTargetData - Return a pointer to the current TargetData object, or
/// null if no TargetData object is available. /// null if no TargetData object is available.
/// ///
@ -84,6 +89,9 @@ public:
/// if (AA.alias(P1, P2)) { ... } /// if (AA.alias(P1, P2)) { ... }
/// to check to see if two pointers might alias. /// to check to see if two pointers might alias.
/// ///
/// See docs/AliasAnalysis.html for more information on the specific meanings
/// of these values.
///
enum AliasResult { NoAlias = 0, MayAlias = 1, MustAlias = 2 }; enum AliasResult { NoAlias = 0, MayAlias = 1, MustAlias = 2 };
/// alias - The main low level interface to the alias analysis implementation. /// alias - The main low level interface to the alias analysis implementation.
@ -94,6 +102,11 @@ public:
virtual AliasResult alias(const Value *V1, unsigned V1Size, virtual AliasResult alias(const Value *V1, unsigned V1Size,
const Value *V2, unsigned V2Size); const Value *V2, unsigned V2Size);
/// alias - A convenience wrapper for the case where the sizes are unknown.
AliasResult alias(const Value *V1, const Value *V2) {
return alias(V1, UnknownSize, V2, UnknownSize);
}
/// isNoAlias - A trivial helper function to check to see if the specified /// isNoAlias - A trivial helper function to check to see if the specified
/// pointers are no-alias. /// pointers are no-alias.
bool isNoAlias(const Value *V1, unsigned V1Size, bool isNoAlias(const Value *V1, unsigned V1Size,
@ -130,17 +143,11 @@ public:
// AccessesArguments - This function accesses function arguments in well // AccessesArguments - This function accesses function arguments in well
// known (possibly volatile) ways, but does not access any other memory. // known (possibly volatile) ways, but does not access any other memory.
//
// Clients may use the Info parameter of getModRefBehavior to get specific
// information about how pointer arguments are used.
AccessesArguments, AccessesArguments,
// AccessesArgumentsAndGlobals - This function has accesses function // AccessesArgumentsAndGlobals - This function has accesses function
// arguments and global variables well known (possibly volatile) ways, but // arguments and global variables well known (possibly volatile) ways, but
// does not access any other memory. // does not access any other memory.
//
// Clients may use the Info parameter of getModRefBehavior to get specific
// information about how pointer arguments are used.
AccessesArgumentsAndGlobals, AccessesArgumentsAndGlobals,
// OnlyReadsMemory - This function does not perform any non-local stores or // OnlyReadsMemory - This function does not perform any non-local stores or
@ -154,31 +161,17 @@ public:
UnknownModRefBehavior UnknownModRefBehavior
}; };
/// PointerAccessInfo - This struct is used to return results for pointers,
/// globals, and the return value of a function.
struct PointerAccessInfo {
/// V - The value this record corresponds to. This may be an Argument for
/// the function, a GlobalVariable, or null, corresponding to the return
/// value for the function.
Value *V;
/// ModRefInfo - Whether the pointer is loaded or stored to/from.
///
ModRefResult ModRefInfo;
};
/// getModRefBehavior - Return the behavior when calling the given call site. /// getModRefBehavior - Return the behavior when calling the given call site.
virtual ModRefBehavior getModRefBehavior(CallSite CS, virtual ModRefBehavior getModRefBehavior(ImmutableCallSite CS);
std::vector<PointerAccessInfo> *Info = 0);
/// getModRefBehavior - Return the behavior when calling the given function. /// getModRefBehavior - Return the behavior when calling the given function.
/// For use when the call site is not known. /// For use when the call site is not known.
virtual ModRefBehavior getModRefBehavior(Function *F, virtual ModRefBehavior getModRefBehavior(const Function *F);
std::vector<PointerAccessInfo> *Info = 0);
/// getModRefBehavior - Return the modref behavior of the intrinsic with the /// getIntrinsicModRefBehavior - Return the modref behavior of the intrinsic
/// given id. /// with the given id. Most clients won't need this, because the regular
static ModRefBehavior getModRefBehavior(unsigned iid); /// getModRefBehavior incorporates this information.
static ModRefBehavior getIntrinsicModRefBehavior(unsigned iid);
/// doesNotAccessMemory - If the specified call is known to never read or /// doesNotAccessMemory - If the specified call is known to never read or
/// write memory, return true. If the call only reads from known-constant /// write memory, return true. If the call only reads from known-constant
@ -191,14 +184,14 @@ public:
/// ///
/// This property corresponds to the GCC 'const' attribute. /// This property corresponds to the GCC 'const' attribute.
/// ///
bool doesNotAccessMemory(CallSite CS) { bool doesNotAccessMemory(ImmutableCallSite CS) {
return getModRefBehavior(CS) == DoesNotAccessMemory; return getModRefBehavior(CS) == DoesNotAccessMemory;
} }
/// doesNotAccessMemory - If the specified function is known to never read or /// doesNotAccessMemory - If the specified function is known to never read or
/// write memory, return true. For use when the call site is not known. /// write memory, return true. For use when the call site is not known.
/// ///
bool doesNotAccessMemory(Function *F) { bool doesNotAccessMemory(const Function *F) {
return getModRefBehavior(F) == DoesNotAccessMemory; return getModRefBehavior(F) == DoesNotAccessMemory;
} }
@ -211,7 +204,7 @@ public:
/// ///
/// This property corresponds to the GCC 'pure' attribute. /// This property corresponds to the GCC 'pure' attribute.
/// ///
bool onlyReadsMemory(CallSite CS) { bool onlyReadsMemory(ImmutableCallSite CS) {
ModRefBehavior MRB = getModRefBehavior(CS); ModRefBehavior MRB = getModRefBehavior(CS);
return MRB == DoesNotAccessMemory || MRB == OnlyReadsMemory; return MRB == DoesNotAccessMemory || MRB == OnlyReadsMemory;
} }
@ -220,7 +213,7 @@ public:
/// non-volatile memory (or not access memory at all), return true. For use /// non-volatile memory (or not access memory at all), return true. For use
/// when the call site is not known. /// when the call site is not known.
/// ///
bool onlyReadsMemory(Function *F) { bool onlyReadsMemory(const Function *F) {
ModRefBehavior MRB = getModRefBehavior(F); ModRefBehavior MRB = getModRefBehavior(F);
return MRB == DoesNotAccessMemory || MRB == OnlyReadsMemory; return MRB == DoesNotAccessMemory || MRB == OnlyReadsMemory;
} }
@ -234,36 +227,36 @@ public:
/// a particular call site modifies or reads the memory specified by the /// a particular call site modifies or reads the memory specified by the
/// pointer. /// pointer.
/// ///
virtual ModRefResult getModRefInfo(CallSite CS, Value *P, unsigned Size); virtual ModRefResult getModRefInfo(ImmutableCallSite CS,
const Value *P, unsigned Size);
/// getModRefInfo - Return information about whether two call sites may refer /// getModRefInfo - Return information about whether two call sites may refer
/// to the same set of memory locations. This function returns NoModRef if /// to the same set of memory locations. See
/// the two calls refer to disjoint memory locations, Ref if CS1 reads memory /// http://llvm.org/docs/AliasAnalysis.html#ModRefInfo
/// written by CS2, Mod if CS1 writes to memory read or written by CS2, or /// for details.
/// ModRef if CS1 might read or write memory accessed by CS2. virtual ModRefResult getModRefInfo(ImmutableCallSite CS1,
/// ImmutableCallSite CS2);
virtual ModRefResult getModRefInfo(CallSite CS1, CallSite CS2);
public: public:
/// Convenience functions... /// Convenience functions...
ModRefResult getModRefInfo(LoadInst *L, Value *P, unsigned Size); ModRefResult getModRefInfo(const LoadInst *L, const Value *P, unsigned Size);
ModRefResult getModRefInfo(StoreInst *S, Value *P, unsigned Size); ModRefResult getModRefInfo(const StoreInst *S, const Value *P, unsigned Size);
ModRefResult getModRefInfo(CallInst *C, Value *P, unsigned Size) { ModRefResult getModRefInfo(const VAArgInst* I, const Value* P, unsigned Size);
return getModRefInfo(CallSite(C), P, Size); ModRefResult getModRefInfo(const CallInst *C, const Value *P, unsigned Size) {
return getModRefInfo(ImmutableCallSite(C), P, Size);
} }
ModRefResult getModRefInfo(InvokeInst *I, Value *P, unsigned Size) { ModRefResult getModRefInfo(const InvokeInst *I,
return getModRefInfo(CallSite(I), P, Size); const Value *P, unsigned Size) {
return getModRefInfo(ImmutableCallSite(I), P, Size);
} }
ModRefResult getModRefInfo(VAArgInst* I, Value* P, unsigned Size) { ModRefResult getModRefInfo(const Instruction *I,
return AliasAnalysis::ModRef; const Value *P, unsigned Size) {
}
ModRefResult getModRefInfo(Instruction *I, Value *P, unsigned Size) {
switch (I->getOpcode()) { switch (I->getOpcode()) {
case Instruction::VAArg: return getModRefInfo((VAArgInst*)I, P, Size); case Instruction::VAArg: return getModRefInfo((const VAArgInst*)I, P,Size);
case Instruction::Load: return getModRefInfo((LoadInst*)I, P, Size); case Instruction::Load: return getModRefInfo((const LoadInst*)I, P, Size);
case Instruction::Store: return getModRefInfo((StoreInst*)I, P, Size); case Instruction::Store: return getModRefInfo((const StoreInst*)I, P,Size);
case Instruction::Call: return getModRefInfo((CallInst*)I, P, Size); case Instruction::Call: return getModRefInfo((const CallInst*)I, P, Size);
case Instruction::Invoke: return getModRefInfo((InvokeInst*)I, P, Size); case Instruction::Invoke: return getModRefInfo((const InvokeInst*)I,P,Size);
default: return NoModRef; default: return NoModRef;
} }
} }

View File

@ -92,7 +92,8 @@ class AliasSet : public ilist_node<AliasSet> {
AliasSet *Forward; // Forwarding pointer. AliasSet *Forward; // Forwarding pointer.
AliasSet *Next, *Prev; // Doubly linked list of AliasSets. AliasSet *Next, *Prev; // Doubly linked list of AliasSets.
std::vector<CallSite> CallSites; // All calls & invokes in this alias set. // All calls & invokes in this alias set.
std::vector<AssertingVH<Instruction> > CallSites;
// RefCount - Number of nodes pointing to this AliasSet plus the number of // RefCount - Number of nodes pointing to this AliasSet plus the number of
// AliasSets forwarding to it. // AliasSets forwarding to it.
@ -127,6 +128,11 @@ class AliasSet : public ilist_node<AliasSet> {
removeFromTracker(AST); removeFromTracker(AST);
} }
CallSite getCallSite(unsigned i) const {
assert(i < CallSites.size());
return CallSite(CallSites[i]);
}
public: public:
/// Accessors... /// Accessors...
bool isRef() const { return AccessTy & Refs; } bool isRef() const { return AccessTy & Refs; }
@ -229,7 +235,7 @@ private:
void addCallSite(CallSite CS, AliasAnalysis &AA); void addCallSite(CallSite CS, AliasAnalysis &AA);
void removeCallSite(CallSite CS) { void removeCallSite(CallSite CS) {
for (size_t i = 0, e = CallSites.size(); i != e; ++i) for (size_t i = 0, e = CallSites.size(); i != e; ++i)
if (CallSites[i].getInstruction() == CS.getInstruction()) { if (CallSites[i] == CS.getInstruction()) {
CallSites[i] = CallSites.back(); CallSites[i] = CallSites.back();
CallSites.pop_back(); CallSites.pop_back();
} }

View File

@ -22,7 +22,7 @@ template <class Analysis, bool Simple>
struct DOTGraphTraitsViewer : public FunctionPass { struct DOTGraphTraitsViewer : public FunctionPass {
std::string Name; std::string Name;
DOTGraphTraitsViewer(std::string GraphName, const void *ID) : FunctionPass(ID) { DOTGraphTraitsViewer(std::string GraphName, char &ID) : FunctionPass(ID) {
Name = GraphName; Name = GraphName;
} }
@ -48,7 +48,7 @@ struct DOTGraphTraitsPrinter : public FunctionPass {
std::string Name; std::string Name;
DOTGraphTraitsPrinter(std::string GraphName, const void *ID) DOTGraphTraitsPrinter(std::string GraphName, char &ID)
: FunctionPass(ID) { : FunctionPass(ID) {
Name = GraphName; Name = GraphName;
} }

View File

@ -36,6 +36,12 @@ namespace llvm {
class LLVMContext; class LLVMContext;
class raw_ostream; class raw_ostream;
class DIFile;
class DISubprogram;
class DILexicalBlock;
class DIVariable;
class DIType;
/// DIDescriptor - A thin wraper around MDNode to access encoded debug info. /// DIDescriptor - A thin wraper around MDNode to access encoded debug info.
/// This should not be stored in a container, because underly MDNode may /// This should not be stored in a container, because underly MDNode may
/// change in certain situations. /// change in certain situations.
@ -56,11 +62,17 @@ namespace llvm {
} }
GlobalVariable *getGlobalVariableField(unsigned Elt) const; GlobalVariable *getGlobalVariableField(unsigned Elt) const;
Constant *getConstantField(unsigned Elt) const;
Function *getFunctionField(unsigned Elt) const; Function *getFunctionField(unsigned Elt) const;
public: public:
explicit DIDescriptor() : DbgNode(0) {} explicit DIDescriptor() : DbgNode(0) {}
explicit DIDescriptor(const MDNode *N) : DbgNode(N) {} explicit DIDescriptor(const MDNode *N) : DbgNode(N) {}
explicit DIDescriptor(const DIFile F);
explicit DIDescriptor(const DISubprogram F);
explicit DIDescriptor(const DILexicalBlock F);
explicit DIDescriptor(const DIVariable F);
explicit DIDescriptor(const DIType F);
bool Verify() const { return DbgNode != 0; } bool Verify() const { return DbgNode != 0; }
@ -134,7 +146,7 @@ namespace llvm {
public: public:
explicit DICompileUnit(const MDNode *N = 0) : DIScope(N) {} explicit DICompileUnit(const MDNode *N = 0) : DIScope(N) {}
unsigned getLanguage() const { return getUnsignedField(2); } unsigned getLanguage() const { return getUnsignedField(2); }
StringRef getFilename() const { return getStringField(3); } StringRef getFilename() const { return getStringField(3); }
StringRef getDirectory() const { return getStringField(4); } StringRef getDirectory() const { return getStringField(4); }
StringRef getProducer() const { return getStringField(5); } StringRef getProducer() const { return getStringField(5); }
@ -260,6 +272,10 @@ namespace llvm {
StringRef getFilename() const { return getCompileUnit().getFilename();} StringRef getFilename() const { return getCompileUnit().getFilename();}
StringRef getDirectory() const { return getCompileUnit().getDirectory();} StringRef getDirectory() const { return getCompileUnit().getDirectory();}
/// replaceAllUsesWith - Replace all uses of debug info referenced by
/// this descriptor.
void replaceAllUsesWith(DIDescriptor &D);
/// print - print type. /// print - print type.
void print(raw_ostream &OS) const; void print(raw_ostream &OS) const;
@ -274,6 +290,9 @@ namespace llvm {
unsigned getEncoding() const { return getUnsignedField(9); } unsigned getEncoding() const { return getUnsignedField(9); }
/// Verify - Verify that a basic type descriptor is well formed.
bool Verify() const;
/// print - print basic type. /// print - print basic type.
void print(raw_ostream &OS) const; void print(raw_ostream &OS) const;
@ -297,16 +316,14 @@ namespace llvm {
/// return base type size. /// return base type size.
uint64_t getOriginalTypeSize() const; uint64_t getOriginalTypeSize() const;
/// Verify - Verify that a derived type descriptor is well formed.
bool Verify() const;
/// print - print derived type. /// print - print derived type.
void print(raw_ostream &OS) const; void print(raw_ostream &OS) const;
/// dump - print derived type to dbgs() with a newline. /// dump - print derived type to dbgs() with a newline.
void dump() const; void dump() const;
/// replaceAllUsesWith - Replace all uses of debug info referenced by
/// this descriptor. After this completes, the current debug info value
/// is erased.
void replaceAllUsesWith(DIDescriptor &D);
}; };
/// DICompositeType - This descriptor holds a type that can refer to multiple /// DICompositeType - This descriptor holds a type that can refer to multiple
@ -437,6 +454,7 @@ namespace llvm {
unsigned isDefinition() const { return getUnsignedField(10); } unsigned isDefinition() const { return getUnsignedField(10); }
GlobalVariable *getGlobal() const { return getGlobalVariableField(11); } GlobalVariable *getGlobal() const { return getGlobalVariableField(11); }
Constant *getConstant() const { return getConstantField(11); }
/// Verify - Verify that a global variable descriptor is well formed. /// Verify - Verify that a global variable descriptor is well formed.
bool Verify() const; bool Verify() const;
@ -504,10 +522,18 @@ namespace llvm {
public: public:
explicit DILexicalBlock(const MDNode *N = 0) : DIScope(N) {} explicit DILexicalBlock(const MDNode *N = 0) : DIScope(N) {}
DIScope getContext() const { return getFieldAs<DIScope>(1); } 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 getLineNumber() const { return getUnsignedField(2); }
unsigned getColumnNumber() const { return getUnsignedField(3); } unsigned getColumnNumber() const { return getUnsignedField(3); }
StringRef getDirectory() const {
DIFile F = getFieldAs<DIFile>(4);
StringRef dir = F.getDirectory();
return !dir.empty() ? dir : getContext().getDirectory();
}
StringRef getFilename() const {
DIFile F = getFieldAs<DIFile>(4);
StringRef filename = F.getFilename();
return !filename.empty() ? filename : getContext().getFilename();
}
}; };
/// DINameSpace - A wrapper for a C++ style name space. /// DINameSpace - A wrapper for a C++ style name space.
@ -634,6 +660,9 @@ namespace llvm {
unsigned RunTimeLang = 0, unsigned RunTimeLang = 0,
MDNode *ContainingType = 0); MDNode *ContainingType = 0);
/// CreateTemporaryType - Create a temporary forward-declared type.
DIType CreateTemporaryType();
/// CreateArtificialType - Create a new DIType with "artificial" flag set. /// CreateArtificialType - Create a new DIType with "artificial" flag set.
DIType CreateArtificialType(DIType Ty); DIType CreateArtificialType(DIType Ty);
@ -648,7 +677,8 @@ namespace llvm {
unsigned Flags, unsigned Flags,
DIType DerivedFrom, DIType DerivedFrom,
DIArray Elements, DIArray Elements,
unsigned RunTimeLang = 0); unsigned RunTimeLang = 0,
MDNode *ContainingType = 0);
/// CreateSubprogram - Create a new descriptor for the specified subprogram. /// CreateSubprogram - Create a new descriptor for the specified subprogram.
/// See comments in DISubprogram for descriptions of these fields. /// See comments in DISubprogram for descriptions of these fields.
@ -678,6 +708,15 @@ namespace llvm {
unsigned LineNo, DIType Ty, bool isLocalToUnit, unsigned LineNo, DIType Ty, bool isLocalToUnit,
bool isDefinition, llvm::GlobalVariable *GV); bool isDefinition, llvm::GlobalVariable *GV);
/// CreateGlobalVariable - Create a new descriptor for the specified constant.
DIGlobalVariable
CreateGlobalVariable(DIDescriptor Context, StringRef Name,
StringRef DisplayName,
StringRef LinkageName,
DIFile F,
unsigned LineNo, DIType Ty, bool isLocalToUnit,
bool isDefinition, llvm::Constant *C);
/// CreateVariable - Create a new descriptor for the specified variable. /// CreateVariable - Create a new descriptor for the specified variable.
DIVariable CreateVariable(unsigned Tag, DIDescriptor Context, DIVariable CreateVariable(unsigned Tag, DIDescriptor Context,
StringRef Name, StringRef Name,
@ -694,8 +733,8 @@ namespace llvm {
/// CreateLexicalBlock - This creates a descriptor for a lexical block /// CreateLexicalBlock - This creates a descriptor for a lexical block
/// with the specified parent context. /// with the specified parent context.
DILexicalBlock CreateLexicalBlock(DIDescriptor Context, unsigned Line = 0, DILexicalBlock CreateLexicalBlock(DIDescriptor Context, DIFile F,
unsigned Col = 0); unsigned Line = 0, unsigned Col = 0);
/// CreateNameSpace - This creates new descriptor for a namespace /// CreateNameSpace - This creates new descriptor for a namespace
/// with the specified parent context. /// with the specified parent context.

View File

@ -702,7 +702,7 @@ public:
static char ID; // Pass ID, replacement for typeid static char ID; // Pass ID, replacement for typeid
DominatorTreeBase<BasicBlock>* DT; DominatorTreeBase<BasicBlock>* DT;
DominatorTree() : FunctionPass(&ID) { DominatorTree() : FunctionPass(ID) {
DT = new DominatorTreeBase<BasicBlock>(false); DT = new DominatorTreeBase<BasicBlock>(false);
} }
@ -890,7 +890,7 @@ protected:
const bool IsPostDominators; const bool IsPostDominators;
public: public:
DominanceFrontierBase(void *ID, bool isPostDom) DominanceFrontierBase(char &ID, bool isPostDom)
: FunctionPass(ID), IsPostDominators(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
@ -995,6 +995,9 @@ public:
/// print - Convert to human readable form /// print - Convert to human readable form
/// ///
virtual void print(raw_ostream &OS, const Module* = 0) const; virtual void print(raw_ostream &OS, const Module* = 0) const;
/// dump - Dump the dominance frontier to dbgs().
void dump() const;
}; };
@ -1006,7 +1009,7 @@ class DominanceFrontier : public DominanceFrontierBase {
public: public:
static char ID; // Pass ID, replacement for typeid static char ID; // Pass ID, replacement for typeid
DominanceFrontier() : DominanceFrontier() :
DominanceFrontierBase(&ID, false) {} DominanceFrontierBase(ID, false) {}
BasicBlock *getRoot() const { BasicBlock *getRoot() const {
assert(Roots.size() == 1 && "Should always have entry node!"); assert(Roots.size() == 1 && "Should always have entry node!");

View File

@ -26,7 +26,7 @@ class FindUsedTypes : public ModulePass {
std::set<const Type *> UsedTypes; std::set<const Type *> UsedTypes;
public: public:
static char ID; // Pass identification, replacement for typeid static char ID; // Pass identification, replacement for typeid
FindUsedTypes() : ModulePass(&ID) {} FindUsedTypes() : ModulePass(ID) {}
/// getTypes - After the pass has been run, return the set containing all of /// getTypes - After the pass has been run, return the set containing all of
/// the types used in the module. /// the types used in the module.

View File

@ -48,7 +48,7 @@ class IntervalPartition : public FunctionPass {
public: public:
static char ID; // Pass identification, replacement for typeid static char ID; // Pass identification, replacement for typeid
IntervalPartition() : FunctionPass(&ID), RootInterval(0) {} IntervalPartition() : FunctionPass(ID), RootInterval(0) {}
// run - Calculate the interval partition for this function // run - Calculate the interval partition for this function
virtual bool runOnFunction(Function &F); virtual bool runOnFunction(Function &F);

View File

@ -12,8 +12,8 @@
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_LIVEVALUES_H #ifndef LLVM_ANALYSIS_LAZYVALUEINFO_H
#define LLVM_ANALYSIS_LIVEVALUES_H #define LLVM_ANALYSIS_LAZYVALUEINFO_H
#include "llvm/Pass.h" #include "llvm/Pass.h"
@ -31,7 +31,7 @@ class LazyValueInfo : public FunctionPass {
void operator=(const LazyValueInfo&); // DO NOT IMPLEMENT. void operator=(const LazyValueInfo&); // DO NOT IMPLEMENT.
public: public:
static char ID; static char ID;
LazyValueInfo() : FunctionPass(&ID), PImpl(0) {} LazyValueInfo() : FunctionPass(ID), PImpl(0) {}
~LazyValueInfo() { assert(PImpl == 0 && "releaseMemory not called"); } ~LazyValueInfo() { assert(PImpl == 0 && "releaseMemory not called"); }
/// Tristate - This is used to return true/false/dunno results. /// Tristate - This is used to return true/false/dunno results.
@ -57,6 +57,12 @@ public:
/// constant on the specified edge. Return null if not. /// constant on the specified edge. Return null if not.
Constant *getConstantOnEdge(Value *V, BasicBlock *FromBB, BasicBlock *ToBB); Constant *getConstantOnEdge(Value *V, BasicBlock *FromBB, BasicBlock *ToBB);
/// threadEdge - Inform the analysis cache that we have threaded an edge from
/// PredBB to OldSucc to be from PredBB to NewSucc instead.
void threadEdge(BasicBlock *PredBB, BasicBlock *OldSucc, BasicBlock *NewSucc);
/// eraseBlock - Inform the analysis cache that we have erased a block.
void eraseBlock(BasicBlock *BB);
// Implementation boilerplate. // Implementation boilerplate.

View File

@ -28,18 +28,20 @@ namespace llvm {
LibCallInfo *LCI; LibCallInfo *LCI;
explicit LibCallAliasAnalysis(LibCallInfo *LC = 0) explicit LibCallAliasAnalysis(LibCallInfo *LC = 0)
: FunctionPass(&ID), LCI(LC) { : FunctionPass(ID), LCI(LC) {
} }
explicit LibCallAliasAnalysis(const void *ID, LibCallInfo *LC) explicit LibCallAliasAnalysis(char &ID, LibCallInfo *LC)
: FunctionPass(ID), LCI(LC) { : FunctionPass(ID), LCI(LC) {
} }
~LibCallAliasAnalysis(); ~LibCallAliasAnalysis();
ModRefResult getModRefInfo(CallSite CS, Value *P, unsigned Size); ModRefResult getModRefInfo(ImmutableCallSite CS,
const Value *P, unsigned Size);
ModRefResult getModRefInfo(CallSite CS1, CallSite CS2) { ModRefResult getModRefInfo(ImmutableCallSite CS1,
ImmutableCallSite CS2) {
// TODO: Could compare two direct calls against each other if we cared to. // TODO: Could compare two direct calls against each other if we cared to.
return AliasAnalysis::getModRefInfo(CS1,CS2); return AliasAnalysis::getModRefInfo(CS1, CS2);
} }
virtual void getAnalysisUsage(AnalysisUsage &AU) const; virtual void getAnalysisUsage(AnalysisUsage &AU) const;
@ -49,9 +51,20 @@ namespace llvm {
return false; return false;
} }
/// getAdjustedAnalysisPointer - This method is used when a pass implements
/// an analysis interface through multiple inheritance. If needed, it
/// should override this to adjust the this pointer as needed for the
/// specified pass info.
virtual void *getAdjustedAnalysisPointer(const void *PI) {
if (PI == &AliasAnalysis::ID)
return (AliasAnalysis*)this;
return this;
}
private: private:
ModRefResult AnalyzeLibCallDetails(const LibCallFunctionInfo *FI, ModRefResult AnalyzeLibCallDetails(const LibCallFunctionInfo *FI,
CallSite CS, Value *P, unsigned Size); ImmutableCallSite CS,
const Value *P, unsigned Size);
}; };
} // End of llvm namespace } // End of llvm namespace

View File

@ -47,7 +47,8 @@ namespace llvm {
enum LocResult { enum LocResult {
Yes, No, Unknown Yes, No, Unknown
}; };
LocResult (*isLocation)(CallSite CS, const Value *Ptr, unsigned Size); LocResult (*isLocation)(ImmutableCallSite CS,
const Value *Ptr, unsigned Size);
}; };
/// LibCallFunctionInfo - Each record in the array of FunctionInfo structs /// LibCallFunctionInfo - Each record in the array of FunctionInfo structs
@ -142,7 +143,7 @@ namespace llvm {
/// getFunctionInfo - Return the LibCallFunctionInfo object corresponding to /// getFunctionInfo - Return the LibCallFunctionInfo object corresponding to
/// the specified function if we have it. If not, return null. /// the specified function if we have it. If not, return null.
const LibCallFunctionInfo *getFunctionInfo(Function *F) const; const LibCallFunctionInfo *getFunctionInfo(const Function *F) const;
//===------------------------------------------------------------------===// //===------------------------------------------------------------------===//

View File

@ -91,7 +91,7 @@ class LoopDependenceAnalysis : public LoopPass {
public: public:
static char ID; // Class identification, replacement for typeinfo static char ID; // Class identification, replacement for typeinfo
LoopDependenceAnalysis() : LoopPass(&ID) {} LoopDependenceAnalysis() : LoopPass(ID) {}
/// isDependencePair - Check whether two values can possibly give rise to /// isDependencePair - Check whether two values can possibly give rise to
/// a data dependence: that is the case if both are instructions accessing /// a data dependence: that is the case if both are instructions accessing

View File

@ -35,6 +35,7 @@
#include "llvm/ADT/DepthFirstIterator.h" #include "llvm/ADT/DepthFirstIterator.h"
#include "llvm/ADT/GraphTraits.h" #include "llvm/ADT/GraphTraits.h"
#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Analysis/Dominators.h" #include "llvm/Analysis/Dominators.h"
#include "llvm/Support/CFG.h" #include "llvm/Support/CFG.h"
#include "llvm/Support/raw_ostream.h" #include "llvm/Support/raw_ostream.h"
@ -229,13 +230,16 @@ public:
return 0; return 0;
} }
/// Edge type.
typedef std::pair<BlockT*, BlockT*> Edge;
/// getExitEdges - Return all pairs of (_inside_block_,_outside_block_). /// getExitEdges - Return all pairs of (_inside_block_,_outside_block_).
typedef std::pair<const BlockT*,const BlockT*> Edge; template <typename EdgeT>
void getExitEdges(SmallVectorImpl<Edge> &ExitEdges) const { void getExitEdges(SmallVectorImpl<EdgeT> &ExitEdges) const {
// Sort the blocks vector so that we can use binary search to do quick // Sort the blocks vector so that we can use binary search to do quick
// lookups. // lookups.
SmallVector<BlockT*, 128> LoopBBs(block_begin(), block_end()); SmallVector<BlockT*, 128> LoopBBs(block_begin(), block_end());
std::sort(LoopBBs.begin(), LoopBBs.end()); array_pod_sort(LoopBBs.begin(), LoopBBs.end());
typedef GraphTraits<BlockT*> BlockTraits; typedef GraphTraits<BlockT*> BlockTraits;
for (block_iterator BI = block_begin(), BE = block_end(); BI != BE; ++BI) for (block_iterator BI = block_begin(), BE = block_end(); BI != BE; ++BI)
@ -244,7 +248,7 @@ public:
I != E; ++I) I != E; ++I)
if (!std::binary_search(LoopBBs.begin(), LoopBBs.end(), *I)) if (!std::binary_search(LoopBBs.begin(), LoopBBs.end(), *I))
// Not in current loop? It must be an exit block. // Not in current loop? It must be an exit block.
ExitEdges.push_back(std::make_pair(*BI, *I)); ExitEdges.push_back(EdgeT(*BI, *I));
} }
/// getLoopPreheader - If there is a preheader for this loop, return it. A /// getLoopPreheader - If there is a preheader for this loop, return it. A
@ -505,6 +509,12 @@ protected:
} }
}; };
template<class BlockT, class LoopT>
raw_ostream& operator<<(raw_ostream &OS, const LoopBase<BlockT, LoopT> &Loop) {
Loop.print(OS);
return OS;
}
class Loop : public LoopBase<BasicBlock, Loop> { class Loop : public LoopBase<BasicBlock, Loop> {
public: public:
Loop() {} Loop() {}
@ -552,12 +562,6 @@ public:
/// ///
PHINode *getCanonicalInductionVariable() const; PHINode *getCanonicalInductionVariable() const;
/// getCanonicalInductionVariableIncrement - Return the LLVM value that holds
/// the canonical induction variable value for the "next" iteration of the
/// loop. This always succeeds if getCanonicalInductionVariable succeeds.
///
Instruction *getCanonicalInductionVariableIncrement() const;
/// getTripCount - Return a loop-invariant LLVM value indicating the number of /// getTripCount - Return a loop-invariant LLVM value indicating the number of
/// times the loop will be executed. Note that this means that the backedge /// times the loop will be executed. Note that this means that the backedge
/// of the loop executes N-1 times. If the trip-count cannot be determined, /// of the loop executes N-1 times. If the trip-count cannot be determined,
@ -936,7 +940,7 @@ class LoopInfo : public FunctionPass {
public: public:
static char ID; // Pass identification, replacement for typeid static char ID; // Pass identification, replacement for typeid
LoopInfo() : FunctionPass(&ID) {} LoopInfo() : FunctionPass(ID) {}
LoopInfoBase<BasicBlock, Loop>& getBase() { return LI; } LoopInfoBase<BasicBlock, Loop>& getBase() { return LI; }

View File

@ -19,6 +19,7 @@
#include "llvm/Pass.h" #include "llvm/Pass.h"
#include "llvm/PassManagers.h" #include "llvm/PassManagers.h"
#include "llvm/Function.h" #include "llvm/Function.h"
#include <deque>
namespace llvm { namespace llvm {
@ -28,8 +29,7 @@ class PMStack;
class LoopPass : public Pass { class LoopPass : public Pass {
public: public:
explicit LoopPass(intptr_t pid) : Pass(PT_Loop, pid) {} explicit LoopPass(char &pid) : Pass(PT_Loop, pid) {}
explicit LoopPass(void *pid) : Pass(PT_Loop, pid) {}
/// getPrinterPass - Get a pass to print the function corresponding /// getPrinterPass - Get a pass to print the function corresponding
/// to a Loop. /// to a Loop.
@ -58,7 +58,7 @@ public:
/// Assign pass manager to manage this pass /// Assign pass manager to manage this pass
virtual void assignPassManager(PMStack &PMS, virtual void assignPassManager(PMStack &PMS,
PassManagerType PMT = PMT_LoopPassManager); PassManagerType PMT);
/// Return what kind of Pass Manager can manage this pass. /// Return what kind of Pass Manager can manage this pass.
virtual PassManagerType getPotentialPassManagerType() const { virtual PassManagerType getPotentialPassManagerType() const {
@ -104,10 +104,10 @@ public:
/// Print passes managed by this manager /// Print passes managed by this manager
void dumpPassStructure(unsigned Offset); void dumpPassStructure(unsigned Offset);
Pass *getContainedPass(unsigned N) { LoopPass *getContainedPass(unsigned N) {
assert(N < PassVector.size() && "Pass number out of range!"); assert(N < PassVector.size() && "Pass number out of range!");
Pass *FP = static_cast<Pass *>(PassVector[N]); LoopPass *LP = static_cast<LoopPass *>(PassVector[N]);
return FP; return LP;
} }
virtual PassManagerType getPassManagerType() const { virtual PassManagerType getPassManagerType() const {

View File

@ -79,13 +79,20 @@ namespace llvm {
// //
FunctionPass *createScalarEvolutionAliasAnalysisPass(); FunctionPass *createScalarEvolutionAliasAnalysisPass();
//===--------------------------------------------------------------------===//
//
// createTypeBasedAliasAnalysisPass - This pass implements metadata-based
// type-based alias analysis.
//
ImmutablePass *createTypeBasedAliasAnalysisPass();
//===--------------------------------------------------------------------===// //===--------------------------------------------------------------------===//
// //
// createProfileLoaderPass - This pass loads information from a profile dump // createProfileLoaderPass - This pass loads information from a profile dump
// file. // file.
// //
ModulePass *createProfileLoaderPass(); ModulePass *createProfileLoaderPass();
extern const PassInfo *ProfileLoaderPassID; extern char &ProfileLoaderPassID;
//===--------------------------------------------------------------------===// //===--------------------------------------------------------------------===//
// //
@ -99,7 +106,7 @@ namespace llvm {
// instead of loading it from a previous run. // instead of loading it from a previous run.
// //
FunctionPass *createProfileEstimatorPass(); FunctionPass *createProfileEstimatorPass();
extern const PassInfo *ProfileEstimatorPassID; extern char &ProfileEstimatorPassID;
//===--------------------------------------------------------------------===// //===--------------------------------------------------------------------===//
// //
@ -154,6 +161,13 @@ namespace llvm {
// print debug info intrinsics in human readable form // print debug info intrinsics in human readable form
FunctionPass *createDbgInfoPrinterPass(); FunctionPass *createDbgInfoPrinterPass();
//===--------------------------------------------------------------------===//
//
// createRegionInfoPass - This pass finds all single entry single exit regions
// in a function and builds the region hierarchy.
//
FunctionPass *createRegionInfoPass();
// Print module-level debug info metadata in human-readable form. // Print module-level debug info metadata in human-readable form.
ModulePass *createModuleDebugInfoPrinterPass(); ModulePass *createModuleDebugInfoPrinterPass();
} }

View File

@ -98,6 +98,7 @@ namespace llvm {
virtual bool runOnFunction(Function &F); virtual bool runOnFunction(Function &F);
virtual void getAnalysisUsage(AnalysisUsage &AU) const; virtual void getAnalysisUsage(AnalysisUsage &AU) const;
void print(raw_ostream &OS, const Module* = 0) const; void print(raw_ostream &OS, const Module* = 0) const;
Value *computeAllocationCountValue(Value *P, const Type *&Ty) const;
private: private:
Function *FF; Function *FF;
TargetData *TD; TargetData *TD;

View File

@ -25,7 +25,7 @@ struct PostDominatorTree : public FunctionPass {
static char ID; // Pass identification, replacement for typeid static char ID; // Pass identification, replacement for typeid
DominatorTreeBase<BasicBlock>* DT; DominatorTreeBase<BasicBlock>* DT;
PostDominatorTree() : FunctionPass(&ID) { PostDominatorTree() : FunctionPass(ID) {
DT = new DominatorTreeBase<BasicBlock>(true); DT = new DominatorTreeBase<BasicBlock>(true);
} }
@ -106,7 +106,7 @@ template <> struct GraphTraits<PostDominatorTree*>
struct PostDominanceFrontier : public DominanceFrontierBase { struct PostDominanceFrontier : public DominanceFrontierBase {
static char ID; static char ID;
PostDominanceFrontier() PostDominanceFrontier()
: DominanceFrontierBase(&ID, true) {} : DominanceFrontierBase(ID, true) {}
virtual bool runOnFunction(Function &) { virtual bool runOnFunction(Function &) {
Frontiers.clear(); Frontiers.clear();

View File

@ -0,0 +1,630 @@
//===- RegionInfo.h - SESE region analysis ----------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Calculate a program structure tree built out of single entry single exit
// regions.
// The basic ideas are taken from "The Program Structure Tree - Richard Johnson,
// David Pearson, Keshav Pingali - 1994", however enriched with ideas from "The
// Refined Process Structure Tree - Jussi Vanhatalo, Hagen Voelyer, Jana
// Koehler - 2009".
// The algorithm to calculate these data structures however is completely
// different, as it takes advantage of existing information already available
// in (Post)dominace tree and dominance frontier passes. This leads to a simpler
// and in practice hopefully better performing algorithm. The runtime of the
// algorithms described in the papers above are both linear in graph size,
// O(V+E), whereas this algorithm is not, as the dominance frontier information
// itself is not, but in practice runtime seems to be in the order of magnitude
// of dominance tree calculation.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_REGION_INFO_H
#define LLVM_ANALYSIS_REGION_INFO_H
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/Analysis/Dominators.h"
#include "llvm/Analysis/PostDominators.h"
#include "llvm/Support/Allocator.h"
namespace llvm {
class Region;
class RegionInfo;
class raw_ostream;
class Loop;
class LoopInfo;
/// @brief Marker class to iterate over the elements of a Region in flat mode.
///
/// The class is used to either iterate in Flat mode or by not using it to not
/// iterate in Flat mode. During a Flat mode iteration all Regions are entered
/// and the iteration returns every BasicBlock. If the Flat mode is not
/// selected for SubRegions just one RegionNode containing the subregion is
/// returned.
template <class GraphType>
class FlatIt {};
/// @brief A RegionNode represents a subregion or a BasicBlock that is part of a
/// Region.
class RegionNode {
// DO NOT IMPLEMENT
RegionNode(const RegionNode &);
// DO NOT IMPLEMENT
const RegionNode &operator=(const RegionNode &);
/// This is the entry basic block that starts this region node. If this is a
/// BasicBlock RegionNode, then entry is just the basic block, that this
/// RegionNode represents. Otherwise it is the entry of this (Sub)RegionNode.
///
/// In the BBtoRegionNode map of the parent of this node, BB will always map
/// to this node no matter which kind of node this one is.
///
/// The node can hold either a Region or a BasicBlock.
/// Use one bit to save, if this RegionNode is a subregion or BasicBlock
/// RegionNode.
PointerIntPair<BasicBlock*, 1, bool> entry;
protected:
/// @brief The parent Region of this RegionNode.
/// @see getParent()
Region* parent;
public:
/// @brief Create a RegionNode.
///
/// @param Parent The parent of this RegionNode.
/// @param Entry The entry BasicBlock of the RegionNode. If this
/// RegionNode represents a BasicBlock, this is the
/// BasicBlock itself. If it represents a subregion, this
/// is the entry BasicBlock of the subregion.
/// @param isSubRegion If this RegionNode represents a SubRegion.
inline RegionNode(Region* Parent, BasicBlock* Entry, bool isSubRegion = 0)
: entry(Entry, isSubRegion), parent(Parent) {}
/// @brief Get the parent Region of this RegionNode.
///
/// The parent Region is the Region this RegionNode belongs to. If for
/// example a BasicBlock is element of two Regions, there exist two
/// RegionNodes for this BasicBlock. Each with the getParent() function
/// pointing to the Region this RegionNode belongs to.
///
/// @return Get the parent Region of this RegionNode.
inline Region* getParent() const { return parent; }
/// @brief Get the entry BasicBlock of this RegionNode.
///
/// If this RegionNode represents a BasicBlock this is just the BasicBlock
/// itself, otherwise we return the entry BasicBlock of the Subregion
///
/// @return The entry BasicBlock of this RegionNode.
inline BasicBlock* getEntry() const { return entry.getPointer(); }
/// @brief Get the content of this RegionNode.
///
/// This can be either a BasicBlock or a subregion. Before calling getNodeAs()
/// check the type of the content with the isSubRegion() function call.
///
/// @return The content of this RegionNode.
template<class T>
inline T* getNodeAs() const;
/// @brief Is this RegionNode a subregion?
///
/// @return True if it contains a subregion. False if it contains a
/// BasicBlock.
inline bool isSubRegion() const {
return entry.getInt();
}
};
/// Print a RegionNode.
inline raw_ostream &operator<<(raw_ostream &OS, const RegionNode &Node);
template<>
inline BasicBlock* RegionNode::getNodeAs<BasicBlock>() const {
assert(!isSubRegion() && "This is not a BasicBlock RegionNode!");
return getEntry();
}
template<>
inline Region* RegionNode::getNodeAs<Region>() const {
assert(isSubRegion() && "This is not a subregion RegionNode!");
return reinterpret_cast<Region*>(const_cast<RegionNode*>(this));
}
//===----------------------------------------------------------------------===//
/// @brief A single entry single exit Region.
///
/// A Region is a connected subgraph of a control flow graph that has exactly
/// two connections to the remaining graph. It can be used to analyze or
/// optimize parts of the control flow graph.
///
/// A <em> simple Region </em> is connected to the remaing graph by just two
/// edges. One edge entering the Region and another one leaving the Region.
///
/// An <em> extended Region </em> (or just Region) is a subgraph that can be
/// transform into a simple Region. The transformation is done by adding
/// BasicBlocks that merge several entry or exit edges so that after the merge
/// just one entry and one exit edge exists.
///
/// The \e Entry of a Region is the first BasicBlock that is passed after
/// entering the Region. It is an element of the Region. The entry BasicBlock
/// dominates all BasicBlocks in the Region.
///
/// The \e Exit of a Region is the first BasicBlock that is passed after
/// leaving the Region. It is not an element of the Region. The exit BasicBlock,
/// postdominates all BasicBlocks in the Region.
///
/// A <em> canonical Region </em> cannot be constructed by combining smaller
/// Regions.
///
/// Region A is the \e parent of Region B, if B is completely contained in A.
///
/// Two canonical Regions either do not intersect at all or one is
/// the parent of the other.
///
/// The <em> Program Structure Tree</em> is a graph (V, E) where V is the set of
/// Regions in the control flow graph and E is the \e parent relation of these
/// Regions.
///
/// Example:
///
/// \verbatim
/// A simple control flow graph, that contains two regions.
///
/// 1
/// / |
/// 2 |
/// / \ 3
/// 4 5 |
/// | | |
/// 6 7 8
/// \ | /
/// \ |/ Region A: 1 -> 9 {1,2,3,4,5,6,7,8}
/// 9 Region B: 2 -> 9 {2,4,5,6,7}
/// \endverbatim
///
/// You can obtain more examples by either calling
///
/// <tt> "opt -regions -analyze anyprogram.ll" </tt>
/// or
/// <tt> "opt -view-regions-only anyprogram.ll" </tt>
///
/// on any LLVM file you are interested in.
///
/// The first call returns a textual representation of the program structure
/// tree, the second one creates a graphical representation using graphviz.
class Region : public RegionNode {
friend class RegionInfo;
// DO NOT IMPLEMENT
Region(const Region &);
// DO NOT IMPLEMENT
const Region &operator=(const Region &);
// Information necessary to manage this Region.
RegionInfo* RI;
DominatorTree *DT;
// The exit BasicBlock of this region.
// (The entry BasicBlock is part of RegionNode)
BasicBlock *exit;
typedef std::vector<Region*> RegionSet;
// The subregions of this region.
RegionSet children;
typedef std::map<BasicBlock*, RegionNode*> BBNodeMapT;
// Save the BasicBlock RegionNodes that are element of this Region.
mutable BBNodeMapT BBNodeMap;
/// verifyBBInRegion - Check if a BB is in this Region. This check also works
/// if the region is incorrectly built. (EXPENSIVE!)
void verifyBBInRegion(BasicBlock* BB) const;
/// verifyWalk - Walk over all the BBs of the region starting from BB and
/// verify that all reachable basic blocks are elements of the region.
/// (EXPENSIVE!)
void verifyWalk(BasicBlock* BB, std::set<BasicBlock*>* visitedBB) const;
/// verifyRegionNest - Verify if the region and its children are valid
/// regions (EXPENSIVE!)
void verifyRegionNest() const;
public:
/// @brief Create a new region.
///
/// @param Entry The entry basic block of the region.
/// @param Exit The exit basic block of the region.
/// @param RI The region info object that is managing this region.
/// @param DT The dominator tree of the current function.
/// @param Parent The surrounding region or NULL if this is a top level
/// region.
Region(BasicBlock *Entry, BasicBlock *Exit, RegionInfo* RI,
DominatorTree *DT, Region *Parent = 0);
/// Delete the Region and all its subregions.
~Region();
/// @brief Get the entry BasicBlock of the Region.
/// @return The entry BasicBlock of the region.
BasicBlock *getEntry() const { return RegionNode::getEntry(); }
/// @brief Get the exit BasicBlock of the Region.
/// @return The exit BasicBlock of the Region, NULL if this is the TopLevel
/// Region.
BasicBlock *getExit() const { return exit; }
/// @brief Get the parent of the Region.
/// @return The parent of the Region or NULL if this is a top level
/// Region.
Region *getParent() const { return RegionNode::getParent(); }
/// @brief Get the RegionNode representing the current Region.
/// @return The RegionNode representing the current Region.
RegionNode* getNode() const {
return const_cast<RegionNode*>(reinterpret_cast<const RegionNode*>(this));
}
/// @brief Get the nesting level of this Region.
///
/// An toplevel Region has depth 0.
///
/// @return The depth of the region.
unsigned getDepth() const;
/// @brief Is this a simple region?
///
/// A region is simple if it has exactly one exit and one entry edge.
///
/// @return True if the Region is simple.
bool isSimple() const;
/// @brief Returns the name of the Region.
/// @return The Name of the Region.
std::string getNameStr() const;
/// @brief Return the RegionInfo object, that belongs to this Region.
RegionInfo *getRegionInfo() const {
return RI;
}
/// @brief Print the region.
///
/// @param OS The output stream the Region is printed to.
/// @param printTree Print also the tree of subregions.
/// @param level The indentation level used for printing.
void print(raw_ostream& OS, bool printTree = true, unsigned level = 0) const;
/// @brief Print the region to stderr.
void dump() const;
/// @brief Check if the region contains a BasicBlock.
///
/// @param BB The BasicBlock that might be contained in this Region.
/// @return True if the block is contained in the region otherwise false.
bool contains(const BasicBlock *BB) const;
/// @brief Check if the region contains another region.
///
/// @param SubRegion The region that might be contained in this Region.
/// @return True if SubRegion is contained in the region otherwise false.
bool contains(const Region *SubRegion) const {
// Toplevel Region.
if (!getExit())
return true;
return contains(SubRegion->getEntry())
&& (contains(SubRegion->getExit()) || SubRegion->getExit() == getExit());
}
/// @brief Check if the region contains an Instruction.
///
/// @param Inst The Instruction that might be contained in this region.
/// @return True if the Instruction is contained in the region otherwise false.
bool contains(const Instruction *Inst) const {
return contains(Inst->getParent());
}
/// @brief Check if the region contains a loop.
///
/// @param L The loop that might be contained in this region.
/// @return True if the loop is contained in the region otherwise false.
/// In case a NULL pointer is passed to this function the result
/// is false, except for the region that describes the whole function.
/// In that case true is returned.
bool contains(const Loop *L) const;
/// @brief Get the outermost loop in the region that contains a loop.
///
/// Find for a Loop L the outermost loop OuterL that is a parent loop of L
/// and is itself contained in the region.
///
/// @param L The loop the lookup is started.
/// @return The outermost loop in the region, NULL if such a loop does not
/// exist or if the region describes the whole function.
Loop *outermostLoopInRegion(Loop *L) const;
/// @brief Get the outermost loop in the region that contains a basic block.
///
/// Find for a basic block BB the outermost loop L that contains BB and is
/// itself contained in the region.
///
/// @param LI A pointer to a LoopInfo analysis.
/// @param BB The basic block surrounded by the loop.
/// @return The outermost loop in the region, NULL if such a loop does not
/// exist or if the region describes the whole function.
Loop *outermostLoopInRegion(LoopInfo *LI, BasicBlock* BB) const;
/// @brief Get the subregion that starts at a BasicBlock
///
/// @param BB The BasicBlock the subregion should start.
/// @return The Subregion if available, otherwise NULL.
Region* getSubRegionNode(BasicBlock *BB) const;
/// @brief Get the RegionNode for a BasicBlock
///
/// @param BB The BasicBlock at which the RegionNode should start.
/// @return If available, the RegionNode that represents the subregion
/// starting at BB. If no subregion starts at BB, the RegionNode
/// representing BB.
RegionNode* getNode(BasicBlock *BB) const;
/// @brief Get the BasicBlock RegionNode for a BasicBlock
///
/// @param BB The BasicBlock for which the RegionNode is requested.
/// @return The RegionNode representing the BB.
RegionNode* getBBNode(BasicBlock *BB) const;
/// @brief Add a new subregion to this Region.
///
/// @param SubRegion The new subregion that will be added.
void addSubRegion(Region *SubRegion);
/// @brief Remove a subregion from this Region.
///
/// The subregion is not deleted, as it will probably be inserted into another
/// region.
/// @param SubRegion The SubRegion that will be removed.
Region *removeSubRegion(Region *SubRegion);
/// @brief Move all direct child nodes of this Region to another Region.
///
/// @param To The Region the child nodes will be transfered to.
void transferChildrenTo(Region *To);
/// @brief Verify if the region is a correct region.
///
/// Check if this is a correctly build Region. This is an expensive check, as
/// the complete CFG of the Region will be walked.
void verifyRegion() const;
/// @brief Clear the cache for BB RegionNodes.
///
/// After calling this function the BasicBlock RegionNodes will be stored at
/// different memory locations. RegionNodes obtained before this function is
/// called are therefore not comparable to RegionNodes abtained afterwords.
void clearNodeCache();
/// @name Subregion Iterators
///
/// These iterators iterator over all subregions of this Region.
//@{
typedef RegionSet::iterator iterator;
typedef RegionSet::const_iterator const_iterator;
iterator begin() { return children.begin(); }
iterator end() { return children.end(); }
const_iterator begin() const { return children.begin(); }
const_iterator end() const { return children.end(); }
//@}
/// @name BasicBlock Iterators
///
/// These iterators iterate over all BasicBlock RegionNodes that are
/// contained in this Region. The iterator also iterates over BasicBlocks
/// that are elements of a subregion of this Region. It is therefore called a
/// flat iterator.
//@{
typedef df_iterator<RegionNode*, SmallPtrSet<RegionNode*, 8>, false,
GraphTraits<FlatIt<RegionNode*> > > block_iterator;
typedef df_iterator<const RegionNode*, SmallPtrSet<const RegionNode*, 8>,
false, GraphTraits<FlatIt<const RegionNode*> > >
const_block_iterator;
block_iterator block_begin();
block_iterator block_end();
const_block_iterator block_begin() const;
const_block_iterator block_end() const;
//@}
/// @name Element Iterators
///
/// These iterators iterate over all BasicBlock and subregion RegionNodes that
/// are direct children of this Region. It does not iterate over any
/// RegionNodes that are also element of a subregion of this Region.
//@{
typedef df_iterator<RegionNode*, SmallPtrSet<RegionNode*, 8>, false,
GraphTraits<RegionNode*> > element_iterator;
typedef df_iterator<const RegionNode*, SmallPtrSet<const RegionNode*, 8>,
false, GraphTraits<const RegionNode*> >
const_element_iterator;
element_iterator element_begin();
element_iterator element_end();
const_element_iterator element_begin() const;
const_element_iterator element_end() const;
//@}
};
//===----------------------------------------------------------------------===//
/// @brief Analysis that detects all canonical Regions.
///
/// The RegionInfo pass detects all canonical regions in a function. The Regions
/// are connected using the parent relation. This builds a Program Structure
/// Tree.
class RegionInfo : public FunctionPass {
typedef DenseMap<BasicBlock*,BasicBlock*> BBtoBBMap;
typedef DenseMap<BasicBlock*, Region*> BBtoRegionMap;
typedef SmallPtrSet<Region*, 4> RegionSet;
// DO NOT IMPLEMENT
RegionInfo(const RegionInfo &);
// DO NOT IMPLEMENT
const RegionInfo &operator=(const RegionInfo &);
DominatorTree *DT;
PostDominatorTree *PDT;
DominanceFrontier *DF;
/// The top level region.
Region *TopLevelRegion;
/// Map every BB to the smallest region, that contains BB.
BBtoRegionMap BBtoRegion;
// isCommonDomFrontier - Returns true if BB is in the dominance frontier of
// entry, because it was inherited from exit. In the other case there is an
// edge going from entry to BB without passing exit.
bool isCommonDomFrontier(BasicBlock* BB, BasicBlock* entry,
BasicBlock* exit) const;
// isRegion - Check if entry and exit surround a valid region, based on
// dominance tree and dominance frontier.
bool isRegion(BasicBlock* entry, BasicBlock* exit) const;
// insertShortCut - Saves a shortcut pointing from entry to exit.
// This function may extend this shortcut if possible.
void insertShortCut(BasicBlock* entry, BasicBlock* exit,
BBtoBBMap* ShortCut) const;
// getNextPostDom - Returns the next BB that postdominates N, while skipping
// all post dominators that cannot finish a canonical region.
DomTreeNode *getNextPostDom(DomTreeNode* N, BBtoBBMap *ShortCut) const;
// isTrivialRegion - A region is trivial, if it contains only one BB.
bool isTrivialRegion(BasicBlock *entry, BasicBlock *exit) const;
// createRegion - Creates a single entry single exit region.
Region *createRegion(BasicBlock *entry, BasicBlock *exit);
// findRegionsWithEntry - Detect all regions starting with bb 'entry'.
void findRegionsWithEntry(BasicBlock *entry, BBtoBBMap *ShortCut);
// scanForRegions - Detects regions in F.
void scanForRegions(Function &F, BBtoBBMap *ShortCut);
// getTopMostParent - Get the top most parent with the same entry block.
Region *getTopMostParent(Region *region);
// buildRegionsTree - build the region hierarchy after all region detected.
void buildRegionsTree(DomTreeNode *N, Region *region);
// Calculate - detecte all regions in function and build the region tree.
void Calculate(Function& F);
void releaseMemory();
// updateStatistics - Update statistic about created regions.
void updateStatistics(Region *R);
// isSimple - Check if a region is a simple region with exactly one entry
// edge and exactly one exit edge.
bool isSimple(Region* R) const;
public:
static char ID;
explicit RegionInfo();
~RegionInfo();
/// @name FunctionPass interface
//@{
virtual bool runOnFunction(Function &F);
virtual void getAnalysisUsage(AnalysisUsage &AU) const;
virtual void print(raw_ostream &OS, const Module *) const;
virtual void verifyAnalysis() const;
//@}
/// @brief Get the smallest region that contains a BasicBlock.
///
/// @param BB The basic block.
/// @return The smallest region, that contains BB or NULL, if there is no
/// region containing BB.
Region *getRegionFor(BasicBlock *BB) const;
/// @brief A shortcut for getRegionFor().
///
/// @param BB The basic block.
/// @return The smallest region, that contains BB or NULL, if there is no
/// region containing BB.
Region *operator[](BasicBlock *BB) const;
/// @brief Return the exit of the maximal refined region, that starts at a
/// BasicBlock.
///
/// @param BB The BasicBlock the refined region starts.
BasicBlock *getMaxRegionExit(BasicBlock *BB) const;
/// @brief Find the smallest region that contains two regions.
///
/// @param A The first region.
/// @param B The second region.
/// @return The smallest region containing A and B.
Region *getCommonRegion(Region* A, Region *B) const;
/// @brief Find the smallest region that contains two basic blocks.
///
/// @param A The first basic block.
/// @param B The second basic block.
/// @return The smallest region that contains A and B.
Region* getCommonRegion(BasicBlock* A, BasicBlock *B) const {
return getCommonRegion(getRegionFor(A), getRegionFor(B));
}
/// @brief Find the smallest region that contains a set of regions.
///
/// @param Regions A vector of regions.
/// @return The smallest region that contains all regions in Regions.
Region* getCommonRegion(SmallVectorImpl<Region*> &Regions) const;
/// @brief Find the smallest region that contains a set of basic blocks.
///
/// @param BBs A vector of basic blocks.
/// @return The smallest region that contains all basic blocks in BBS.
Region* getCommonRegion(SmallVectorImpl<BasicBlock*> &BBs) const;
Region *getTopLevelRegion() const {
return TopLevelRegion;
}
/// @brief Clear the Node Cache for all Regions.
///
/// @see Region::clearNodeCache()
void clearNodeCache() {
if (TopLevelRegion)
TopLevelRegion->clearNodeCache();
}
};
inline raw_ostream &operator<<(raw_ostream &OS, const RegionNode &Node) {
if (Node.isSubRegion())
return OS << Node.getNodeAs<Region>()->getNameStr();
else
return OS << Node.getNodeAs<BasicBlock>()->getNameStr();
}
} // End llvm namespace
#endif

View File

@ -0,0 +1,342 @@
//===- RegionIterator.h - Iterators to iteratate over Regions ---*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// This file defines the iterators to iterate over the elements of a Region.
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_REGION_ITERATOR_H
#define LLVM_ANALYSIS_REGION_ITERATOR_H
#include "llvm/ADT/GraphTraits.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/Analysis/RegionInfo.h"
#include "llvm/Support/CFG.h"
#include "llvm/Support/raw_ostream.h"
namespace llvm {
//===----------------------------------------------------------------------===//
/// @brief Hierachical RegionNode successor iterator.
///
/// This iterator iterates over all successors of a RegionNode.
///
/// For a BasicBlock RegionNode it skips all BasicBlocks that are not part of
/// the parent Region. Furthermore for BasicBlocks that start a subregion, a
/// RegionNode representing the subregion is returned.
///
/// For a subregion RegionNode there is just one successor. The RegionNode
/// representing the exit of the subregion.
template<class NodeType>
class RNSuccIterator : public std::iterator<std::forward_iterator_tag,
NodeType, ptrdiff_t>
{
typedef std::iterator<std::forward_iterator_tag, NodeType, ptrdiff_t> super;
// The iterator works in two modes, bb mode or region mode.
enum ItMode{
// In BB mode it returns all successors of this BasicBlock as its
// successors.
ItBB,
// In region mode there is only one successor, thats the regionnode mapping
// to the exit block of the regionnode
ItRgBegin, // At the beginning of the regionnode successor.
ItRgEnd // At the end of the regionnode successor.
};
// Use two bit to represent the mode iterator.
PointerIntPair<NodeType*, 2, enum ItMode> Node;
// The block successor iterator.
succ_iterator BItor;
// advanceRegionSucc - A region node has only one successor. It reaches end
// once we advance it.
void advanceRegionSucc() {
assert(Node.getInt() == ItRgBegin && "Cannot advance region successor!");
Node.setInt(ItRgEnd);
}
NodeType* getNode() const{ return Node.getPointer(); }
// isRegionMode - Is the current iterator in region mode?
bool isRegionMode() const { return Node.getInt() != ItBB; }
// Get the immediate successor. This function may return a Basic Block
// RegionNode or a subregion RegionNode.
RegionNode* getISucc(BasicBlock* BB) const {
RegionNode *succ;
succ = getNode()->getParent()->getNode(BB);
assert(succ && "BB not in Region or entered subregion!");
return succ;
}
// getRegionSucc - Return the successor basic block of a SubRegion RegionNode.
inline BasicBlock* getRegionSucc() const {
assert(Node.getInt() == ItRgBegin && "Cannot get the region successor!");
return getNode()->template getNodeAs<Region>()->getExit();
}
// isExit - Is this the exit BB of the Region?
inline bool isExit(BasicBlock* BB) const {
return getNode()->getParent()->getExit() == BB;
}
public:
typedef RNSuccIterator<NodeType> Self;
typedef typename super::pointer pointer;
/// @brief Create begin iterator of a RegionNode.
inline RNSuccIterator(NodeType* node)
: Node(node, node->isSubRegion() ? ItRgBegin : ItBB),
BItor(succ_begin(node->getEntry())) {
// Skip the exit block
if (!isRegionMode())
while (succ_end(node->getEntry()) != BItor && isExit(*BItor))
++BItor;
if (isRegionMode() && isExit(getRegionSucc()))
advanceRegionSucc();
}
/// @brief Create an end iterator.
inline RNSuccIterator(NodeType* node, bool)
: Node(node, node->isSubRegion() ? ItRgEnd : ItBB),
BItor(succ_end(node->getEntry())) {}
inline bool operator==(const Self& x) const {
assert(isRegionMode() == x.isRegionMode() && "Broken iterator!");
if (isRegionMode())
return Node.getInt() == x.Node.getInt();
else
return BItor == x.BItor;
}
inline bool operator!=(const Self& x) const { return !operator==(x); }
inline pointer operator*() const {
BasicBlock* BB = isRegionMode() ? getRegionSucc() : *BItor;
assert(!isExit(BB) && "Iterator out of range!");
return getISucc(BB);
}
inline Self& operator++() {
if(isRegionMode()) {
// The Region only has 1 successor.
advanceRegionSucc();
} else {
// Skip the exit.
do
++BItor;
while (BItor != succ_end(getNode()->getEntry())
&& isExit(*BItor));
}
return *this;
}
inline Self operator++(int) {
Self tmp = *this;
++*this;
return tmp;
}
inline const Self &operator=(const Self &I) {
if (this != &I) {
assert(getNode()->getParent() == I.getNode()->getParent()
&& "Cannot assign iterators of two different regions!");
Node = I.Node;
BItor = I.BItor;
}
return *this;
}
};
//===----------------------------------------------------------------------===//
/// @brief Flat RegionNode iterator.
///
/// The Flat Region iterator will iterate over all BasicBlock RegionNodes that
/// are contained in the Region and its subregions. This is close to a virtual
/// control flow graph of the Region.
template<class NodeType>
class RNSuccIterator<FlatIt<NodeType> >
: public std::iterator<std::forward_iterator_tag, NodeType, ptrdiff_t>
{
typedef std::iterator<std::forward_iterator_tag, NodeType, ptrdiff_t> super;
NodeType* Node;
succ_iterator Itor;
public:
typedef RNSuccIterator<FlatIt<NodeType> > Self;
typedef typename super::pointer pointer;
/// @brief Create the iterator from a RegionNode.
///
/// Note that the incoming node must be a bb node, otherwise it will trigger
/// an assertion when we try to get a BasicBlock.
inline RNSuccIterator(NodeType* node) : Node(node),
Itor(succ_begin(node->getEntry())) {
assert(!Node->isSubRegion()
&& "Subregion node not allowed in flat iterating mode!");
assert(Node->getParent() && "A BB node must have a parent!");
// Skip the exit block of the iterating region.
while (succ_end(Node->getEntry()) != Itor
&& Node->getParent()->getExit() == *Itor)
++Itor;
}
/// @brief Create an end iterator
inline RNSuccIterator(NodeType* node, bool) : Node(node),
Itor(succ_end(node->getEntry())) {
assert(!Node->isSubRegion()
&& "Subregion node not allowed in flat iterating mode!");
}
inline bool operator==(const Self& x) const {
assert(Node->getParent() == x.Node->getParent()
&& "Cannot compare iterators of different regions!");
return Itor == x.Itor && Node == x.Node;
}
inline bool operator!=(const Self& x) const { return !operator==(x); }
inline pointer operator*() const {
BasicBlock* BB = *Itor;
// Get the iterating region.
Region* Parent = Node->getParent();
// The only case that the successor reaches out of the region is it reaches
// the exit of the region.
assert(Parent->getExit() != BB && "iterator out of range!");
return Parent->getBBNode(BB);
}
inline Self& operator++() {
// Skip the exit block of the iterating region.
do
++Itor;
while (Itor != succ_end(Node->getEntry())
&& Node->getParent()->getExit() == *Itor);
return *this;
}
inline Self operator++(int) {
Self tmp = *this;
++*this;
return tmp;
}
inline const Self &operator=(const Self &I) {
if (this != &I) {
assert(Node->getParent() == I.Node->getParent()
&& "Cannot assign iterators to two different regions!");
Node = I.Node;
Itor = I.Itor;
}
return *this;
}
};
template<class NodeType>
inline RNSuccIterator<NodeType> succ_begin(NodeType* Node) {
return RNSuccIterator<NodeType>(Node);
}
template<class NodeType>
inline RNSuccIterator<NodeType> succ_end(NodeType* Node) {
return RNSuccIterator<NodeType>(Node, true);
}
//===--------------------------------------------------------------------===//
// RegionNode GraphTraits specialization so the bbs in the region can be
// iterate by generic graph iterators.
//
// NodeT can either be region node or const region node, otherwise child_begin
// and child_end fail.
#define RegionNodeGraphTraits(NodeT) \
template<> struct GraphTraits<NodeT*> { \
typedef NodeT NodeType; \
typedef RNSuccIterator<NodeType> ChildIteratorType; \
static NodeType *getEntryNode(NodeType* N) { return N; } \
static inline ChildIteratorType child_begin(NodeType *N) { \
return RNSuccIterator<NodeType>(N); \
} \
static inline ChildIteratorType child_end(NodeType *N) { \
return RNSuccIterator<NodeType>(N, true); \
} \
}; \
template<> struct GraphTraits<FlatIt<NodeT*> > { \
typedef NodeT NodeType; \
typedef RNSuccIterator<FlatIt<NodeT> > ChildIteratorType; \
static NodeType *getEntryNode(NodeType* N) { return N; } \
static inline ChildIteratorType child_begin(NodeType *N) { \
return RNSuccIterator<FlatIt<NodeType> >(N); \
} \
static inline ChildIteratorType child_end(NodeType *N) { \
return RNSuccIterator<FlatIt<NodeType> >(N, true); \
} \
}
#define RegionGraphTraits(RegionT, NodeT) \
template<> struct GraphTraits<RegionT*> \
: public GraphTraits<NodeT*> { \
typedef df_iterator<NodeType*> nodes_iterator; \
static NodeType *getEntryNode(RegionT* R) { \
return R->getNode(R->getEntry()); \
} \
static nodes_iterator nodes_begin(RegionT* R) { \
return nodes_iterator::begin(getEntryNode(R)); \
} \
static nodes_iterator nodes_end(RegionT* R) { \
return nodes_iterator::end(getEntryNode(R)); \
} \
}; \
template<> struct GraphTraits<FlatIt<RegionT*> > \
: public GraphTraits<FlatIt<NodeT*> > { \
typedef df_iterator<NodeType*, SmallPtrSet<NodeType*, 8>, false, \
GraphTraits<FlatIt<NodeType*> > > nodes_iterator; \
static NodeType *getEntryNode(RegionT* R) { \
return R->getBBNode(R->getEntry()); \
} \
static nodes_iterator nodes_begin(RegionT* R) { \
return nodes_iterator::begin(getEntryNode(R)); \
} \
static nodes_iterator nodes_end(RegionT* R) { \
return nodes_iterator::end(getEntryNode(R)); \
} \
}
RegionNodeGraphTraits(RegionNode);
RegionNodeGraphTraits(const RegionNode);
RegionGraphTraits(Region, RegionNode);
RegionGraphTraits(const Region, const RegionNode);
template <> struct GraphTraits<RegionInfo*>
: public GraphTraits<FlatIt<RegionNode*> > {
typedef df_iterator<NodeType*, SmallPtrSet<NodeType*, 8>, false,
GraphTraits<FlatIt<NodeType*> > > nodes_iterator;
static NodeType *getEntryNode(RegionInfo *RI) {
return GraphTraits<FlatIt<Region*> >::getEntryNode(RI->getTopLevelRegion());
}
static nodes_iterator nodes_begin(RegionInfo* RI) {
return nodes_iterator::begin(getEntryNode(RI));
}
static nodes_iterator nodes_end(RegionInfo *RI) {
return nodes_iterator::end(getEntryNode(RI));
}
};
} // End namespace llvm
#endif

View File

@ -0,0 +1,26 @@
//===-- RegionPrinter.h - Region printer external interface -----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines external functions that can be called to explicitly
// instantiate the region printer.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_REGIONPRINTER_H
#define LLVM_ANALYSIS_REGIONPRINTER_H
namespace llvm {
class FunctionPass;
FunctionPass *createRegionViewerPass();
FunctionPass *createRegionOnlyViewerPass();
FunctionPass *createRegionPrinterPass();
FunctionPass *createRegionOnlyPrinterPass();
} // End llvm namespace
#endif

View File

@ -44,12 +44,17 @@ namespace llvm {
class Loop; class Loop;
class LoopInfo; class LoopInfo;
class Operator; class Operator;
class SCEVUnknown;
class SCEV;
template<> struct FoldingSetTrait<SCEV>;
/// SCEV - This class represents an analyzed expression in the program. These /// SCEV - This class represents an analyzed expression in the program. These
/// are opaque objects that the client is not allowed to do much with /// are opaque objects that the client is not allowed to do much with
/// directly. /// directly.
/// ///
class SCEV : public FoldingSetNode { class SCEV : public FoldingSetNode {
friend struct FoldingSetTrait<SCEV>;
/// FastID - A reference to an Interned FoldingSetNodeID for this node. /// FastID - A reference to an Interned FoldingSetNodeID for this node.
/// The ScalarEvolution's BumpPtrAllocator holds the data. /// The ScalarEvolution's BumpPtrAllocator holds the data.
FoldingSetNodeIDRef FastID; FoldingSetNodeIDRef FastID;
@ -73,9 +78,6 @@ namespace llvm {
unsigned getSCEVType() const { return SCEVType; } unsigned getSCEVType() const { return SCEVType; }
/// Profile - FoldingSet support.
void Profile(FoldingSetNodeID& ID) { ID = FastID; }
/// isLoopInvariant - Return true if the value of this SCEV is unchanging in /// isLoopInvariant - Return true if the value of this SCEV is unchanging in
/// the specified loop. /// the specified loop.
virtual bool isLoopInvariant(const Loop *L) const = 0; virtual bool isLoopInvariant(const Loop *L) const = 0;
@ -125,6 +127,21 @@ namespace llvm {
void dump() const; void dump() const;
}; };
// Specialize FoldingSetTrait for SCEV to avoid needing to compute
// temporary FoldingSetNodeID values.
template<> struct FoldingSetTrait<SCEV> : DefaultFoldingSetTrait<SCEV> {
static void Profile(const SCEV &X, FoldingSetNodeID& ID) {
ID = X.FastID;
}
static bool Equals(const SCEV &X, const FoldingSetNodeID &ID,
FoldingSetNodeID &TempID) {
return ID == X.FastID;
}
static unsigned ComputeHash(const SCEV &X, FoldingSetNodeID &TempID) {
return X.FastID.ComputeHash();
}
};
inline raw_ostream &operator<<(raw_ostream &OS, const SCEV &S) { inline raw_ostream &operator<<(raw_ostream &OS, const SCEV &S) {
S.print(OS); S.print(OS);
return OS; return OS;
@ -175,6 +192,7 @@ namespace llvm {
friend class SCEVCallbackVH; friend class SCEVCallbackVH;
friend class SCEVExpander; friend class SCEVExpander;
friend class SCEVUnknown;
/// F - The function we are analyzing. /// F - The function we are analyzing.
/// ///
@ -196,9 +214,14 @@ namespace llvm {
/// counts and things. /// counts and things.
SCEVCouldNotCompute CouldNotCompute; SCEVCouldNotCompute CouldNotCompute;
/// Scalars - This is a cache of the scalars we have analyzed so far. /// ValueExprMapType - The typedef for ValueExprMap.
/// ///
std::map<SCEVCallbackVH, const SCEV *> Scalars; typedef DenseMap<SCEVCallbackVH, const SCEV *, DenseMapInfo<Value *> >
ValueExprMapType;
/// ValueExprMap - This is a cache of the values we have analyzed so far.
///
ValueExprMapType ValueExprMap;
/// BackedgeTakenInfo - Information about the backedge-taken count /// BackedgeTakenInfo - Information about the backedge-taken count
/// of a loop. This currently includes an exact count and a maximum count. /// of a loop. This currently includes an exact count and a maximum count.
@ -263,7 +286,7 @@ namespace llvm {
/// ForgetSymbolicValue - This looks up computed SCEV values for all /// ForgetSymbolicValue - This looks up computed SCEV values for all
/// instructions that depend on the given instruction and removes them from /// instructions that depend on the given instruction and removes them from
/// the Scalars map if they reference SymName. This is used during PHI /// the ValueExprMap map if they reference SymName. This is used during PHI
/// resolution. /// resolution.
void ForgetSymbolicName(Instruction *I, const SCEV *SymName); void ForgetSymbolicName(Instruction *I, const SCEV *SymName);
@ -350,10 +373,11 @@ namespace llvm {
std::pair<BasicBlock *, BasicBlock *> std::pair<BasicBlock *, BasicBlock *>
getPredecessorWithUniqueSuccessorForBB(BasicBlock *BB); getPredecessorWithUniqueSuccessorForBB(BasicBlock *BB);
/// isImpliedCond - Test whether the condition described by Pred, LHS, /// isImpliedCond - Test whether the condition described by Pred, LHS, and
/// and RHS is true whenever the given Cond value evaluates to true. /// RHS is true whenever the given FoundCondValue value evaluates to true.
bool isImpliedCond(Value *Cond, ICmpInst::Predicate Pred, bool isImpliedCond(ICmpInst::Predicate Pred,
const SCEV *LHS, const SCEV *RHS, const SCEV *LHS, const SCEV *RHS,
Value *FoundCondValue,
bool Inverse); bool Inverse);
/// isImpliedCondOperands - Test whether the condition described by Pred, /// isImpliedCondOperands - Test whether the condition described by Pred,
@ -659,6 +683,11 @@ namespace llvm {
private: private:
FoldingSet<SCEV> UniqueSCEVs; FoldingSet<SCEV> UniqueSCEVs;
BumpPtrAllocator SCEVAllocator; BumpPtrAllocator SCEVAllocator;
/// FirstUnknown - The head of a linked list of all SCEVUnknown
/// values that have been allocated. This is used by releaseMemory
/// to locate them all and call their destructors.
SCEVUnknown *FirstUnknown;
}; };
} }

View File

@ -18,6 +18,7 @@
#include "llvm/Analysis/ScalarEvolutionNormalization.h" #include "llvm/Analysis/ScalarEvolutionNormalization.h"
#include "llvm/Support/IRBuilder.h" #include "llvm/Support/IRBuilder.h"
#include "llvm/Support/TargetFolder.h" #include "llvm/Support/TargetFolder.h"
#include "llvm/Support/ValueHandle.h"
#include <set> #include <set>
namespace llvm { namespace llvm {
@ -31,8 +32,8 @@ namespace llvm {
ScalarEvolution &SE; ScalarEvolution &SE;
std::map<std::pair<const SCEV *, Instruction *>, AssertingVH<Value> > std::map<std::pair<const SCEV *, Instruction *>, AssertingVH<Value> >
InsertedExpressions; InsertedExpressions;
std::set<Value*> InsertedValues; std::set<AssertingVH<Value> > InsertedValues;
std::set<Value*> InsertedPostIncValues; std::set<AssertingVH<Value> > InsertedPostIncValues;
/// PostIncLoops - Addrecs referring to any of the given loops are expanded /// PostIncLoops - Addrecs referring to any of the given loops are expanded
/// in post-inc mode. For example, expanding {1,+,1}<L> in post-inc mode /// in post-inc mode. For example, expanding {1,+,1}<L> in post-inc mode
@ -70,13 +71,18 @@ namespace llvm {
/// clear - Erase the contents of the InsertedExpressions map so that users /// clear - Erase the contents of the InsertedExpressions map so that users
/// trying to expand the same expression into multiple BasicBlocks or /// trying to expand the same expression into multiple BasicBlocks or
/// different places within the same BasicBlock can do so. /// different places within the same BasicBlock can do so.
void clear() { InsertedExpressions.clear(); } void clear() {
InsertedExpressions.clear();
InsertedValues.clear();
InsertedPostIncValues.clear();
}
/// getOrInsertCanonicalInductionVariable - This method returns the /// getOrInsertCanonicalInductionVariable - This method returns the
/// canonical induction variable of the specified type for the specified /// canonical induction variable of the specified type for the specified
/// loop (inserting one if there is none). A canonical induction variable /// loop (inserting one if there is none). A canonical induction variable
/// starts at zero and steps by one on each iteration. /// starts at zero and steps by one on each iteration.
Value *getOrInsertCanonicalInductionVariable(const Loop *L, const Type *Ty); PHINode *getOrInsertCanonicalInductionVariable(const Loop *L,
const Type *Ty);
/// expandCodeFor - Insert code to directly compute the specified SCEV /// expandCodeFor - Insert code to directly compute the specified SCEV
/// expression into the program. The inserted code is inserted into the /// expression into the program. The inserted code is inserted into the

View File

@ -202,33 +202,14 @@ namespace llvm {
op_iterator op_begin() const { return Operands; } op_iterator op_begin() const { return Operands; }
op_iterator op_end() const { return Operands + NumOperands; } op_iterator op_end() const { return Operands + NumOperands; }
virtual bool isLoopInvariant(const Loop *L) const { virtual bool isLoopInvariant(const Loop *L) const;
for (unsigned i = 0, e = getNumOperands(); i != e; ++i)
if (!getOperand(i)->isLoopInvariant(L)) return false;
return true;
}
// hasComputableLoopEvolution - N-ary expressions have computable loop // hasComputableLoopEvolution - N-ary expressions have computable loop
// evolutions iff they have at least one operand that varies with the loop, // evolutions iff they have at least one operand that varies with the loop,
// but that all varying operands are computable. // but that all varying operands are computable.
virtual bool hasComputableLoopEvolution(const Loop *L) const { virtual bool hasComputableLoopEvolution(const Loop *L) const;
bool HasVarying = false;
for (unsigned i = 0, e = getNumOperands(); i != e; ++i)
if (!getOperand(i)->isLoopInvariant(L)) {
if (getOperand(i)->hasComputableLoopEvolution(L))
HasVarying = true;
else
return false;
}
return HasVarying;
}
virtual bool hasOperand(const SCEV *O) const { virtual bool hasOperand(const SCEV *O) const;
for (unsigned i = 0, e = getNumOperands(); i != e; ++i)
if (O == getOperand(i) || getOperand(i)->hasOperand(O))
return true;
return false;
}
bool dominates(BasicBlock *BB, DominatorTree *DT) const; bool dominates(BasicBlock *BB, DominatorTree *DT) const;
@ -520,15 +501,28 @@ namespace llvm {
/// value, and only represent it as its LLVM Value. This is the "bottom" /// value, and only represent it as its LLVM Value. This is the "bottom"
/// value for the analysis. /// value for the analysis.
/// ///
class SCEVUnknown : public SCEV { class SCEVUnknown : public SCEV, private CallbackVH {
friend class ScalarEvolution; friend class ScalarEvolution;
Value *V; // Implement CallbackVH.
SCEVUnknown(const FoldingSetNodeIDRef ID, Value *v) : virtual void deleted();
SCEV(ID, scUnknown), V(v) {} virtual void allUsesReplacedWith(Value *New);
/// SE - The parent ScalarEvolution value. This is used to update
/// the parent's maps when the value associated with a SCEVUnknown
/// is deleted or RAUW'd.
ScalarEvolution *SE;
/// Next - The next pointer in the linked list of all
/// SCEVUnknown instances owned by a ScalarEvolution.
SCEVUnknown *Next;
SCEVUnknown(const FoldingSetNodeIDRef ID, Value *V,
ScalarEvolution *se, SCEVUnknown *next) :
SCEV(ID, scUnknown), CallbackVH(V), SE(se), Next(next) {}
public: public:
Value *getValue() const { return V; } Value *getValue() const { return getValPtr(); }
/// isSizeOf, isAlignOf, isOffsetOf - Test whether this is a special /// isSizeOf, isAlignOf, isOffsetOf - Test whether this is a special
/// constant representing a type size, alignment, or field offset in /// constant representing a type size, alignment, or field offset in

View File

@ -77,25 +77,6 @@ namespace llvm {
/// ///
bool CannotBeNegativeZero(const Value *V, unsigned Depth = 0); bool CannotBeNegativeZero(const Value *V, unsigned Depth = 0);
/// DecomposeGEPExpression - If V is a symbolic pointer expression, decompose
/// it into a base pointer with a constant offset and a number of scaled
/// symbolic offsets.
///
/// The scaled symbolic offsets (represented by pairs of a Value* and a scale
/// in the VarIndices vector) are Value*'s that are known to be scaled by the
/// specified amount, but which may have other unrepresented high bits. As
/// such, the gep cannot necessarily be reconstructed from its decomposed
/// form.
///
/// When TargetData is around, this function is capable of analyzing
/// everything that Value::getUnderlyingObject() can look through. When not,
/// it just looks through pointer casts.
///
const Value *DecomposeGEPExpression(const Value *V, int64_t &BaseOffs,
SmallVectorImpl<std::pair<const Value*, int64_t> > &VarIndices,
const TargetData *TD);
/// FindInsertedValue - Given an aggregrate and an sequence of indices, see if /// FindInsertedValue - Given an aggregrate and an sequence of indices, see if
/// the scalar value indexed is already around as a register, for example if /// the scalar value indexed is already around as a register, for example if

View File

@ -1,4 +1,4 @@
//===-- AsmAnnotationWriter.h - Itf for annotation .ll files - --*- C++ -*-===// //===-- AssemblyAnnotationWriter.h - Annotation .ll files -------*- C++ -*-===//
// //
// The LLVM Compiler Infrastructure // The LLVM Compiler Infrastructure
// //
@ -32,21 +32,26 @@ public:
/// emitFunctionAnnot - This may be implemented to emit a string right before /// emitFunctionAnnot - This may be implemented to emit a string right before
/// the start of a function. /// the start of a function.
virtual void emitFunctionAnnot(const Function *F, raw_ostream &OS) {} virtual void emitFunctionAnnot(const Function *F,
formatted_raw_ostream &OS) {}
/// emitBasicBlockStartAnnot - This may be implemented to emit a string right /// emitBasicBlockStartAnnot - This may be implemented to emit a string right
/// after the basic block label, but before the first instruction in the block. /// after the basic block label, but before the first instruction in the
virtual void emitBasicBlockStartAnnot(const BasicBlock *BB, raw_ostream &OS){ /// block.
virtual void emitBasicBlockStartAnnot(const BasicBlock *BB,
formatted_raw_ostream &OS) {
} }
/// emitBasicBlockEndAnnot - This may be implemented to emit a string right /// emitBasicBlockEndAnnot - This may be implemented to emit a string right
/// after the basic block. /// after the basic block.
virtual void emitBasicBlockEndAnnot(const BasicBlock *BB, raw_ostream &OS){ virtual void emitBasicBlockEndAnnot(const BasicBlock *BB,
formatted_raw_ostream &OS) {
} }
/// emitInstructionAnnot - This may be implemented to emit a string right /// emitInstructionAnnot - This may be implemented to emit a string right
/// before an instruction is emitted. /// before an instruction is emitted.
virtual void emitInstructionAnnot(const Instruction *I, raw_ostream &OS) {} virtual void emitInstructionAnnot(const Instruction *I,
formatted_raw_ostream &OS) {}
/// printInfoComment - This may be implemented to emit a comment to the /// printInfoComment - This may be implemented to emit a comment to the
/// right of an instruction or global value. /// right of an instruction or global value.

View File

@ -16,6 +16,7 @@
namespace llvm { namespace llvm {
class Module; class Module;
class GlobalVariable;
class Function; class Function;
class CallInst; class CallInst;
@ -35,6 +36,10 @@ namespace llvm {
/// so that it can update all calls to the old function. /// so that it can update all calls to the old function.
void UpgradeCallsToIntrinsic(Function* F); void UpgradeCallsToIntrinsic(Function* F);
/// This checks for global variables which should be upgraded. It returns true
/// if it requires upgrading.
bool UpgradeGlobalVariable(GlobalVariable *GV);
/// This function checks debug info intrinsics. If an intrinsic is invalid /// This function checks debug info intrinsics. If an intrinsic is invalid
/// then this function simply removes the intrinsic. /// then this function simply removes the intrinsic.
void CheckDebugInfoIntrinsics(Module *M); void CheckDebugInfoIntrinsics(Module *M);

View File

@ -297,7 +297,7 @@ class Archive {
/// its symbol table without reading in any of the archive's members. This /// its symbol table without reading in any of the archive's members. This
/// reduces both I/O and cpu time in opening the archive if it is to be used /// reduces both I/O and cpu time in opening the archive if it is to be used
/// solely for symbol lookup (e.g. during linking). The \p Filename must /// solely for symbol lookup (e.g. during linking). The \p Filename must
/// exist and be an archive file or an exception will be thrown. This form /// exist and be an archive file or an error will be returned. This form
/// of opening the archive is intended for read-only operations that need to /// of opening the archive is intended for read-only operations that need to
/// locate members via the symbol table for link editing. Since the archve /// locate members via the symbol table for link editing. Since the archve
/// members are not read by this method, the archive will appear empty upon /// members are not read by this method, the archive will appear empty upon
@ -306,8 +306,7 @@ class Archive {
/// if this form of opening the archive is used that only the symbol table /// if this form of opening the archive is used that only the symbol table
/// lookup methods (getSymbolTable, findModuleDefiningSymbol, and /// lookup methods (getSymbolTable, findModuleDefiningSymbol, and
/// findModulesDefiningSymbols) be used. /// findModulesDefiningSymbols) be used.
/// @throws std::string if an error occurs opening the file /// @returns an Archive* that represents the archive file, or null on error.
/// @returns an Archive* that represents the archive file.
/// @brief Open an existing archive and load its symbols. /// @brief Open an existing archive and load its symbols.
static Archive* OpenAndLoadSymbols( static Archive* OpenAndLoadSymbols(
const sys::Path& Filename, ///< Name of the archive file to open const sys::Path& Filename, ///< Name of the archive file to open
@ -319,7 +318,6 @@ class Archive {
/// closes files. It does nothing with the archive file on disk. If you /// closes files. It does nothing with the archive file on disk. If you
/// haven't used the writeToDisk method by the time the destructor is /// haven't used the writeToDisk method by the time the destructor is
/// called, all changes to the archive will be lost. /// called, all changes to the archive will be lost.
/// @throws std::string if an error occurs
/// @brief Destruct in-memory archive /// @brief Destruct in-memory archive
~Archive(); ~Archive();

View File

@ -88,7 +88,7 @@ public:
//===--------------------------------------------------------------------===// //===--------------------------------------------------------------------===//
void Emit(uint32_t Val, unsigned NumBits) { void Emit(uint32_t Val, unsigned NumBits) {
assert(NumBits <= 32 && "Invalid value size!"); assert(NumBits && NumBits <= 32 && "Invalid value size!");
assert((Val & ~(~0U >> (32-NumBits))) == 0 && "High bits set!"); assert((Val & ~(~0U >> (32-NumBits))) == 0 && "High bits set!");
CurValue |= Val << CurBit; CurValue |= Val << CurBit;
if (CurBit + NumBits < 32) { if (CurBit + NumBits < 32) {
@ -277,10 +277,12 @@ private:
switch (Op.getEncoding()) { switch (Op.getEncoding()) {
default: assert(0 && "Unknown encoding!"); default: assert(0 && "Unknown encoding!");
case BitCodeAbbrevOp::Fixed: case BitCodeAbbrevOp::Fixed:
Emit((unsigned)V, (unsigned)Op.getEncodingData()); if (Op.getEncodingData())
Emit((unsigned)V, (unsigned)Op.getEncodingData());
break; break;
case BitCodeAbbrevOp::VBR: case BitCodeAbbrevOp::VBR:
EmitVBR64(V, (unsigned)Op.getEncodingData()); if (Op.getEncodingData())
EmitVBR64(V, (unsigned)Op.getEncodingData());
break; break;
case BitCodeAbbrevOp::Char6: case BitCodeAbbrevOp::Char6:
Emit(BitCodeAbbrevOp::EncodeChar6((char)V), 6); Emit(BitCodeAbbrevOp::EncodeChar6((char)V), 6);

View File

@ -94,8 +94,7 @@ namespace bitc {
TYPE_CODE_FP128 = 14, // LONG DOUBLE (112 bit mantissa) TYPE_CODE_FP128 = 14, // LONG DOUBLE (112 bit mantissa)
TYPE_CODE_PPC_FP128= 15, // PPC LONG DOUBLE (2 doubles) TYPE_CODE_PPC_FP128= 15, // PPC LONG DOUBLE (2 doubles)
TYPE_CODE_METADATA = 16, // METADATA TYPE_CODE_METADATA = 16 // METADATA
TYPE_CODE_UNION = 17 // UNION: [eltty x N]
}; };
// The type symbol table only has one code (TST_ENTRY_CODE). // The type symbol table only has one code (TST_ENTRY_CODE).
@ -111,12 +110,20 @@ namespace bitc {
enum MetadataCodes { enum MetadataCodes {
METADATA_STRING = 1, // MDSTRING: [values] METADATA_STRING = 1, // MDSTRING: [values]
METADATA_NODE = 2, // MDNODE: [n x (type num, value num)] // FIXME: Remove NODE in favor of NODE2 in LLVM 3.0
METADATA_FN_NODE = 3, // FN_MDNODE: [n x (type num, value num)] METADATA_NODE = 2, // NODE with potentially invalid metadata
// FIXME: Remove FN_NODE in favor of FN_NODE2 in LLVM 3.0
METADATA_FN_NODE = 3, // FN_NODE with potentially invalid metadata
METADATA_NAME = 4, // STRING: [values] METADATA_NAME = 4, // STRING: [values]
METADATA_NAMED_NODE = 5, // NAMEDMDNODE: [n x mdnodes] // FIXME: Remove NAMED_NODE in favor of NAMED_NODE2 in LLVM 3.0
METADATA_NAMED_NODE = 5, // NAMED_NODE with potentially invalid metadata
METADATA_KIND = 6, // [n x [id, name]] METADATA_KIND = 6, // [n x [id, name]]
METADATA_ATTACHMENT = 7 // [m x [value, [n x [id, mdnode]]] // FIXME: Remove ATTACHMENT in favor of ATTACHMENT2 in LLVM 3.0
METADATA_ATTACHMENT = 7, // ATTACHMENT with potentially invalid metadata
METADATA_NODE2 = 8, // NODE2: [n x (type num, value num)]
METADATA_FN_NODE2 = 9, // FN_NODE2: [n x (type num, value num)]
METADATA_NAMED_NODE2 = 10, // NAMED_NODE2: [n x mdnodes]
METADATA_ATTACHMENT2 = 11 // [m x [value, [n x [id, mdnode]]]
}; };
// The constants block (CONSTANTS_BLOCK_ID) describes emission for each // The constants block (CONSTANTS_BLOCK_ID) describes emission for each
// constant and maintains an implicit current type value. // constant and maintains an implicit current type value.
@ -224,7 +231,8 @@ namespace bitc {
FUNC_CODE_INST_LOAD = 20, // LOAD: [opty, op, align, vol] FUNC_CODE_INST_LOAD = 20, // LOAD: [opty, op, align, vol]
// FIXME: Remove STORE in favor of STORE2 in LLVM 3.0 // FIXME: Remove STORE in favor of STORE2 in LLVM 3.0
FUNC_CODE_INST_STORE = 21, // STORE: [valty,val,ptr, align, vol] FUNC_CODE_INST_STORE = 21, // STORE: [valty,val,ptr, align, vol]
FUNC_CODE_INST_CALL = 22, // CALL: [attr, fnty, fnid, args...] // FIXME: Remove CALL in favor of CALL2 in LLVM 3.0
FUNC_CODE_INST_CALL = 22, // CALL with potentially invalid metadata
FUNC_CODE_INST_VAARG = 23, // VAARG: [valistty, valist, instty] FUNC_CODE_INST_VAARG = 23, // VAARG: [valistty, valist, instty]
// This store code encodes the pointer type, rather than the value type // This store code encodes the pointer type, rather than the value type
// this is so information only available in the pointer type (e.g. address // this is so information only available in the pointer type (e.g. address
@ -242,8 +250,13 @@ namespace bitc {
FUNC_CODE_INST_INBOUNDS_GEP= 30, // INBOUNDS_GEP: [n x operands] FUNC_CODE_INST_INBOUNDS_GEP= 30, // INBOUNDS_GEP: [n x operands]
FUNC_CODE_INST_INDIRECTBR = 31, // INDIRECTBR: [opty, op0, op1, ...] FUNC_CODE_INST_INDIRECTBR = 31, // INDIRECTBR: [opty, op0, op1, ...]
FUNC_CODE_DEBUG_LOC = 32, // DEBUG_LOC: [Line,Col,ScopeVal, IAVal] // FIXME: Remove DEBUG_LOC in favor of DEBUG_LOC2 in LLVM 3.0
FUNC_CODE_DEBUG_LOC_AGAIN = 33 // DEBUG_LOC_AGAIN FUNC_CODE_DEBUG_LOC = 32, // DEBUG_LOC with potentially invalid metadata
FUNC_CODE_DEBUG_LOC_AGAIN = 33, // DEBUG_LOC_AGAIN
FUNC_CODE_INST_CALL2 = 34, // CALL2: [attr, fnty, fnid, args...]
FUNC_CODE_DEBUG_LOC2 = 35 // DEBUG_LOC2: [Line,Col,ScopeVal, IAVal]
}; };
} // End bitc namespace } // End bitc namespace
} // End llvm namespace } // End llvm namespace

View File

@ -33,8 +33,7 @@ class CallGraphSCC;
class CallGraphSCCPass : public Pass { class CallGraphSCCPass : public Pass {
public: public:
explicit CallGraphSCCPass(intptr_t pid) : Pass(PT_CallGraphSCC, pid) {} explicit CallGraphSCCPass(char &pid) : Pass(PT_CallGraphSCC, pid) {}
explicit CallGraphSCCPass(void *pid) : Pass(PT_CallGraphSCC, pid) {}
/// createPrinterPass - Get a pass that prints the Module /// createPrinterPass - Get a pass that prints the Module
/// corresponding to a CallGraph. /// corresponding to a CallGraph.
@ -64,7 +63,7 @@ public:
/// Assign pass manager to manager this pass /// Assign pass manager to manager this pass
virtual void assignPassManager(PMStack &PMS, virtual void assignPassManager(PMStack &PMS,
PassManagerType PMT =PMT_CallGraphPassManager); PassManagerType PMT);
/// Return what kind of Pass Manager can manage this pass. /// Return what kind of Pass Manager can manage this pass.
virtual PassManagerType getPotentialPassManagerType() const { virtual PassManagerType getPotentialPassManagerType() const {

View File

@ -54,6 +54,7 @@ namespace llvm {
class Mangler; class Mangler;
class TargetLoweringObjectFile; class TargetLoweringObjectFile;
class TargetData; class TargetData;
class TargetMachine;
class Twine; class Twine;
class Type; class Type;
@ -296,7 +297,7 @@ namespace llvm {
MCSymbol *GetBlockAddressSymbol(const BlockAddress *BA) const; MCSymbol *GetBlockAddressSymbol(const BlockAddress *BA) const;
MCSymbol *GetBlockAddressSymbol(const BasicBlock *BB) const; MCSymbol *GetBlockAddressSymbol(const BasicBlock *BB) const;
//===------------------------------------------------------------------===// //===------------------------------------------------------------------===//
// Emission Helper Routines. // Emission Helper Routines.
//===------------------------------------------------------------------===// //===------------------------------------------------------------------===//
public: public:
@ -327,6 +328,12 @@ namespace llvm {
void EmitLabelOffsetDifference(const MCSymbol *Hi, uint64_t Offset, void EmitLabelOffsetDifference(const MCSymbol *Hi, uint64_t Offset,
const MCSymbol *Lo, unsigned Size) const; const MCSymbol *Lo, unsigned Size) const;
/// EmitLabelPlusOffset - Emit something like ".long Label+Offset"
/// where the size in bytes of the directive is specified by Size and Label
/// specifies the label. This implicitly uses .set if it is available.
void EmitLabelPlusOffset(const MCSymbol *Label, uint64_t Offset,
unsigned Size) const;
//===------------------------------------------------------------------===// //===------------------------------------------------------------------===//
// Dwarf Emission Helper Routines // Dwarf Emission Helper Routines
//===------------------------------------------------------------------===// //===------------------------------------------------------------------===//
@ -369,6 +376,10 @@ namespace llvm {
/// operands. /// operands.
virtual MachineLocation getDebugValueLocation(const MachineInstr *MI) const; virtual MachineLocation getDebugValueLocation(const MachineInstr *MI) const;
/// getISAEncoding - Get the value for DW_AT_APPLE_isa. Zero if no isa
/// encoding specified.
virtual unsigned getISAEncoding() { return 0; }
//===------------------------------------------------------------------===// //===------------------------------------------------------------------===//
// Dwarf Lowering Routines // Dwarf Lowering Routines
//===------------------------------------------------------------------===// //===------------------------------------------------------------------===//

View File

@ -12,10 +12,35 @@
#define LLVM_CODEGEN_CALCSPILLWEIGHTS_H #define LLVM_CODEGEN_CALCSPILLWEIGHTS_H
#include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/ADT/DenseMap.h"
namespace llvm { namespace llvm {
class LiveInterval; class LiveInterval;
class LiveIntervals;
class MachineLoopInfo;
/// VirtRegAuxInfo - Calculate auxiliary information for a virtual
/// register such as its spill weight and allocation hint.
class VirtRegAuxInfo {
MachineFunction &mf_;
LiveIntervals &lis_;
const MachineLoopInfo &loops_;
DenseMap<unsigned, float> hint_;
public:
VirtRegAuxInfo(MachineFunction &mf, LiveIntervals &lis,
const MachineLoopInfo &loops) :
mf_(mf), lis_(lis), loops_(loops) {}
/// CalculateRegClass - recompute the register class for reg from its uses.
/// Since the register class can affect the allocation hint, this function
/// should be called before CalculateWeightAndHint if both are called.
void CalculateRegClass(unsigned reg);
/// CalculateWeightAndHint - (re)compute li's spill weight and allocation
/// hint.
void CalculateWeightAndHint(LiveInterval &li);
};
/// CalculateSpillWeights - Compute spill weights for all virtual register /// CalculateSpillWeights - Compute spill weights for all virtual register
/// live intervals. /// live intervals.
@ -23,11 +48,11 @@ namespace llvm {
public: public:
static char ID; static char ID;
CalculateSpillWeights() : MachineFunctionPass(&ID) {} CalculateSpillWeights() : MachineFunctionPass(ID) {}
virtual void getAnalysisUsage(AnalysisUsage &au) const; virtual void getAnalysisUsage(AnalysisUsage &au) const;
virtual bool runOnMachineFunction(MachineFunction &fn); virtual bool runOnMachineFunction(MachineFunction &fn);
private: private:
/// Returns true if the given live interval is zero length. /// Returns true if the given live interval is zero length.

View File

@ -275,6 +275,12 @@ public:
return Result; return Result;
} }
/// Version of AllocateStack with extra register to be shadowed.
unsigned AllocateStack(unsigned Size, unsigned Align, unsigned ShadowReg) {
MarkAllocated(ShadowReg);
return AllocateStack(Size, Align);
}
// HandleByVal - Allocate a stack slot large enough to pass an argument by // HandleByVal - Allocate a stack slot large enough to pass an argument by
// value. The size and alignment information of the argument is encoded in its // value. The size and alignment information of the argument is encoded in its
// parameter attribute. // parameter attribute.

View File

@ -77,6 +77,9 @@ public:
/// anywhere in the function. /// anywhere in the function.
DenseMap<const AllocaInst*, int> StaticAllocaMap; DenseMap<const AllocaInst*, int> StaticAllocaMap;
/// ByValArgFrameIndexMap - Keep track of frame indices for byval arguments.
DenseMap<const Argument*, int> ByValArgFrameIndexMap;
/// ArgDbgValues - A list of DBG_VALUE instructions created during isel for /// ArgDbgValues - A list of DBG_VALUE instructions created during isel for
/// function arguments that are inserted after scheduling is completed. /// function arguments that are inserted after scheduling is completed.
SmallVector<MachineInstr*, 8> ArgDbgValues; SmallVector<MachineInstr*, 8> ArgDbgValues;
@ -138,6 +141,13 @@ public:
assert(R == 0 && "Already initialized this value register!"); assert(R == 0 && "Already initialized this value register!");
return R = CreateRegs(V->getType()); return R = CreateRegs(V->getType());
} }
/// setByValArgumentFrameIndex - Record frame index for the byval
/// argument.
void setByValArgumentFrameIndex(const Argument *A, int FI);
/// getByValArgumentFrameIndex - Get frame index for the byval argument.
int getByValArgumentFrameIndex(const Argument *A);
}; };
/// AddCatchInfo - Extract the personality and type infos from an eh.selector /// AddCatchInfo - Extract the personality and type infos from an eh.selector

View File

@ -603,7 +603,7 @@ namespace ISD {
/// which do not reference a specific memory location should be less than /// which do not reference a specific memory location should be less than
/// this value. Those that do must not be less than this value, and can /// this value. Those that do must not be less than this value, and can
/// be used with SelectionDAG::getMemIntrinsicNode. /// be used with SelectionDAG::getMemIntrinsicNode.
static const int FIRST_TARGET_MEMORY_OPCODE = BUILTIN_OP_END+100; static const int FIRST_TARGET_MEMORY_OPCODE = BUILTIN_OP_END+150;
//===--------------------------------------------------------------------===// //===--------------------------------------------------------------------===//
/// MemIndexedMode enum - This enum defines the load / store indexed /// MemIndexedMode enum - This enum defines the load / store indexed
@ -633,7 +633,6 @@ namespace ISD {
/// (the result of the load and the result of the base +/- offset /// (the result of the load and the result of the base +/- offset
/// computation); a post-indexed store produces one value (the /// computation); a post-indexed store produces one value (the
/// the result of the base +/- offset computation). /// the result of the base +/- offset computation).
///
enum MemIndexedMode { enum MemIndexedMode {
UNINDEXED = 0, UNINDEXED = 0,
PRE_INC, PRE_INC,
@ -651,10 +650,8 @@ namespace ISD {
/// integer result type. /// integer result type.
/// ZEXTLOAD loads the integer operand and zero extends it to a larger /// ZEXTLOAD loads the integer operand and zero extends it to a larger
/// integer result type. /// integer result type.
/// EXTLOAD is used for three things: floating point extending loads, /// EXTLOAD is used for two things: floating point extending loads and
/// integer extending loads [the top bits are undefined], and vector /// integer extending loads [the top bits are undefined].
/// extending loads [load into low elt].
///
enum LoadExtType { enum LoadExtType {
NON_EXTLOAD = 0, NON_EXTLOAD = 0,
EXTLOAD, EXTLOAD,

View File

@ -39,7 +39,7 @@ namespace llvm {
/// This class holds information about a machine level values, including /// This class holds information about a machine level values, including
/// definition and use points. /// definition and use points.
/// ///
/// Care must be taken in interpreting the def index of the value. The /// Care must be taken in interpreting the def index of the value. The
/// following rules apply: /// following rules apply:
/// ///
/// If the isDefAccurate() method returns false then def does not contain the /// If the isDefAccurate() method returns false then def does not contain the
@ -108,7 +108,7 @@ namespace llvm {
/// For a stack interval, returns the reg which this stack interval was /// For a stack interval, returns the reg which this stack interval was
/// defined from. /// defined from.
/// For a register interval the behaviour of this method is undefined. /// For a register interval the behaviour of this method is undefined.
unsigned getReg() const { return cr.reg; } unsigned getReg() const { return cr.reg; }
/// For a stack interval, set the defining register. /// For a stack interval, set the defining register.
/// This method should not be called on register intervals as it may lead /// This method should not be called on register intervals as it may lead
@ -189,7 +189,7 @@ namespace llvm {
} }
/// containsRange - Return true if the given range, [S, E), is covered by /// containsRange - Return true if the given range, [S, E), is covered by
/// this range. /// this range.
bool containsRange(SlotIndex S, SlotIndex E) const { bool containsRange(SlotIndex S, SlotIndex E) const {
assert((S < E) && "Backwards interval?"); assert((S < E) && "Backwards interval?");
return (start <= S && S < end) && (start < E && E <= end); return (start <= S && S < end) && (start < E && E <= end);
@ -236,7 +236,7 @@ namespace llvm {
float weight; // weight of this interval float weight; // weight of this interval
Ranges ranges; // the ranges in which this register is live Ranges ranges; // the ranges in which this register is live
VNInfoList valnos; // value#'s VNInfoList valnos; // value#'s
struct InstrSlots { struct InstrSlots {
enum { enum {
LOAD = 0, LOAD = 0,
@ -281,7 +281,7 @@ namespace llvm {
while (I->end <= Pos) ++I; while (I->end <= Pos) ++I;
return I; return I;
} }
void clear() { void clear() {
valnos.clear(); valnos.clear();
ranges.clear(); ranges.clear();
@ -305,7 +305,7 @@ namespace llvm {
bool containsOneValue() const { return valnos.size() == 1; } bool containsOneValue() const { return valnos.size() == 1; }
unsigned getNumValNums() const { return (unsigned)valnos.size(); } unsigned getNumValNums() const { return (unsigned)valnos.size(); }
/// getValNumInfo - Returns pointer to the specified val#. /// getValNumInfo - Returns pointer to the specified val#.
/// ///
inline VNInfo *getValNumInfo(unsigned ValNo) { inline VNInfo *getValNumInfo(unsigned ValNo) {
@ -336,6 +336,11 @@ namespace llvm {
return VNI; return VNI;
} }
/// RenumberValues - Renumber all values in order of appearance and remove
/// unused values.
/// Recalculate phi-kill flags in case any phi-def values were removed.
void RenumberValues(LiveIntervals &lis);
/// isOnlyLROfValNo - Return true if the specified live range is the only /// isOnlyLROfValNo - Return true if the specified live range is the only
/// one defined by the its val#. /// one defined by the its val#.
bool isOnlyLROfValNo(const LiveRange *LR) { bool isOnlyLROfValNo(const LiveRange *LR) {
@ -346,7 +351,7 @@ namespace llvm {
} }
return true; return true;
} }
/// MergeValueNumberInto - This method is called when two value nubmers /// MergeValueNumberInto - This method is called when two value nubmers
/// are found to be equivalent. This eliminates V1, replacing all /// are found to be equivalent. This eliminates V1, replacing all
/// LiveRanges with the V1 value number with the V2 value number. This can /// LiveRanges with the V1 value number with the V2 value number. This can
@ -387,7 +392,7 @@ namespace llvm {
/// except for the register of the interval. /// except for the register of the interval.
void Copy(const LiveInterval &RHS, MachineRegisterInfo *MRI, void Copy(const LiveInterval &RHS, MachineRegisterInfo *MRI,
VNInfo::Allocator &VNInfoAllocator); VNInfo::Allocator &VNInfoAllocator);
bool empty() const { return ranges.empty(); } bool empty() const { return ranges.empty(); }
/// beginIndex - Return the lowest numbered slot covered by interval. /// beginIndex - Return the lowest numbered slot covered by interval.
@ -454,17 +459,19 @@ namespace llvm {
iterator FindLiveRangeContaining(SlotIndex Idx); iterator FindLiveRangeContaining(SlotIndex Idx);
/// findDefinedVNInfo - Find the by the specified /// findDefinedVNInfo - Find the by the specified
/// index (register interval) or defined /// index (register interval) or defined
VNInfo *findDefinedVNInfoForRegInt(SlotIndex Idx) const; VNInfo *findDefinedVNInfoForRegInt(SlotIndex Idx) const;
/// findDefinedVNInfo - Find the VNInfo that's defined by the specified /// findDefinedVNInfo - Find the VNInfo that's defined by the specified
/// register (stack inteval only). /// register (stack inteval only).
VNInfo *findDefinedVNInfoForStackInt(unsigned Reg) const; VNInfo *findDefinedVNInfoForStackInt(unsigned Reg) const;
/// overlaps - Return true if the intersection of the two live intervals is /// overlaps - Return true if the intersection of the two live intervals is
/// not empty. /// not empty.
bool overlaps(const LiveInterval& other) const { bool overlaps(const LiveInterval& other) const {
if (other.empty())
return false;
return overlapsFrom(other, other.begin()); return overlapsFrom(other, other.begin());
} }
@ -514,6 +521,15 @@ namespace llvm {
/// ///
unsigned getSize() const; unsigned getSize() const;
/// Returns true if the live interval is zero length, i.e. no live ranges
/// span instructions. It doesn't pay to spill such an interval.
bool isZeroLength() const {
for (const_iterator i = begin(), e = end(); i != e; ++i)
if (i->end.getPrevIndex() > i->start)
return false;
return true;
}
/// isSpillable - Can this interval be spilled? /// isSpillable - Can this interval be spilled?
bool isSpillable() const { bool isSpillable() const {
return weight != HUGE_VALF; return weight != HUGE_VALF;
@ -543,6 +559,7 @@ namespace llvm {
Ranges::iterator addRangeFrom(LiveRange LR, Ranges::iterator From); Ranges::iterator addRangeFrom(LiveRange LR, Ranges::iterator From);
void extendIntervalEndTo(Ranges::iterator I, SlotIndex NewEnd); void extendIntervalEndTo(Ranges::iterator I, SlotIndex NewEnd);
Ranges::iterator extendIntervalStartTo(Ranges::iterator I, SlotIndex NewStr); Ranges::iterator extendIntervalStartTo(Ranges::iterator I, SlotIndex NewStr);
void markValNoForDeletion(VNInfo *V);
LiveInterval& operator=(const LiveInterval& rhs); // DO NOT IMPLEMENT LiveInterval& operator=(const LiveInterval& rhs); // DO NOT IMPLEMENT

View File

@ -42,7 +42,7 @@ namespace llvm {
class TargetInstrInfo; class TargetInstrInfo;
class TargetRegisterClass; class TargetRegisterClass;
class VirtRegMap; class VirtRegMap;
class LiveIntervals : public MachineFunctionPass { class LiveIntervals : public MachineFunctionPass {
MachineFunction* mf_; MachineFunction* mf_;
MachineRegisterInfo* mri_; MachineRegisterInfo* mri_;
@ -68,7 +68,7 @@ namespace llvm {
public: public:
static char ID; // Pass identification, replacement for typeid static char ID; // Pass identification, replacement for typeid
LiveIntervals() : MachineFunctionPass(&ID) {} LiveIntervals() : MachineFunctionPass(ID) {}
// Calculate the spill weight to assign to a single instruction. // Calculate the spill weight to assign to a single instruction.
static float getSpillWeight(bool isDef, bool isUse, unsigned loopDepth); static float getSpillWeight(bool isDef, bool isUse, unsigned loopDepth);
@ -105,6 +105,12 @@ namespace llvm {
return r2iMap_.count(reg); return r2iMap_.count(reg);
} }
/// isAllocatable - is the physical register reg allocatable in the current
/// function?
bool isAllocatable(unsigned reg) const {
return allocatableRegs_.test(reg);
}
/// getScaledIntervalSize - get the size of an interval in "units," /// getScaledIntervalSize - get the size of an interval in "units,"
/// where every function is composed of one thousand units. This /// where every function is composed of one thousand units. This
/// measure scales properly with empty index slots in the function. /// measure scales properly with empty index slots in the function.
@ -117,7 +123,7 @@ namespace llvm {
unsigned getFuncInstructionCount() { unsigned getFuncInstructionCount() {
return indexes_->getFunctionSize(); return indexes_->getFunctionSize();
} }
/// getApproximateInstructionCount - computes an estimate of the number /// getApproximateInstructionCount - computes an estimate of the number
/// of instructions in a given LiveInterval. /// of instructions in a given LiveInterval.
unsigned getApproximateInstructionCount(LiveInterval& I) { unsigned getApproximateInstructionCount(LiveInterval& I) {
@ -149,7 +155,7 @@ namespace llvm {
/// dupInterval - Duplicate a live interval. The caller is responsible for /// dupInterval - Duplicate a live interval. The caller is responsible for
/// managing the allocated memory. /// managing the allocated memory.
LiveInterval *dupInterval(LiveInterval *li); LiveInterval *dupInterval(LiveInterval *li);
/// addLiveRangeToEndOfBlock - Given a register and an instruction, /// addLiveRangeToEndOfBlock - Given a register and an instruction,
/// adds a live range from that instruction to the end of its MBB. /// adds a live range from that instruction to the end of its MBB.
LiveRange addLiveRangeToEndOfBlock(unsigned reg, LiveRange addLiveRangeToEndOfBlock(unsigned reg,
@ -181,7 +187,7 @@ namespace llvm {
SlotIndex getInstructionIndex(const MachineInstr *instr) const { SlotIndex getInstructionIndex(const MachineInstr *instr) const {
return indexes_->getInstructionIndex(instr); return indexes_->getInstructionIndex(instr);
} }
/// Returns the instruction associated with the given index. /// Returns the instruction associated with the given index.
MachineInstr* getInstructionFromIndex(SlotIndex index) const { MachineInstr* getInstructionFromIndex(SlotIndex index) const {
return indexes_->getInstructionFromIndex(index); return indexes_->getInstructionFromIndex(index);
@ -190,12 +196,32 @@ namespace llvm {
/// Return the first index in the given basic block. /// Return the first index in the given basic block.
SlotIndex getMBBStartIdx(const MachineBasicBlock *mbb) const { SlotIndex getMBBStartIdx(const MachineBasicBlock *mbb) const {
return indexes_->getMBBStartIdx(mbb); return indexes_->getMBBStartIdx(mbb);
} }
/// Return the last index in the given basic block. /// Return the last index in the given basic block.
SlotIndex getMBBEndIdx(const MachineBasicBlock *mbb) const { SlotIndex getMBBEndIdx(const MachineBasicBlock *mbb) const {
return indexes_->getMBBEndIdx(mbb); return indexes_->getMBBEndIdx(mbb);
} }
bool isLiveInToMBB(const LiveInterval &li,
const MachineBasicBlock *mbb) const {
return li.liveAt(getMBBStartIdx(mbb));
}
LiveRange* findEnteringRange(LiveInterval &li,
const MachineBasicBlock *mbb) {
return li.getLiveRangeContaining(getMBBStartIdx(mbb));
}
bool isLiveOutOfMBB(const LiveInterval &li,
const MachineBasicBlock *mbb) const {
return li.liveAt(getMBBEndIdx(mbb).getPrevSlot());
}
LiveRange* findExitingRange(LiveInterval &li,
const MachineBasicBlock *mbb) {
return li.getLiveRangeContaining(getMBBEndIdx(mbb).getPrevSlot());
}
MachineBasicBlock* getMBBFromIndex(SlotIndex index) const { MachineBasicBlock* getMBBFromIndex(SlotIndex index) const {
return indexes_->getMBBFromIndex(index); return indexes_->getMBBFromIndex(index);
@ -217,6 +243,10 @@ namespace llvm {
indexes_->replaceMachineInstrInMaps(MI, NewMI); indexes_->replaceMachineInstrInMaps(MI, NewMI);
} }
void InsertMBBInMaps(MachineBasicBlock *MBB) {
indexes_->insertMBBInMaps(MBB);
}
bool findLiveInMBBs(SlotIndex Start, SlotIndex End, bool findLiveInMBBs(SlotIndex Start, SlotIndex End,
SmallVectorImpl<MachineBasicBlock*> &MBBs) const { SmallVectorImpl<MachineBasicBlock*> &MBBs) const {
return indexes_->findLiveInMBBs(Start, End, MBBs); return indexes_->findLiveInMBBs(Start, End, MBBs);
@ -276,7 +306,7 @@ namespace llvm {
/// within a single basic block. /// within a single basic block.
bool intervalIsInOneMBB(const LiveInterval &li) const; bool intervalIsInOneMBB(const LiveInterval &li) const;
private: private:
/// computeIntervals - Compute live intervals. /// computeIntervals - Compute live intervals.
void computeIntervals(); void computeIntervals();
@ -290,7 +320,7 @@ namespace llvm {
/// isPartialRedef - Return true if the specified def at the specific index /// isPartialRedef - Return true if the specified def at the specific index
/// is partially re-defining the specified live interval. A common case of /// is partially re-defining the specified live interval. A common case of
/// this is a definition of the sub-register. /// this is a definition of the sub-register.
bool isPartialRedef(SlotIndex MIIdx, MachineOperand &MO, bool isPartialRedef(SlotIndex MIIdx, MachineOperand &MO,
LiveInterval &interval); LiveInterval &interval);

View File

@ -39,7 +39,7 @@ namespace llvm {
public: public:
static char ID; // Pass identification, replacement for typeid static char ID; // Pass identification, replacement for typeid
LiveStacks() : MachineFunctionPass(&ID) {} LiveStacks() : MachineFunctionPass(ID) {}
typedef SS2IntervalMap::iterator iterator; typedef SS2IntervalMap::iterator iterator;
typedef SS2IntervalMap::const_iterator const_iterator; typedef SS2IntervalMap::const_iterator const_iterator;

View File

@ -46,7 +46,7 @@ class TargetRegisterInfo;
class LiveVariables : public MachineFunctionPass { class LiveVariables : public MachineFunctionPass {
public: public:
static char ID; // Pass identification, replacement for typeid static char ID; // Pass identification, replacement for typeid
LiveVariables() : MachineFunctionPass(&ID) {} LiveVariables() : MachineFunctionPass(ID) {}
/// VarInfo - This represents the regions where a virtual register is live in /// VarInfo - This represents the regions where a virtual register is live in
/// the program. We represent this with three different pieces of /// the program. We represent this with three different pieces of

View File

@ -15,6 +15,7 @@
#define LLVM_CODEGEN_MACHINEFRAMEINFO_H #define LLVM_CODEGEN_MACHINEFRAMEINFO_H
#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/SmallVector.h"
//#include "llvm/ADT/IndexedMap.h"
#include "llvm/System/DataTypes.h" #include "llvm/System/DataTypes.h"
#include <cassert> #include <cassert>
#include <vector> #include <vector>
@ -30,15 +31,15 @@ class TargetFrameInfo;
class BitVector; class BitVector;
/// The CalleeSavedInfo class tracks the information need to locate where a /// The CalleeSavedInfo class tracks the information need to locate where a
/// callee saved register in the current frame. /// callee saved register is in the current frame.
class CalleeSavedInfo { class CalleeSavedInfo {
unsigned Reg; unsigned Reg;
int FrameIdx; int FrameIdx;
public: public:
explicit CalleeSavedInfo(unsigned R, int FI = 0) explicit CalleeSavedInfo(unsigned R, int FI = 0)
: Reg(R), FrameIdx(FI) {} : Reg(R), FrameIdx(FI) {}
// Accessors. // Accessors.
unsigned getReg() const { return Reg; } unsigned getReg() const { return Reg; }
int getFrameIdx() const { return FrameIdx; } int getFrameIdx() const { return FrameIdx; }
@ -81,7 +82,7 @@ class MachineFrameInfo {
// SPOffset - The offset of this object from the stack pointer on entry to // SPOffset - The offset of this object from the stack pointer on entry to
// the function. This field has no meaning for a variable sized element. // the function. This field has no meaning for a variable sized element.
int64_t SPOffset; int64_t SPOffset;
// The size of this object on the stack. 0 means a variable sized object, // The size of this object on the stack. 0 means a variable sized object,
// ~0ULL means a dead object. // ~0ULL means a dead object.
uint64_t Size; uint64_t Size;
@ -94,13 +95,23 @@ class MachineFrameInfo {
// default, fixed objects are immutable unless marked otherwise. // default, fixed objects are immutable unless marked otherwise.
bool isImmutable; bool isImmutable;
// isSpillSlot - If true, the stack object is used as spill slot. It // isSpillSlot - If true the stack object is used as spill slot. It
// cannot alias any other memory objects. // cannot alias any other memory objects.
bool isSpillSlot; bool isSpillSlot;
StackObject(uint64_t Sz, unsigned Al, int64_t SP, bool IM, bool isSS) // MayNeedSP - If true the stack object triggered the creation of the stack
// protector. We should allocate this object right after the stack
// protector.
bool MayNeedSP;
// PreAllocated - If true, the object was mapped into the local frame
// block and doesn't need additional handling for allocation beyond that.
bool PreAllocated;
StackObject(uint64_t Sz, unsigned Al, int64_t SP, bool IM,
bool isSS, bool NSP)
: SPOffset(SP), Size(Sz), Alignment(Al), isImmutable(IM), : SPOffset(SP), Size(Sz), Alignment(Al), isImmutable(IM),
isSpillSlot(isSS) {} isSpillSlot(isSS), MayNeedSP(NSP), PreAllocated(false) {}
}; };
/// Objects - The list of stack objects allocated... /// Objects - The list of stack objects allocated...
@ -132,7 +143,7 @@ class MachineFrameInfo {
/// to be allocated on entry to the function. /// to be allocated on entry to the function.
/// ///
uint64_t StackSize; uint64_t StackSize;
/// OffsetAdjustment - The amount that a frame offset needs to be adjusted to /// OffsetAdjustment - The amount that a frame offset needs to be adjusted to
/// have the actual offset from the stack/frame pointer. The exact usage of /// have the actual offset from the stack/frame pointer. The exact usage of
/// this is target-dependent, but it is typically used to adjust between /// this is target-dependent, but it is typically used to adjust between
@ -143,10 +154,10 @@ class MachineFrameInfo {
/// TargetRegisterInfo::getFrameIndexOffset); when generating code, the /// TargetRegisterInfo::getFrameIndexOffset); when generating code, the
/// corresponding adjustments are performed directly. /// corresponding adjustments are performed directly.
int OffsetAdjustment; int OffsetAdjustment;
/// MaxAlignment - The prolog/epilog code inserter may process objects /// MaxAlignment - The prolog/epilog code inserter may process objects
/// that require greater alignment than the default alignment the target /// that require greater alignment than the default alignment the target
/// provides. To handle this, MaxAlignment is set to the maximum alignment /// provides. To handle this, MaxAlignment is set to the maximum alignment
/// needed by the objects on the current frame. If this is greater than the /// needed by the objects on the current frame. If this is greater than the
/// native alignment maintained by the compiler, dynamic alignment code will /// native alignment maintained by the compiler, dynamic alignment code will
/// be needed. /// be needed.
@ -171,7 +182,7 @@ class MachineFrameInfo {
/// insertion. /// insertion.
/// ///
unsigned MaxCallFrameSize; unsigned MaxCallFrameSize;
/// CSInfo - The prolog/epilog code inserter fills in this vector with each /// CSInfo - The prolog/epilog code inserter fills in this vector with each
/// callee saved register saved in the frame. Beyond its use by the prolog/ /// callee saved register saved in the frame. Beyond its use by the prolog/
/// epilog code inserter, this data used for debug info and exception /// epilog code inserter, this data used for debug info and exception
@ -189,8 +200,24 @@ class MachineFrameInfo {
/// ///
const TargetFrameInfo &TFI; const TargetFrameInfo &TFI;
/// LocalFrameObjects - References to frame indices which are mapped
/// into the local frame allocation block. <FrameIdx, LocalOffset>
SmallVector<std::pair<int, int64_t>, 32> LocalFrameObjects;
/// LocalFrameSize - Size of the pre-allocated local frame block.
int64_t LocalFrameSize;
/// Required alignment of the local object blob, which is the strictest
/// alignment of any object in it.
unsigned LocalFrameMaxAlign;
/// Whether the local object blob needs to be allocated together. If not,
/// PEI should ignore the isPreAllocated flags on the stack objects and
/// just allocate them normally.
bool UseLocalStackAllocationBlock;
public: public:
explicit MachineFrameInfo(const TargetFrameInfo &tfi) : TFI(tfi) { explicit MachineFrameInfo(const TargetFrameInfo &tfi) : TFI(tfi) {
StackSize = NumFixedObjects = OffsetAdjustment = MaxAlignment = 0; StackSize = NumFixedObjects = OffsetAdjustment = MaxAlignment = 0;
HasVarSizedObjects = false; HasVarSizedObjects = false;
FrameAddressTaken = false; FrameAddressTaken = false;
@ -200,6 +227,9 @@ public:
StackProtectorIdx = -1; StackProtectorIdx = -1;
MaxCallFrameSize = 0; MaxCallFrameSize = 0;
CSIValid = false; CSIValid = false;
LocalFrameSize = 0;
LocalFrameMaxAlign = 0;
UseLocalStackAllocationBlock = false;
} }
/// hasStackObjects - Return true if there are any stack objects in this /// hasStackObjects - Return true if there are any stack objects in this
@ -225,8 +255,8 @@ public:
bool isFrameAddressTaken() const { return FrameAddressTaken; } bool isFrameAddressTaken() const { return FrameAddressTaken; }
void setFrameAddressIsTaken(bool T) { FrameAddressTaken = T; } void setFrameAddressIsTaken(bool T) { FrameAddressTaken = T; }
/// isReturnAddressTaken - This method may be called any time after instruction /// isReturnAddressTaken - This method may be called any time after
/// selection is complete to determine if there is a call to /// instruction selection is complete to determine if there is a call to
/// \@llvm.returnaddress in this function. /// \@llvm.returnaddress in this function.
bool isReturnAddressTaken() const { return ReturnAddressTaken; } bool isReturnAddressTaken() const { return ReturnAddressTaken; }
void setReturnAddressIsTaken(bool s) { ReturnAddressTaken = s; } void setReturnAddressIsTaken(bool s) { ReturnAddressTaken = s; }
@ -239,13 +269,64 @@ public:
/// ///
int getObjectIndexEnd() const { return (int)Objects.size()-NumFixedObjects; } int getObjectIndexEnd() const { return (int)Objects.size()-NumFixedObjects; }
/// getNumFixedObjects() - Return the number of fixed objects. /// getNumFixedObjects - Return the number of fixed objects.
unsigned getNumFixedObjects() const { return NumFixedObjects; } unsigned getNumFixedObjects() const { return NumFixedObjects; }
/// getNumObjects() - Return the number of objects. /// getNumObjects - Return the number of objects.
/// ///
unsigned getNumObjects() const { return Objects.size(); } unsigned getNumObjects() const { return Objects.size(); }
/// mapLocalFrameObject - Map a frame index into the local object block
void mapLocalFrameObject(int ObjectIndex, int64_t Offset) {
LocalFrameObjects.push_back(std::pair<int, int64_t>(ObjectIndex, Offset));
Objects[ObjectIndex + NumFixedObjects].PreAllocated = true;
}
/// getLocalFrameObjectMap - Get the local offset mapping for a for an object
std::pair<int, int64_t> getLocalFrameObjectMap(int i) {
assert (i >= 0 && (unsigned)i < LocalFrameObjects.size() &&
"Invalid local object reference!");
return LocalFrameObjects[i];
}
/// getLocalFrameObjectCount - Return the number of objects allocated into
/// the local object block.
int64_t getLocalFrameObjectCount() { return LocalFrameObjects.size(); }
/// setLocalFrameSize - Set the size of the local object blob.
void setLocalFrameSize(int64_t sz) { LocalFrameSize = sz; }
/// getLocalFrameSize - Get the size of the local object blob.
int64_t getLocalFrameSize() const { return LocalFrameSize; }
/// setLocalFrameMaxAlign - Required alignment of the local object blob,
/// which is the strictest alignment of any object in it.
void setLocalFrameMaxAlign(unsigned Align) { LocalFrameMaxAlign = Align; }
/// getLocalFrameMaxAlign - Return the required alignment of the local
/// object blob.
unsigned getLocalFrameMaxAlign() const { return LocalFrameMaxAlign; }
/// getUseLocalStackAllocationBlock - Get whether the local allocation blob
/// should be allocated together or let PEI allocate the locals in it
/// directly.
bool getUseLocalStackAllocationBlock() {return UseLocalStackAllocationBlock;}
/// setUseLocalStackAllocationBlock - Set whether the local allocation blob
/// should be allocated together or let PEI allocate the locals in it
/// directly.
void setUseLocalStackAllocationBlock(bool v) {
UseLocalStackAllocationBlock = v;
}
/// isObjectPreAllocated - Return true if the object was pre-allocated into
/// the local block.
bool isObjectPreAllocated(int ObjectIdx) const {
assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
"Invalid Object Idx!");
return Objects[ObjectIdx+NumFixedObjects].PreAllocated;
}
/// getObjectSize - Return the size of the specified object. /// getObjectSize - Return the size of the specified object.
/// ///
int64_t getObjectSize(int ObjectIdx) const { int64_t getObjectSize(int ObjectIdx) const {
@ -276,6 +357,14 @@ public:
MaxAlignment = std::max(MaxAlignment, Align); MaxAlignment = std::max(MaxAlignment, Align);
} }
/// NeedsStackProtector - Returns true if the object may need stack
/// protectors.
bool MayNeedStackProtector(int ObjectIdx) const {
assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
"Invalid Object Idx!");
return Objects[ObjectIdx+NumFixedObjects].MayNeedSP;
}
/// getObjectOffset - Return the assigned stack offset of the specified object /// getObjectOffset - Return the assigned stack offset of the specified object
/// from the incoming stack pointer. /// from the incoming stack pointer.
/// ///
@ -307,21 +396,21 @@ public:
/// setStackSize - Set the size of the stack... /// setStackSize - Set the size of the stack...
/// ///
void setStackSize(uint64_t Size) { StackSize = Size; } void setStackSize(uint64_t Size) { StackSize = Size; }
/// getOffsetAdjustment - Return the correction for frame offsets. /// getOffsetAdjustment - Return the correction for frame offsets.
/// ///
int getOffsetAdjustment() const { return OffsetAdjustment; } int getOffsetAdjustment() const { return OffsetAdjustment; }
/// setOffsetAdjustment - Set the correction for frame offsets. /// setOffsetAdjustment - Set the correction for frame offsets.
/// ///
void setOffsetAdjustment(int Adj) { OffsetAdjustment = Adj; } void setOffsetAdjustment(int Adj) { OffsetAdjustment = Adj; }
/// getMaxAlignment - Return the alignment in bytes that this function must be /// getMaxAlignment - Return the alignment in bytes that this function must be
/// aligned to, which is greater than the default stack alignment provided by /// aligned to, which is greater than the default stack alignment provided by
/// the target. /// the target.
/// ///
unsigned getMaxAlignment() const { return MaxAlignment; } unsigned getMaxAlignment() const { return MaxAlignment; }
/// setMaxAlignment - Set the preferred alignment. /// setMaxAlignment - Set the preferred alignment.
/// ///
void setMaxAlignment(unsigned Align) { MaxAlignment = Align; } void setMaxAlignment(unsigned Align) { MaxAlignment = Align; }
@ -350,8 +439,8 @@ public:
/// index with a negative value. /// index with a negative value.
/// ///
int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool Immutable); int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool Immutable);
/// isFixedObjectIndex - Returns true if the specified index corresponds to a /// isFixedObjectIndex - Returns true if the specified index corresponds to a
/// fixed stack object. /// fixed stack object.
bool isFixedObjectIndex(int ObjectIdx) const { bool isFixedObjectIndex(int ObjectIdx) const {
@ -382,25 +471,26 @@ public:
return Objects[ObjectIdx+NumFixedObjects].Size == ~0ULL; return Objects[ObjectIdx+NumFixedObjects].Size == ~0ULL;
} }
/// CreateStackObject - Create a new statically sized stack object, /// CreateStackObject - Create a new statically sized stack object, returning
/// returning a nonnegative identifier to represent it. /// a nonnegative identifier to represent it.
/// ///
int CreateStackObject(uint64_t Size, unsigned Alignment, bool isSS) { int CreateStackObject(uint64_t Size, unsigned Alignment, bool isSS,
bool MayNeedSP = false) {
assert(Size != 0 && "Cannot allocate zero size stack objects!"); assert(Size != 0 && "Cannot allocate zero size stack objects!");
Objects.push_back(StackObject(Size, Alignment, 0, false, isSS)); Objects.push_back(StackObject(Size, Alignment, 0, false, isSS, MayNeedSP));
int Index = (int)Objects.size()-NumFixedObjects-1; int Index = (int)Objects.size() - NumFixedObjects - 1;
assert(Index >= 0 && "Bad frame index!"); assert(Index >= 0 && "Bad frame index!");
MaxAlignment = std::max(MaxAlignment, Alignment); MaxAlignment = std::max(MaxAlignment, Alignment);
return Index; return Index;
} }
/// CreateSpillStackObject - Create a new statically sized stack /// CreateSpillStackObject - Create a new statically sized stack object that
/// object that represents a spill slot, returning a nonnegative /// represents a spill slot, returning a nonnegative identifier to represent
/// identifier to represent it. /// it.
/// ///
int CreateSpillStackObject(uint64_t Size, unsigned Alignment) { int CreateSpillStackObject(uint64_t Size, unsigned Alignment) {
CreateStackObject(Size, Alignment, true); CreateStackObject(Size, Alignment, true, false);
int Index = (int)Objects.size()-NumFixedObjects-1; int Index = (int)Objects.size() - NumFixedObjects - 1;
MaxAlignment = std::max(MaxAlignment, Alignment); MaxAlignment = std::max(MaxAlignment, Alignment);
return Index; return Index;
} }
@ -417,9 +507,10 @@ public:
/// variable sized object is created, whether or not the index returned is /// variable sized object is created, whether or not the index returned is
/// actually used. /// actually used.
/// ///
int CreateVariableSizedObject() { int CreateVariableSizedObject(unsigned Alignment) {
HasVarSizedObjects = true; HasVarSizedObjects = true;
Objects.push_back(StackObject(0, 1, 0, false, false)); Objects.push_back(StackObject(0, Alignment, 0, false, false, true));
MaxAlignment = std::max(MaxAlignment, Alignment);
return (int)Objects.size()-NumFixedObjects-1; return (int)Objects.size()-NumFixedObjects-1;
} }
@ -431,7 +522,7 @@ public:
/// setCalleeSavedInfo - Used by prolog/epilog inserter to set the function's /// setCalleeSavedInfo - Used by prolog/epilog inserter to set the function's
/// callee saved information. /// callee saved information.
void setCalleeSavedInfo(const std::vector<CalleeSavedInfo> &CSI) { void setCalleeSavedInfo(const std::vector<CalleeSavedInfo> &CSI) {
CSInfo = CSI; CSInfo = CSI;
} }
@ -452,7 +543,7 @@ public:
BitVector getPristineRegs(const MachineBasicBlock *MBB) const; BitVector getPristineRegs(const MachineBasicBlock *MBB) const;
/// print - Used by the MachineFunction printer to print information about /// print - Used by the MachineFunction printer to print information about
/// stack objects. Implemented in MachineFunction.cpp /// stack objects. Implemented in MachineFunction.cpp
/// ///
void print(const MachineFunction &MF, raw_ostream &OS) const; void print(const MachineFunction &MF, raw_ostream &OS) const;

View File

@ -266,7 +266,7 @@ public:
/// verify - Run the current MachineFunction through the machine code /// verify - Run the current MachineFunction through the machine code
/// verifier, useful for debugger use. /// verifier, useful for debugger use.
void verify(Pass *p=NULL, bool allowDoubleDefs=false) const; void verify(Pass *p=NULL) const;
// Provide accessors for the MachineBasicBlock list... // Provide accessors for the MachineBasicBlock list...
typedef BasicBlockListType::iterator iterator; typedef BasicBlockListType::iterator iterator;

View File

@ -31,8 +31,7 @@ class MachineFunction;
/// override runOnMachineFunction. /// override runOnMachineFunction.
class MachineFunctionPass : public FunctionPass { class MachineFunctionPass : public FunctionPass {
protected: protected:
explicit MachineFunctionPass(intptr_t ID) : FunctionPass(ID) {} explicit MachineFunctionPass(char &ID) : FunctionPass(ID) {}
explicit MachineFunctionPass(void *ID) : FunctionPass(ID) {}
/// runOnMachineFunction - This method must be overloaded to perform the /// runOnMachineFunction - This method must be overloaded to perform the
/// desired machine code transformation or analysis. /// desired machine code transformation or analysis.

View File

@ -201,12 +201,14 @@ public:
/// isLabel - Returns true if the MachineInstr represents a label. /// isLabel - Returns true if the MachineInstr represents a label.
/// ///
bool isLabel() const { bool isLabel() const {
return getOpcode() == TargetOpcode::DBG_LABEL || return getOpcode() == TargetOpcode::PROLOG_LABEL ||
getOpcode() == TargetOpcode::EH_LABEL || getOpcode() == TargetOpcode::EH_LABEL ||
getOpcode() == TargetOpcode::GC_LABEL; getOpcode() == TargetOpcode::GC_LABEL;
} }
bool isDebugLabel() const { return getOpcode() == TargetOpcode::DBG_LABEL; } bool isPrologLabel() const {
return getOpcode() == TargetOpcode::PROLOG_LABEL;
}
bool isEHLabel() const { return getOpcode() == TargetOpcode::EH_LABEL; } bool isEHLabel() const { return getOpcode() == TargetOpcode::EH_LABEL; }
bool isGCLabel() const { return getOpcode() == TargetOpcode::GC_LABEL; } bool isGCLabel() const { return getOpcode() == TargetOpcode::GC_LABEL; }
bool isDebugValue() const { return getOpcode() == TargetOpcode::DBG_VALUE; } bool isDebugValue() const { return getOpcode() == TargetOpcode::DBG_VALUE; }

View File

@ -67,7 +67,7 @@ class MachineLoopInfo : public MachineFunctionPass {
public: public:
static char ID; // Pass identification, replacement for typeid static char ID; // Pass identification, replacement for typeid
MachineLoopInfo() : MachineFunctionPass(&ID) {} MachineLoopInfo() : MachineFunctionPass(ID) {}
LoopInfoBase<MachineBasicBlock, MachineLoop>& getBase() { return LI; } LoopInfoBase<MachineBasicBlock, MachineLoop>& getBase() { return LI; }

View File

@ -344,7 +344,7 @@ public:
VariableDbgInfo.push_back(std::make_pair(N, std::make_pair(Slot, Loc))); VariableDbgInfo.push_back(std::make_pair(N, std::make_pair(Slot, Loc)));
} }
VariableDbgInfoMapTy &getVariableDbgInfo(); VariableDbgInfoMapTy &getVariableDbgInfo() { return VariableDbgInfo; }
}; // End class MachineModuleInfo }; // End class MachineModuleInfo

View File

@ -30,55 +30,55 @@ namespace llvm {
/// createUnreachableBlockEliminationPass - The LLVM code generator does not /// createUnreachableBlockEliminationPass - The LLVM code generator does not
/// work well with unreachable basic blocks (what live ranges make sense for a /// work well with unreachable basic blocks (what live ranges make sense for a
/// block that cannot be reached?). As such, a code generator should either /// block that cannot be reached?). As such, a code generator should either
/// not instruction select unreachable blocks, or it can run this pass as it's /// not instruction select unreachable blocks, or run this pass as its
/// last LLVM modifying pass to clean up blocks that are not reachable from /// last LLVM modifying pass to clean up blocks that are not reachable from
/// the entry block. /// the entry block.
FunctionPass *createUnreachableBlockEliminationPass(); FunctionPass *createUnreachableBlockEliminationPass();
/// MachineFunctionPrinter pass - This pass prints out the machine function to /// MachineFunctionPrinter pass - This pass prints out the machine function to
/// the given stream, as a debugging tool. /// the given stream as a debugging tool.
MachineFunctionPass * MachineFunctionPass *
createMachineFunctionPrinterPass(raw_ostream &OS, createMachineFunctionPrinterPass(raw_ostream &OS,
const std::string &Banner =""); const std::string &Banner ="");
/// MachineLoopInfo pass - This pass is a loop analysis pass. /// MachineLoopInfo pass - This pass is a loop analysis pass.
/// ///
extern const PassInfo *const MachineLoopInfoID; extern char &MachineLoopInfoID;
/// MachineDominators pass - This pass is a machine dominators analysis pass. /// MachineDominators pass - This pass is a machine dominators analysis pass.
/// ///
extern const PassInfo *const MachineDominatorsID; extern char &MachineDominatorsID;
/// PHIElimination pass - This pass eliminates machine instruction PHI nodes /// PHIElimination pass - This pass eliminates machine instruction PHI nodes
/// by inserting copy instructions. This destroys SSA information, but is the /// by inserting copy instructions. This destroys SSA information, but is the
/// desired input for some register allocators. This pass is "required" by /// desired input for some register allocators. This pass is "required" by
/// these register allocator like this: AU.addRequiredID(PHIEliminationID); /// these register allocator like this: AU.addRequiredID(PHIEliminationID);
/// ///
extern const PassInfo *const PHIEliminationID; extern char &PHIEliminationID;
/// StrongPHIElimination pass - This pass eliminates machine instruction PHI /// StrongPHIElimination pass - This pass eliminates machine instruction PHI
/// nodes by inserting copy instructions. This destroys SSA information, but /// nodes by inserting copy instructions. This destroys SSA information, but
/// is the desired input for some register allocators. This pass is /// is the desired input for some register allocators. This pass is
/// "required" by these register allocator like this: /// "required" by these register allocator like this:
/// AU.addRequiredID(PHIEliminationID); /// AU.addRequiredID(PHIEliminationID);
/// This pass is still in development /// This pass is still in development
extern const PassInfo *const StrongPHIEliminationID; extern char &StrongPHIEliminationID;
extern const PassInfo *const PreAllocSplittingID; extern char &PreAllocSplittingID;
/// SimpleRegisterCoalescing pass. Aggressively coalesces every register /// SimpleRegisterCoalescing pass. Aggressively coalesces every register
/// copy it can. /// copy it can.
/// ///
extern const PassInfo *const SimpleRegisterCoalescingID; extern char &SimpleRegisterCoalescingID;
/// TwoAddressInstruction pass - This pass reduces two-address instructions to /// TwoAddressInstruction pass - This pass reduces two-address instructions to
/// use two operands. This destroys SSA information but it is desired by /// use two operands. This destroys SSA information but it is desired by
/// register allocators. /// register allocators.
extern const PassInfo *const TwoAddressInstructionPassID; extern char &TwoAddressInstructionPassID;
/// UnreachableMachineBlockElimination pass - This pass removes unreachable /// UnreachableMachineBlockElimination pass - This pass removes unreachable
/// machine basic blocks. /// machine basic blocks.
extern const PassInfo *const UnreachableMachineBlockElimID; extern char &UnreachableMachineBlockElimID;
/// DeadMachineInstructionElim pass - This pass removes dead machine /// DeadMachineInstructionElim pass - This pass removes dead machine
/// instructions. /// instructions.
@ -114,7 +114,7 @@ namespace llvm {
/// and eliminates abstract frame references. /// and eliminates abstract frame references.
/// ///
FunctionPass *createPrologEpilogCodeInserter(); FunctionPass *createPrologEpilogCodeInserter();
/// LowerSubregs Pass - This pass lowers subregs to register-register copies /// LowerSubregs Pass - This pass lowers subregs to register-register copies
/// which yields suboptimal, but correct code if the register allocator /// which yields suboptimal, but correct code if the register allocator
/// cannot coalesce all subreg operations during allocation. /// cannot coalesce all subreg operations during allocation.
@ -145,36 +145,36 @@ namespace llvm {
/// IntrinsicLowering Pass - Performs target-independent LLVM IR /// IntrinsicLowering Pass - Performs target-independent LLVM IR
/// transformations for highly portable strategies. /// transformations for highly portable strategies.
FunctionPass *createGCLoweringPass(); FunctionPass *createGCLoweringPass();
/// MachineCodeAnalysis Pass - Target-independent pass to mark safe points in /// MachineCodeAnalysis Pass - Target-independent pass to mark safe points in
/// machine code. Must be added very late during code generation, just prior /// machine code. Must be added very late during code generation, just prior
/// to output, and importantly after all CFG transformations (such as branch /// to output, and importantly after all CFG transformations (such as branch
/// folding). /// folding).
FunctionPass *createGCMachineCodeAnalysisPass(); FunctionPass *createGCMachineCodeAnalysisPass();
/// Deleter Pass - Releases GC metadata. /// Deleter Pass - Releases GC metadata.
/// ///
FunctionPass *createGCInfoDeleter(); FunctionPass *createGCInfoDeleter();
/// Creates a pass to print GC metadata. /// Creates a pass to print GC metadata.
/// ///
FunctionPass *createGCInfoPrinter(raw_ostream &OS); FunctionPass *createGCInfoPrinter(raw_ostream &OS);
/// createMachineCSEPass - This pass performs global CSE on machine /// createMachineCSEPass - This pass performs global CSE on machine
/// instructions. /// instructions.
FunctionPass *createMachineCSEPass(); FunctionPass *createMachineCSEPass();
/// createMachineLICMPass - This pass performs LICM on machine instructions. /// createMachineLICMPass - This pass performs LICM on machine instructions.
/// ///
FunctionPass *createMachineLICMPass(bool PreRegAlloc = true); FunctionPass *createMachineLICMPass(bool PreRegAlloc = true);
/// createMachineSinkingPass - This pass performs sinking on machine /// createMachineSinkingPass - This pass performs sinking on machine
/// instructions. /// instructions.
FunctionPass *createMachineSinkingPass(); FunctionPass *createMachineSinkingPass();
/// createOptimizeExtsPass - This pass performs sign / zero extension /// createPeepholeOptimizerPass - This pass performs peephole optimizations -
/// optimization by increasing uses of extended values. /// like extension and comparison eliminations.
FunctionPass *createOptimizeExtsPass(); FunctionPass *createPeepholeOptimizerPass();
/// createOptimizePHIsPass - This pass optimizes machine instruction PHIs /// createOptimizePHIsPass - This pass optimizes machine instruction PHIs
/// to take advantage of opportunities created during DAG legalization. /// to take advantage of opportunities created during DAG legalization.
@ -188,19 +188,23 @@ namespace llvm {
/// createMachineVerifierPass - This pass verifies cenerated machine code /// createMachineVerifierPass - This pass verifies cenerated machine code
/// instructions for correctness. /// instructions for correctness.
/// FunctionPass *createMachineVerifierPass();
/// @param allowDoubleDefs ignore double definitions of
/// registers. Useful before LiveVariables has run.
FunctionPass *createMachineVerifierPass(bool allowDoubleDefs);
/// createDwarfEHPass - This pass mulches exception handling code into a form /// createDwarfEHPass - This pass mulches exception handling code into a form
/// adapted to code generation. Required if using dwarf exception handling. /// adapted to code generation. Required if using dwarf exception handling.
FunctionPass *createDwarfEHPass(const TargetMachine *tm, bool fast); FunctionPass *createDwarfEHPass(const TargetMachine *tm);
/// createSjLjEHPass - This pass adapts exception handling code to use /// createSjLjEHPass - This pass adapts exception handling code to use
/// the GCC-style builtin setjmp/longjmp (sjlj) to handling EH control flow. /// the GCC-style builtin setjmp/longjmp (sjlj) to handling EH control flow.
FunctionPass *createSjLjEHPass(const TargetLowering *tli); FunctionPass *createSjLjEHPass(const TargetLowering *tli);
/// createLocalStackSlotAllocationPass - This pass assigns local frame
/// indices to stack slots relative to one another and allocates
/// base registers to access them when it is estimated by the target to
/// be out of range of normal frame pointer or stack pointer index
/// addressing.
FunctionPass *createLocalStackSlotAllocationPass();
} // End llvm namespace } // End llvm namespace
#endif #endif

View File

@ -31,7 +31,7 @@ namespace llvm {
public: public:
static char ID; static char ID;
ProcessImplicitDefs() : MachineFunctionPass(&ID) {} ProcessImplicitDefs() : MachineFunctionPass(ID) {}
virtual void getAnalysisUsage(AnalysisUsage &au) const; virtual void getAnalysisUsage(AnalysisUsage &au) const;

View File

@ -78,12 +78,19 @@ ScheduleDAGSDNodes *createTDRRListDAGScheduler(SelectionDAGISel *IS,
ScheduleDAGSDNodes *createSourceListDAGScheduler(SelectionDAGISel *IS, ScheduleDAGSDNodes *createSourceListDAGScheduler(SelectionDAGISel *IS,
CodeGenOpt::Level OptLevel); CodeGenOpt::Level OptLevel);
/// createHybridListDAGScheduler - This creates a bottom up hybrid register /// createHybridListDAGScheduler - This creates a bottom up register pressure
/// usage reduction list scheduler that make use of latency information to /// aware list scheduler that make use of latency information to avoid stalls
/// avoid stalls for long latency instructions. /// for long latency instructions in low register pressure mode. In high
/// register pressure mode it schedules to reduce register pressure.
ScheduleDAGSDNodes *createHybridListDAGScheduler(SelectionDAGISel *IS, ScheduleDAGSDNodes *createHybridListDAGScheduler(SelectionDAGISel *IS,
CodeGenOpt::Level); CodeGenOpt::Level);
/// createILPListDAGScheduler - This creates a bottom up register pressure
/// aware list scheduler that tries to increase instruction level parallelism
/// in low register pressure mode. In high register pressure mode it schedules
/// to reduce register pressure.
ScheduleDAGSDNodes *createILPListDAGScheduler(SelectionDAGISel *IS,
CodeGenOpt::Level);
/// createTDListDAGScheduler - This creates a top-down list scheduler with /// createTDListDAGScheduler - This creates a top-down list scheduler with
/// a hazard recognizer. /// a hazard recognizer.
ScheduleDAGSDNodes *createTDListDAGScheduler(SelectionDAGISel *IS, ScheduleDAGSDNodes *createTDListDAGScheduler(SelectionDAGISel *IS,

View File

@ -977,10 +977,6 @@ public:
/// been verified as a debug information descriptor. /// been verified as a debug information descriptor.
bool isVerifiedDebugInfoDesc(SDValue Op) const; bool isVerifiedDebugInfoDesc(SDValue Op) const;
/// getShuffleScalarElt - Returns the scalar element that will make up the ith
/// element of the result of the vector shuffle.
SDValue getShuffleScalarElt(const ShuffleVectorSDNode *N, unsigned Idx);
/// UnrollVectorOp - Utility function used by legalize and lowering to /// UnrollVectorOp - Utility function used by legalize and lowering to
/// "unroll" a vector operation by splitting out the scalars and operating /// "unroll" a vector operation by splitting out the scalars and operating
/// on each element individually. If the ResNE is 0, fully unroll the vector /// on each element individually. If the ResNE is 0, fully unroll the vector

View File

@ -128,7 +128,8 @@ namespace llvm {
friend class SlotIndexes; friend class SlotIndexes;
friend struct DenseMapInfo<SlotIndex>; friend struct DenseMapInfo<SlotIndex>;
private: enum Slot { LOAD, USE, DEF, STORE, NUM };
static const unsigned PHI_BIT = 1 << 2; static const unsigned PHI_BIT = 1 << 2;
PointerIntPair<IndexListEntry*, 3, unsigned> lie; PointerIntPair<IndexListEntry*, 3, unsigned> lie;
@ -146,6 +147,11 @@ namespace llvm {
return entry().getIndex() | getSlot(); return entry().getIndex() | getSlot();
} }
/// Returns the slot for this SlotIndex.
Slot getSlot() const {
return static_cast<Slot>(lie.getInt() & ~PHI_BIT);
}
static inline unsigned getHashValue(const SlotIndex &v) { static inline unsigned getHashValue(const SlotIndex &v) {
IndexListEntry *ptrVal = &v.entry(); IndexListEntry *ptrVal = &v.entry();
return (unsigned((intptr_t)ptrVal) >> 4) ^ return (unsigned((intptr_t)ptrVal) >> 4) ^
@ -153,11 +159,6 @@ namespace llvm {
} }
public: public:
// FIXME: Ugh. This is public because LiveIntervalAnalysis is still using it
// for some spill weight stuff. Fix that, then make this private.
enum Slot { LOAD, USE, DEF, STORE, NUM };
static inline SlotIndex getEmptyKey() { static inline SlotIndex getEmptyKey() {
return SlotIndex(IndexListEntry::getEmptyKeyEntry(), 0); return SlotIndex(IndexListEntry::getEmptyKeyEntry(), 0);
} }
@ -235,16 +236,31 @@ namespace llvm {
return other.getIndex() - getIndex(); return other.getIndex() - getIndex();
} }
/// Returns the slot for this SlotIndex.
Slot getSlot() const {
return static_cast<Slot>(lie.getInt() & ~PHI_BIT);
}
/// Returns the state of the PHI bit. /// Returns the state of the PHI bit.
bool isPHI() const { bool isPHI() const {
return lie.getInt() & PHI_BIT; return lie.getInt() & PHI_BIT;
} }
/// isLoad - Return true if this is a LOAD slot.
bool isLoad() const {
return getSlot() == LOAD;
}
/// isDef - Return true if this is a DEF slot.
bool isDef() const {
return getSlot() == DEF;
}
/// isUse - Return true if this is a USE slot.
bool isUse() const {
return getSlot() == USE;
}
/// isStore - Return true if this is a STORE slot.
bool isStore() const {
return getSlot() == STORE;
}
/// Returns the base index for associated with this index. The base index /// Returns the base index for associated with this index. The base index
/// is the one associated with the LOAD slot for the instruction pointed to /// is the one associated with the LOAD slot for the instruction pointed to
/// by this index. /// by this index.
@ -475,7 +491,7 @@ namespace llvm {
public: public:
static char ID; static char ID;
SlotIndexes() : MachineFunctionPass(&ID), indexListHead(0) {} SlotIndexes() : MachineFunctionPass(ID), indexListHead(0) {}
virtual void getAnalysisUsage(AnalysisUsage &au) const; virtual void getAnalysisUsage(AnalysisUsage &au) const;
virtual void releaseMemory(); virtual void releaseMemory();
@ -494,6 +510,11 @@ namespace llvm {
return SlotIndex(front(), 0); return SlotIndex(front(), 0);
} }
/// Returns the base index of the last slot in this analysis.
SlotIndex getLastIndex() {
return SlotIndex(back(), 0);
}
/// Returns the invalid index marker for this analysis. /// Returns the invalid index marker for this analysis.
SlotIndex getInvalidIndex() { SlotIndex getInvalidIndex() {
return getZeroIndex(); return getZeroIndex();

View File

@ -105,7 +105,6 @@ class TargetLoweringObjectFileMachO : public TargetLoweringObjectFile {
const MCSection *UStringSection; const MCSection *UStringSection;
const MCSection *TextCoalSection; const MCSection *TextCoalSection;
const MCSection *ConstTextCoalSection; const MCSection *ConstTextCoalSection;
const MCSection *ConstDataCoalSection;
const MCSection *ConstDataSection; const MCSection *ConstDataSection;
const MCSection *DataCoalSection; const MCSection *DataCoalSection;
const MCSection *DataCommonSection; const MCSection *DataCommonSection;

View File

@ -159,14 +159,12 @@ namespace llvm {
/// getPow2VectorType - Widens the length of the given vector EVT up to /// getPow2VectorType - Widens the length of the given vector EVT up to
/// the nearest power of 2 and returns that type. /// the nearest power of 2 and returns that type.
MVT getPow2VectorType() const { MVT getPow2VectorType() const {
if (!isPow2VectorType()) { if (isPow2VectorType())
unsigned NElts = getVectorNumElements();
unsigned Pow2NElts = 1 << Log2_32_Ceil(NElts);
return MVT::getVectorVT(getVectorElementType(), Pow2NElts);
}
else {
return *this; return *this;
}
unsigned NElts = getVectorNumElements();
unsigned Pow2NElts = 1 << Log2_32_Ceil(NElts);
return MVT::getVectorVT(getVectorElementType(), Pow2NElts);
} }
/// getScalarType - If this is a vector type, return the element type, /// getScalarType - If this is a vector type, return the element type,
@ -350,17 +348,6 @@ namespace llvm {
} }
return (MVT::SimpleValueType)(MVT::INVALID_SIMPLE_VALUE_TYPE); return (MVT::SimpleValueType)(MVT::INVALID_SIMPLE_VALUE_TYPE);
} }
static MVT getIntVectorWithNumElements(unsigned NumElts) {
switch (NumElts) {
default: return (MVT::SimpleValueType)(MVT::INVALID_SIMPLE_VALUE_TYPE);
case 1: return MVT::v1i64;
case 2: return MVT::v2i32;
case 4: return MVT::v4i16;
case 8: return MVT::v8i8;
case 16: return MVT::v16i8;
}
}
}; };
struct EVT { // EVT = Extended Value Type struct EVT { // EVT = Extended Value Type
@ -374,21 +361,15 @@ namespace llvm {
EVT(MVT::SimpleValueType SVT) : V(SVT), LLVMTy(0) { } EVT(MVT::SimpleValueType SVT) : V(SVT), LLVMTy(0) { }
EVT(MVT S) : V(S), LLVMTy(0) {} EVT(MVT S) : V(S), LLVMTy(0) {}
bool operator==(const EVT VT) const { bool operator==(EVT VT) const {
if (V.SimpleTy == VT.V.SimpleTy) { return !(*this != VT);
if (V.SimpleTy == MVT::INVALID_SIMPLE_VALUE_TYPE)
return LLVMTy == VT.LLVMTy;
return true;
}
return false;
} }
bool operator!=(const EVT VT) const { bool operator!=(EVT VT) const {
if (V.SimpleTy == VT.V.SimpleTy) { if (V.SimpleTy != VT.V.SimpleTy)
if (V.SimpleTy == MVT::INVALID_SIMPLE_VALUE_TYPE) return true;
return LLVMTy != VT.LLVMTy; if (V.SimpleTy == MVT::INVALID_SIMPLE_VALUE_TYPE)
return false; return LLVMTy != VT.LLVMTy;
} return false;
return true;
} }
/// getFloatingPointVT - Returns the EVT that represents a floating point /// getFloatingPointVT - Returns the EVT that represents a floating point
@ -402,30 +383,32 @@ namespace llvm {
/// number of bits. /// number of bits.
static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth) { static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth) {
MVT M = MVT::getIntegerVT(BitWidth); MVT M = MVT::getIntegerVT(BitWidth);
if (M.SimpleTy == MVT::INVALID_SIMPLE_VALUE_TYPE) if (M.SimpleTy != MVT::INVALID_SIMPLE_VALUE_TYPE)
return getExtendedIntegerVT(Context, BitWidth);
else
return M; return M;
return getExtendedIntegerVT(Context, BitWidth);
} }
/// getVectorVT - Returns the EVT that represents a vector NumElements in /// getVectorVT - Returns the EVT that represents a vector NumElements in
/// length, where each element is of type VT. /// length, where each element is of type VT.
static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements) { static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements) {
MVT M = MVT::getVectorVT(VT.V, NumElements); MVT M = MVT::getVectorVT(VT.V, NumElements);
if (M.SimpleTy == MVT::INVALID_SIMPLE_VALUE_TYPE) if (M.SimpleTy != MVT::INVALID_SIMPLE_VALUE_TYPE)
return getExtendedVectorVT(Context, VT, NumElements);
else
return M; return M;
return getExtendedVectorVT(Context, VT, NumElements);
} }
/// getIntVectorWithNumElements - Return any integer vector type that has /// getIntVectorWithNumElements - Return any integer vector type that has
/// the specified number of elements. /// the specified number of elements.
static EVT getIntVectorWithNumElements(LLVMContext &C, unsigned NumElts) { static EVT getIntVectorWithNumElements(LLVMContext &C, unsigned NumElts) {
MVT M = MVT::getIntVectorWithNumElements(NumElts); switch (NumElts) {
if (M.SimpleTy == MVT::INVALID_SIMPLE_VALUE_TYPE) default: return getVectorVT(C, MVT::i8, NumElts);
return getVectorVT(C, MVT::i8, NumElts); case 1: return MVT::v1i64;
else case 2: return MVT::v2i32;
return M; case 4: return MVT::v4i16;
case 8: return MVT::v8i8;
case 16: return MVT::v16i8;
}
return MVT::INVALID_SIMPLE_VALUE_TYPE;
} }
/// isSimple - Test if the given EVT is simple (as opposed to being /// isSimple - Test if the given EVT is simple (as opposed to being
@ -457,26 +440,27 @@ namespace llvm {
/// is64BitVector - Return true if this is a 64-bit vector type. /// is64BitVector - Return true if this is a 64-bit vector type.
bool is64BitVector() const { bool is64BitVector() const {
return isSimple() ? if (!isSimple())
(V==MVT::v8i8 || V==MVT::v4i16 || V==MVT::v2i32 || return isExtended64BitVector();
V==MVT::v1i64 || V==MVT::v2f32) :
isExtended64BitVector(); return (V == MVT::v8i8 || V==MVT::v4i16 || V==MVT::v2i32 ||
V == MVT::v1i64 || V==MVT::v2f32);
} }
/// is128BitVector - Return true if this is a 128-bit vector type. /// is128BitVector - Return true if this is a 128-bit vector type.
bool is128BitVector() const { bool is128BitVector() const {
return isSimple() ? if (!isSimple())
(V==MVT::v16i8 || V==MVT::v8i16 || V==MVT::v4i32 || return isExtended128BitVector();
V==MVT::v2i64 || V==MVT::v4f32 || V==MVT::v2f64) : return (V==MVT::v16i8 || V==MVT::v8i16 || V==MVT::v4i32 ||
isExtended128BitVector(); V==MVT::v2i64 || V==MVT::v4f32 || V==MVT::v2f64);
} }
/// is256BitVector - Return true if this is a 256-bit vector type. /// is256BitVector - Return true if this is a 256-bit vector type.
inline bool is256BitVector() const { inline bool is256BitVector() const {
return isSimple() if (!isSimple())
? (V==MVT::v8f32 || V==MVT::v4f64 || V==MVT::v32i8 || return isExtended256BitVector();
V==MVT::v16i16 || V==MVT::v8i32 || V==MVT::v4i64) return (V == MVT::v8f32 || V == MVT::v4f64 || V == MVT::v32i8 ||
: isExtended256BitVector(); V == MVT::v16i16 || V == MVT::v8i32 || V == MVT::v4i64);
} }
/// is512BitVector - Return true if this is a 512-bit vector type. /// is512BitVector - Return true if this is a 512-bit vector type.
@ -550,8 +534,7 @@ namespace llvm {
assert(isVector() && "Invalid vector type!"); assert(isVector() && "Invalid vector type!");
if (isSimple()) if (isSimple())
return V.getVectorElementType(); return V.getVectorElementType();
else return getExtendedVectorElementType();
return getExtendedVectorElementType();
} }
/// getVectorNumElements - Given a vector type, return the number of /// getVectorNumElements - Given a vector type, return the number of
@ -560,16 +543,14 @@ namespace llvm {
assert(isVector() && "Invalid vector type!"); assert(isVector() && "Invalid vector type!");
if (isSimple()) if (isSimple())
return V.getVectorNumElements(); return V.getVectorNumElements();
else return getExtendedVectorNumElements();
return getExtendedVectorNumElements();
} }
/// getSizeInBits - Return the size of the specified value type in bits. /// getSizeInBits - Return the size of the specified value type in bits.
unsigned getSizeInBits() const { unsigned getSizeInBits() const {
if (isSimple()) if (isSimple())
return V.getSizeInBits(); return V.getSizeInBits();
else return getExtendedSizeInBits();
return getExtendedSizeInBits();
} }
/// getStoreSize - Return the number of bytes overwritten by a store /// getStoreSize - Return the number of bytes overwritten by a store
@ -592,8 +573,7 @@ namespace llvm {
unsigned BitWidth = getSizeInBits(); unsigned BitWidth = getSizeInBits();
if (BitWidth <= 8) if (BitWidth <= 8)
return EVT(MVT::i8); return EVT(MVT::i8);
else return getIntegerVT(Context, 1 << Log2_32_Ceil(BitWidth));
return getIntegerVT(Context, 1 << Log2_32_Ceil(BitWidth));
} }
/// getHalfSizedIntegerVT - Finds the smallest simple value type that is /// getHalfSizedIntegerVT - Finds the smallest simple value type that is
@ -604,12 +584,10 @@ namespace llvm {
assert(isInteger() && !isVector() && "Invalid integer type!"); assert(isInteger() && !isVector() && "Invalid integer type!");
unsigned EVTSize = getSizeInBits(); unsigned EVTSize = getSizeInBits();
for (unsigned IntVT = MVT::FIRST_INTEGER_VALUETYPE; for (unsigned IntVT = MVT::FIRST_INTEGER_VALUETYPE;
IntVT <= MVT::LAST_INTEGER_VALUETYPE; IntVT <= MVT::LAST_INTEGER_VALUETYPE; ++IntVT) {
++IntVT) {
EVT HalfVT = EVT((MVT::SimpleValueType)IntVT); EVT HalfVT = EVT((MVT::SimpleValueType)IntVT);
if(HalfVT.getSizeInBits() * 2 >= EVTSize) { if (HalfVT.getSizeInBits() * 2 >= EVTSize)
return HalfVT; return HalfVT;
}
} }
return getIntegerVT(Context, (EVTSize + 1) / 2); return getIntegerVT(Context, (EVTSize + 1) / 2);
} }

View File

@ -34,12 +34,16 @@ namespace llvmc {
std::string OutFile_; std::string OutFile_;
public: public:
Action (const std::string& C, const StrVector& A, void Construct (const std::string& C, const StrVector& A,
bool S, const std::string& O) bool S, const std::string& O) {
: Command_(C), Args_(A), StopCompilation_(S), OutFile_(O) Command_ = C;
{} Args_ = A;
StopCompilation_ = S;
OutFile_ = O;
}
bool IsConstructed () { return (Command_.size() != 0);}
/// Execute - Executes the represented action. /// Execute - Executes the command. Returns -1 on error.
int Execute () const; int Execute () const;
bool StopCompilation () const { return StopCompilation_; } bool StopCompilation () const { return StopCompilation_; }
const std::string& OutFile() { return OutFile_; } const std::string& OutFile() { return OutFile_; }

View File

@ -0,0 +1,40 @@
//===--- AutoGenerated.h - The LLVM Compiler Driver -------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open
// Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Interface to the autogenerated driver code.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_INCLUDE_COMPILER_DRIVER_AUTOGENERATED_H
#define LLVM_INCLUDE_COMPILER_DRIVER_AUTOGENERATED_H
namespace llvmc {
class LanguageMap;
class CompilationGraph;
namespace autogenerated {
int PreprocessOptions();
int PopulateLanguageMap(LanguageMap& langMap);
int PopulateCompilationGraph(CompilationGraph& graph);
inline int RunInitialization (LanguageMap& M, CompilationGraph& G) {
if (int ret = PreprocessOptions())
return ret;
if (int ret = PopulateLanguageMap(M))
return ret;
if (int ret = PopulateCompilationGraph(G))
return ret;
return 0;
}
}
}
#endif // LLVM_INCLUDE_COMPILER_DRIVER_AUTOGENERATED_H

View File

@ -18,6 +18,8 @@
#include <string> #include <string>
namespace llvmc {
namespace SaveTempsEnum { enum Values { Cwd, Obj, Unset }; } namespace SaveTempsEnum { enum Values { Cwd, Obj, Unset }; }
extern llvm::cl::list<std::string> InputFilenames; extern llvm::cl::list<std::string> InputFilenames;
@ -32,4 +34,6 @@ extern llvm::cl::opt<bool> ViewGraph;
extern llvm::cl::opt<bool> WriteGraph; extern llvm::cl::opt<bool> WriteGraph;
extern llvm::cl::opt<SaveTempsEnum::Values> SaveTemps; extern llvm::cl::opt<SaveTempsEnum::Values> SaveTemps;
} // End namespace llvmc.
#endif // LLVM_INCLUDE_COMPILER_DRIVER_BUILTIN_OPTIONS_H #endif // LLVM_INCLUDE_COMPILER_DRIVER_BUILTIN_OPTIONS_H

View File

@ -32,6 +32,7 @@ def actions;
def alias_option; def alias_option;
def switch_option; def switch_option;
def switch_list_option;
def parameter_option; def parameter_option;
def parameter_list_option; def parameter_list_option;
def prefix_option; def prefix_option;
@ -39,7 +40,6 @@ def prefix_list_option;
// Possible option properties. // Possible option properties.
def extern;
def help; def help;
def hidden; def hidden;
def init; def init;
@ -93,17 +93,8 @@ def error;
def set_option; def set_option;
def unset_option; def unset_option;
// Increase/decrease the edge weight. // Increase the edge weight.
def inc_weight; def inc_weight;
def dec_weight;
// Empty DAG marker.
def empty_dag_marker;
// Used to specify plugin priority.
class PluginPriority<int p> {
int priority = p;
}
// Option list - a single place to specify options. // Option list - a single place to specify options.
class OptionList<list<dag> l> { class OptionList<list<dag> l> {
@ -117,31 +108,17 @@ class OptionPreprocessor<dag d> {
// Map from suffixes to language names // Map from suffixes to language names
class LangToSuffixes<string str, list<string> lst> { def lang_to_suffixes;
string lang = str;
list<string> suffixes = lst;
}
class LanguageMap<list<LangToSuffixes> lst> { class LanguageMap<list<dag> l> {
list<LangToSuffixes> map = lst; list<dag> map = l;
} }
// Compilation graph // Compilation graph
class EdgeBase<string t1, string t2, dag d> { def edge;
string a = t1; def optional_edge;
string b = t2;
dag weight = d; class CompilationGraph<list<dag> l> {
} list<dag> edges = l;
class Edge<string t1, string t2> : EdgeBase<t1, t2, (empty_dag_marker)>;
// Edge and SimpleEdge are synonyms.
class SimpleEdge<string t1, string t2> : EdgeBase<t1, t2, (empty_dag_marker)>;
// Optionally enabled edge.
class OptionalEdge<string t1, string t2, dag props> : EdgeBase<t1, t2, props>;
class CompilationGraph<list<EdgeBase> lst> {
list<EdgeBase> edges = lst;
} }

View File

@ -36,7 +36,7 @@ namespace llvmc {
public: public:
/// GetLanguage - Find the language name corresponding to a given file. /// GetLanguage - Find the language name corresponding to a given file.
const std::string& GetLanguage(const llvm::sys::Path&) const; const std::string* GetLanguage(const llvm::sys::Path&) const;
}; };
/// Edge - Represents an edge of the compilation graph. /// Edge - Represents an edge of the compilation graph.
@ -46,7 +46,7 @@ namespace llvmc {
virtual ~Edge() {} virtual ~Edge() {}
const std::string& ToolName() const { return ToolName_; } const std::string& ToolName() const { return ToolName_; }
virtual unsigned Weight(const InputLanguagesSet& InLangs) const = 0; virtual int Weight(const InputLanguagesSet& InLangs) const = 0;
private: private:
std::string ToolName_; std::string ToolName_;
}; };
@ -55,7 +55,7 @@ namespace llvmc {
class SimpleEdge : public Edge { class SimpleEdge : public Edge {
public: public:
SimpleEdge(const std::string& T) : Edge(T) {} SimpleEdge(const std::string& T) : Edge(T) {}
unsigned Weight(const InputLanguagesSet&) const { return 1; } int Weight(const InputLanguagesSet&) const { return 1; }
}; };
/// Node - A node (vertex) of the compilation graph. /// Node - A node (vertex) of the compilation graph.
@ -132,32 +132,32 @@ namespace llvmc {
void insertNode(Tool* T); void insertNode(Tool* T);
/// insertEdge - Insert a new edge into the graph. Takes ownership /// insertEdge - Insert a new edge into the graph. Takes ownership
/// of the Edge object. /// of the Edge object. Returns non-zero value on error.
void insertEdge(const std::string& A, Edge* E); int insertEdge(const std::string& A, Edge* E);
/// Build - Build target(s) from the input file set. Command-line /// Build - Build target(s) from the input file set. Command-line options
/// options are passed implicitly as global variables. /// are passed implicitly as global variables. Returns non-zero value on
/// error (usually the failed program's exit code).
int Build(llvm::sys::Path const& TempDir, const LanguageMap& LangMap); int Build(llvm::sys::Path const& TempDir, const LanguageMap& LangMap);
/// Check - Check the compilation graph for common errors like /// Check - Check the compilation graph for common errors like cycles,
/// cycles, input/output language mismatch and multiple default /// input/output language mismatch and multiple default edges. Prints error
/// edges. Prints error messages and in case it finds any errors. /// messages and in case it finds any errors.
int Check(); int Check();
/// getNode - Return a reference to the node correponding to the /// getNode - Return a reference to the node corresponding to the given tool
/// given tool name. Throws std::runtime_error. /// name. Returns 0 on error.
Node& getNode(const std::string& ToolName); Node* getNode(const std::string& ToolName);
const Node& getNode(const std::string& ToolName) const; const Node* getNode(const std::string& ToolName) const;
/// viewGraph - This function is meant for use from the debugger. /// viewGraph - This function is meant for use from the debugger. You can
/// You can just say 'call G->viewGraph()' and a ghostview window /// just say 'call G->viewGraph()' and a ghostview window should pop up from
/// should pop up from the program, displaying the compilation /// the program, displaying the compilation graph. This depends on there
/// graph. This depends on there being a 'dot' and 'gv' program /// being a 'dot' and 'gv' program in your path.
/// in your path.
void viewGraph(); void viewGraph();
/// writeGraph - Write Graphviz .dot source file to the current direcotry. /// writeGraph - Write Graphviz .dot source file to the current direcotry.
void writeGraph(const std::string& OutputFilename); int writeGraph(const std::string& OutputFilename);
// GraphTraits support. // GraphTraits support.
friend NodesIterator GraphBegin(CompilationGraph*); friend NodesIterator GraphBegin(CompilationGraph*);
@ -167,16 +167,15 @@ namespace llvmc {
// Helper functions. // Helper functions.
/// getToolsVector - Return a reference to the list of tool names /// getToolsVector - Return a reference to the list of tool names
/// corresponding to the given language name. Throws /// corresponding to the given language name. Returns 0 on error.
/// std::runtime_error. const tools_vector_type* getToolsVector(const std::string& LangName) const;
const tools_vector_type& getToolsVector(const std::string& LangName) const;
/// PassThroughGraph - Pass the input file through the toolchain /// PassThroughGraph - Pass the input file through the toolchain starting at
/// starting at StartNode. /// StartNode.
void PassThroughGraph (const llvm::sys::Path& In, const Node* StartNode, int PassThroughGraph (const llvm::sys::Path& In, const Node* StartNode,
const InputLanguagesSet& InLangs, const InputLanguagesSet& InLangs,
const llvm::sys::Path& TempDir, const llvm::sys::Path& TempDir,
const LanguageMap& LangMap) const; const LanguageMap& LangMap) const;
/// FindToolChain - Find head of the toolchain corresponding to /// FindToolChain - Find head of the toolchain corresponding to
/// the given file. /// the given file.
@ -185,26 +184,32 @@ namespace llvmc {
InputLanguagesSet& InLangs, InputLanguagesSet& InLangs,
const LanguageMap& LangMap) const; const LanguageMap& LangMap) const;
/// BuildInitial - Traverse the initial parts of the toolchains. /// BuildInitial - Traverse the initial parts of the toolchains. Returns
void BuildInitial(InputLanguagesSet& InLangs, /// non-zero value on error.
const llvm::sys::Path& TempDir, int BuildInitial(InputLanguagesSet& InLangs,
const LanguageMap& LangMap); const llvm::sys::Path& TempDir,
const LanguageMap& LangMap);
/// TopologicalSort - Sort the nodes in topological order. /// TopologicalSort - Sort the nodes in topological order. Returns non-zero
void TopologicalSort(std::vector<const Node*>& Out); /// value on error.
/// TopologicalSortFilterJoinNodes - Call TopologicalSort and int TopologicalSort(std::vector<const Node*>& Out);
/// filter the resulting list to include only Join nodes. /// TopologicalSortFilterJoinNodes - Call TopologicalSort and filter the
void TopologicalSortFilterJoinNodes(std::vector<const Node*>& Out); /// resulting list to include only Join nodes. Returns non-zero value on
/// error.
int TopologicalSortFilterJoinNodes(std::vector<const Node*>& Out);
// Functions used to implement Check(). // Functions used to implement Check().
/// CheckLanguageNames - Check that output/input language names /// CheckLanguageNames - Check that output/input language names match for
/// match for all nodes. /// all nodes. Returns non-zero value on error (number of errors
/// encountered).
int CheckLanguageNames() const; int CheckLanguageNames() const;
/// CheckMultipleDefaultEdges - check that there are no multiple /// CheckMultipleDefaultEdges - check that there are no multiple default
/// default default edges. /// default edges. Returns non-zero value on error (number of errors
/// encountered).
int CheckMultipleDefaultEdges() const; int CheckMultipleDefaultEdges() const;
/// CheckCycles - Check that there are no cycles in the graph. /// CheckCycles - Check that there are no cycles in the graph. Returns
/// non-zero value on error (number of errors encountered).
int CheckCycles(); int CheckCycles();
}; };
@ -270,7 +275,7 @@ namespace llvmc {
} }
inline pointer operator*() const { inline pointer operator*() const {
return &OwningGraph->getNode((*EdgeIter)->ToolName()); return OwningGraph->getNode((*EdgeIter)->ToolName());
} }
inline pointer operator->() const { inline pointer operator->() const {
return this->operator*(); return this->operator*();
@ -301,7 +306,7 @@ namespace llvm {
typedef llvmc::NodeChildIterator ChildIteratorType; typedef llvmc::NodeChildIterator ChildIteratorType;
static NodeType* getEntryNode(GraphType* G) { static NodeType* getEntryNode(GraphType* G) {
return &G->getNode("root"); return G->getNode("root");
} }
static ChildIteratorType child_begin(NodeType* N) { static ChildIteratorType child_begin(NodeType* N) {

View File

@ -7,28 +7,22 @@
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// //
// Exception classes for llvmc. // Error handling.
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#ifndef LLVM_INCLUDE_COMPILER_DRIVER_ERROR_H #ifndef LLVM_INCLUDE_COMPILER_DRIVER_ERROR_H
#define LLVM_INCLUDE_COMPILER_DRIVER_ERROR_H #define LLVM_INCLUDE_COMPILER_DRIVER_ERROR_H
#include <stdexcept> #include "llvm/ADT/StringRef.h"
#include "llvm/Support/raw_ostream.h"
namespace llvmc { namespace llvmc {
/// error_code - This gets thrown during the compilation process if a tool inline void PrintError(llvm::StringRef Err) {
/// invocation returns a non-zero exit code. extern const char* ProgramName;
class error_code: public std::runtime_error { llvm::errs() << ProgramName << ": " << Err << '\n';
int Code_; }
public:
error_code (int c)
: std::runtime_error("Tool returned error code"), Code_(c)
{}
int code() const { return Code_; }
};
} }

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