Upgrade our Clang in base to r114020, from upstream's release_28 branch.
Approved-by: rpaulo (mentor)
This commit is contained in:
commit
e580952d8a
@ -1,10 +1,20 @@
|
||||
# See docs/CMake.html for instructions about how to build LLVM with CMake.
|
||||
|
||||
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_VERSION 2.8svn)
|
||||
set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}")
|
||||
set(PACKAGE_BUGREPORT "llvmbugs@cs.uiuc.edu")
|
||||
|
||||
@ -53,7 +63,6 @@ set(LLVM_ALL_TARGETS
|
||||
CppBackend
|
||||
Mips
|
||||
MBlaze
|
||||
MSIL
|
||||
MSP430
|
||||
PIC16
|
||||
PowerPC
|
||||
@ -124,13 +133,6 @@ configure_file(
|
||||
|
||||
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)
|
||||
|
||||
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 )
|
||||
|
||||
if( MSVC )
|
||||
# List of valid CRTs for MSVC
|
||||
set(MSVC_CRT
|
||||
MD
|
||||
MDd
|
||||
MT
|
||||
MTd)
|
||||
include(ChooseMSVCCRT)
|
||||
|
||||
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_SCL_SECURE_NO_WARNINGS -DCRT_NONSTDC_NO_WARNINGS )
|
||||
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'
|
||||
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
|
||||
if (LLVM_ENABLE_WARNINGS)
|
||||
add_llvm_definitions( /W4 /Wall )
|
||||
@ -308,6 +295,7 @@ add_subdirectory(lib/Analysis)
|
||||
add_subdirectory(lib/Analysis/IPA)
|
||||
add_subdirectory(lib/MC)
|
||||
add_subdirectory(lib/MC/MCParser)
|
||||
add_subdirectory(lib/MC/MCDisassembler)
|
||||
add_subdirectory(test)
|
||||
|
||||
add_subdirectory(utils/FileCheck)
|
||||
@ -372,6 +360,8 @@ add_subdirectory(tools)
|
||||
option(LLVM_BUILD_EXAMPLES "Build LLVM example programs." OFF)
|
||||
add_subdirectory(examples)
|
||||
|
||||
add_subdirectory(cmake/modules)
|
||||
|
||||
install(DIRECTORY include/
|
||||
DESTINATION include
|
||||
FILES_MATCHING
|
||||
|
@ -134,6 +134,11 @@ N: Gabor Greif
|
||||
E: ggreif@gmail.com
|
||||
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
|
||||
E: lhames@gmail.com
|
||||
D: PBQP-based register allocator
|
||||
@ -247,6 +252,12 @@ N: Scott Michel
|
||||
E: scottm@aero.org
|
||||
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
|
||||
E: eocallaghan@auroraux.org
|
||||
W: http://www.auroraux.org
|
||||
@ -277,6 +288,11 @@ N: Sandeep Patel
|
||||
E: deeppatel1987@gmail.com
|
||||
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
|
||||
W: http://vladimir_prus.blogspot.com
|
||||
E: ghost@cs.msu.su
|
||||
@ -288,7 +304,10 @@ D: MSIL backend
|
||||
|
||||
N: Duncan Sands
|
||||
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
|
||||
E: sasanka@uiuc.edu
|
||||
@ -306,6 +325,10 @@ N: Anand Shukla
|
||||
E: ashukla@cs.uiuc.edu
|
||||
D: The `paths' pass
|
||||
|
||||
N: Michael J. Spencer
|
||||
E: bigcheesegs@gmail.com
|
||||
D: Shepherding Windows COFF support into MC.
|
||||
|
||||
N: Reid Spencer
|
||||
E: rspencer@reidspencer.com
|
||||
W: http://reidspencer.com/
|
||||
@ -329,14 +352,9 @@ E: xerxes@zafena.se
|
||||
D: Cmake dependency chain and various bug fixes
|
||||
|
||||
N: Bill Wendling
|
||||
E: isanbard@gmail.com
|
||||
E: wendling@apple.com
|
||||
D: Bunches of stuff
|
||||
|
||||
N: Bob Wilson
|
||||
E: bob.wilson@acm.org
|
||||
D: Advanced SIMD (NEON) support in the ARM backend
|
||||
|
||||
N: Wesley Peck
|
||||
E: peckw@wesleypeck.com
|
||||
W: http://wesleypeck.com/
|
||||
D: MicroBlaze backend
|
||||
|
@ -64,7 +64,8 @@ endif
|
||||
|
||||
ifeq ($(MAKECMDGOALS),install-clang)
|
||||
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 :=
|
||||
NO_INSTALL = 1
|
||||
endif
|
||||
@ -78,7 +79,8 @@ ifeq ($(MAKECMDGOALS),install-clang-c)
|
||||
endif
|
||||
|
||||
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 :=
|
||||
endif
|
||||
|
||||
@ -110,7 +112,8 @@ cross-compile-build-tools:
|
||||
--host=$(BUILD_TRIPLE) --target=$(BUILD_TRIPLE); \
|
||||
cd .. ; \
|
||||
fi; \
|
||||
($(MAKE) -C BuildTools \
|
||||
(unset SDKROOT; \
|
||||
$(MAKE) -C BuildTools \
|
||||
BUILD_DIRS_ONLY=1 \
|
||||
UNIVERSAL= \
|
||||
ENABLE_OPTIMIZED=$(ENABLE_OPTIMIZED) \
|
||||
@ -167,7 +170,7 @@ FilesToConfig := \
|
||||
include/llvm/Config/AsmParsers.def \
|
||||
include/llvm/Config/Disassemblers.def \
|
||||
include/llvm/System/DataTypes.h \
|
||||
tools/llvmc/plugins/Base/Base.td
|
||||
tools/llvmc/src/Base.td
|
||||
FilesToConfigPATH := $(addprefix $(LLVM_OBJ_ROOT)/,$(FilesToConfig))
|
||||
|
||||
all-local:: $(FilesToConfigPATH)
|
||||
@ -192,9 +195,6 @@ endif
|
||||
check-llvm2cpp:
|
||||
$(Verb)$(MAKE) check TESTSUITE=Feature RUNLLVM2CPP=1
|
||||
|
||||
check-one:
|
||||
$(Verb)$(MAKE) -C test check-one TESTONE=$(TESTONE)
|
||||
|
||||
srpm: $(LLVM_OBJ_ROOT)/llvm.spec
|
||||
rpmbuild -bs $(LLVM_OBJ_ROOT)/llvm.spec
|
||||
|
||||
|
@ -39,14 +39,18 @@ ifndef PROJECT_NAME
|
||||
PROJECT_NAME := $(LLVMPackageName)
|
||||
endif
|
||||
|
||||
PROJ_OBJ_DIR := $(shell $(PWD))
|
||||
PROJ_OBJ_ROOT := $(shell cd $(PROJ_OBJ_DIR)/$(LEVEL); $(PWD))
|
||||
# The macro below is expanded when 'realpath' is not built-in.
|
||||
# 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)
|
||||
LLVM_SRC_ROOT := $(shell cd @abs_top_srcdir@; $(PWD))
|
||||
LLVM_OBJ_ROOT := $(shell cd @abs_top_builddir@; $(PWD))
|
||||
PROJ_SRC_ROOT := $(shell cd $(LLVM_SRC_ROOT); $(PWD))
|
||||
PROJ_SRC_DIR := $(shell cd $(LLVM_SRC_ROOT)/$(patsubst $(PROJ_OBJ_ROOT)%,%,$(PROJ_OBJ_DIR)); $(PWD))
|
||||
LLVM_SRC_ROOT := $(call realpath, @abs_top_srcdir@)
|
||||
LLVM_OBJ_ROOT := $(call realpath, @abs_top_builddir@)
|
||||
PROJ_SRC_ROOT := $(LLVM_SRC_ROOT)
|
||||
PROJ_SRC_DIR := $(call realpath, $(LLVM_SRC_ROOT)/$(patsubst $(PROJ_OBJ_ROOT)%,%,$(PROJ_OBJ_DIR)))
|
||||
prefix := @prefix@
|
||||
PROJ_prefix := $(prefix)
|
||||
PROJ_VERSION := $(LLVMVersion)
|
||||
@ -66,7 +70,7 @@ endif
|
||||
ifndef LLVM_OBJ_ROOT
|
||||
$(error Projects must define LLVM_OBJ_ROOT)
|
||||
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)
|
||||
PROJ_prefix := $(prefix)
|
||||
ifndef PROJ_VERSION
|
||||
|
@ -196,105 +196,15 @@ install-local:: all-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
|
||||
|
||||
TOOLNAME = $(LLVMC_BASED_DRIVER)
|
||||
|
||||
REQUIRES_EH := 1
|
||||
|
||||
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
|
||||
LLVMLIBS = CompilerDriver.a
|
||||
LINK_COMPONENTS = support system
|
||||
|
||||
endif # LLVMC_BASED_DRIVER
|
||||
|
||||
@ -500,6 +410,26 @@ LLVMLibDir := $(LLVM_OBJ_ROOT)/$(BuildMode)/lib
|
||||
LLVMToolDir := $(LLVM_OBJ_ROOT)/$(BuildMode)/bin
|
||||
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
|
||||
#--------------------------------------------------------------------
|
||||
@ -573,12 +503,7 @@ ifeq ($(HOST_OS),Darwin)
|
||||
SharedLinkOptions += -mmacosx-version-min=$(DARWIN_VERSION)
|
||||
endif
|
||||
else
|
||||
ifeq ($(HOST_OS),Cygwin)
|
||||
SharedLinkOptions=-shared -nostdlib -Wl,--export-all-symbols \
|
||||
-Wl,--enable-auto-import -Wl,--enable-auto-image-base
|
||||
else
|
||||
SharedLinkOptions=-shared
|
||||
endif
|
||||
SharedLinkOptions=-shared
|
||||
endif
|
||||
|
||||
ifeq ($(TARGET_OS),Darwin)
|
||||
@ -588,11 +513,13 @@ ifeq ($(TARGET_OS),Darwin)
|
||||
endif
|
||||
|
||||
ifdef SHARED_LIBRARY
|
||||
ifneq ($(HOST_OS), $(filter $(HOST_OS), Cygwin MingW))
|
||||
ifneq ($(HOST_OS),Darwin)
|
||||
LD.Flags += $(RPATH) -Wl,'$$ORIGIN'
|
||||
else
|
||||
ifneq ($(DARWIN_MAJVERS),4)
|
||||
LD.Flags += $(RPATH) -Wl,$(LibDir)
|
||||
LD.Flags += $(RPATH) -Wl,$(SharedLibDir)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
@ -621,8 +548,8 @@ ifndef KEEP_SYMBOLS
|
||||
endif
|
||||
|
||||
# Adjust linker flags for building an executable
|
||||
ifneq ($(HOST_OS),Darwin)
|
||||
ifneq ($(DARWIN_MAJVERS),4)
|
||||
ifneq ($(HOST_OS), $(filter $(HOST_OS), Cygwin MingW))
|
||||
ifneq ($(HOST_OS), Darwin)
|
||||
ifdef TOOLNAME
|
||||
LD.Flags += $(RPATH) -Wl,'$$ORIGIN/../lib'
|
||||
ifdef EXAMPLE_TOOL
|
||||
@ -631,12 +558,12 @@ ifdef TOOLNAME
|
||||
LD.Flags += $(RPATH) -Wl,$(ToolDir) $(RDYNAMIC)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
else
|
||||
ifneq ($(DARWIN_MAJVERS),4)
|
||||
LD.Flags += $(RPATH) -Wl,@executable_path/../lib
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
#----------------------------------------------------------
|
||||
@ -963,6 +890,13 @@ LLVMUsedLibs := $(patsubst %.a.o, lib%.a, $(addsuffix .o, $(LLVMLIBS)))
|
||||
LLVMLibsPaths := $(addprefix $(LLVMLibDir)/,$(LLVMUsedLibs))
|
||||
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
|
||||
ifdef LINK_COMPONENTS
|
||||
|
||||
@ -975,12 +909,28 @@ $(LLVM_CONFIG):
|
||||
$(ToolDir)/$(strip $(TOOLNAME))$(EXEEXT): $(LLVM_CONFIG)
|
||||
|
||||
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)
|
||||
LLVMLibsPaths += $(LibDir)/libLLVM-$(LLVMVersion)$(SHLIBEXT)
|
||||
LLVMLibsPaths += $(SharedLibDir)/$(SharedPrefix)LLVM-$(LLVMVersion)$(SHLIBEXT)
|
||||
else
|
||||
LLVMLibsOptions += $(shell $(LLVM_CONFIG) --libs $(LINK_COMPONENTS))
|
||||
LLVMLibsPaths += $(LLVM_CONFIG) \
|
||||
$(shell $(LLVM_CONFIG) --libfiles $(LINK_COMPONENTS))
|
||||
|
||||
ifndef NO_LLVM_CONFIG
|
||||
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
|
||||
@ -1011,12 +961,25 @@ $(NativeExportsFile): $(EXPORTED_SYMBOL_FILE) $(ObjDir)/.dir
|
||||
clean-local::
|
||||
-$(Verb) $(RM) -f $(NativeExportsFile)
|
||||
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)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
# Now add the linker command-line options to use the native export file.
|
||||
|
||||
# Darwin
|
||||
ifeq ($(HOST_OS),Darwin)
|
||||
LLVMLibsOptions += -Wl,-exported_symbols_list,$(NativeExportsFile)
|
||||
endif
|
||||
@ -1026,6 +989,12 @@ ifeq ($(HAVE_LINK_VERSION_SCRIPT),1)
|
||||
LLVMLibsOptions += -Wl,--version-script,$(NativeExportsFile)
|
||||
endif
|
||||
|
||||
# Windows
|
||||
ifeq ($(HOST_OS), $(filter $(HOST_OS), Cygwin MingW))
|
||||
# LLVMLibsOptions is invalidated at processing tools/llvm-shlib.
|
||||
SharedLinkOptions += $(NativeExportsFile)
|
||||
endif
|
||||
|
||||
endif
|
||||
|
||||
###############################################################################
|
||||
@ -1100,10 +1069,10 @@ ifdef LIBRARYNAME
|
||||
LIBRARYNAME := $(strip $(LIBRARYNAME))
|
||||
ifdef LOADABLE_MODULE
|
||||
LibName.A := $(LibDir)/$(LIBRARYNAME).a
|
||||
LibName.SO := $(LibDir)/$(LIBRARYNAME)$(SHLIBEXT)
|
||||
LibName.SO := $(SharedLibDir)/$(LIBRARYNAME)$(SHLIBEXT)
|
||||
else
|
||||
LibName.A := $(LibDir)/lib$(LIBRARYNAME).a
|
||||
LibName.SO := $(LibDir)/lib$(LIBRARYNAME)$(SHLIBEXT)
|
||||
LibName.SO := $(SharedLibDir)/$(SharedPrefix)$(LIBRARYNAME)$(SHLIBEXT)
|
||||
endif
|
||||
LibName.O := $(LibDir)/$(LIBRARYNAME).o
|
||||
LibName.BCA:= $(LibDir)/lib$(LIBRARYNAME).bca
|
||||
@ -1128,14 +1097,14 @@ SharedLibKindMessage := "Loadable Module"
|
||||
else
|
||||
SharedLibKindMessage := "Shared Library"
|
||||
endif
|
||||
$(LibName.SO): $(ObjectsO) $(ProjLibsPaths) $(LLVMLibsPaths) $(LibDir)/.dir
|
||||
$(LibName.SO): $(ObjectsO) $(ProjLibsPaths) $(LLVMLibsPaths) $(SharedLibDir)/.dir
|
||||
$(Echo) Linking $(BuildMode) $(SharedLibKindMessage) \
|
||||
$(LIBRARYNAME)$(SHLIBEXT)
|
||||
$(notdir $@)
|
||||
$(Verb) $(Link) $(SharedLinkOptions) -o $@ $(ObjectsO) \
|
||||
$(ProjLibsOptions) $(LLVMLibsOptions) $(LIBS)
|
||||
else
|
||||
$(LibName.SO): $(ObjectsO) $(LibDir)/.dir
|
||||
$(Echo) Linking $(BuildMode) Shared Library $(basename $@)
|
||||
$(LibName.SO): $(ObjectsO) $(SharedLibDir)/.dir
|
||||
$(Echo) Linking $(BuildMode) Shared Library $(notdir $@)
|
||||
$(Verb) $(Link) $(SharedLinkOptions) -o $@ $(ObjectsO)
|
||||
endif
|
||||
|
||||
@ -1151,21 +1120,23 @@ uninstall-local::
|
||||
$(Echo) Uninstall circumvented with NO_INSTALL
|
||||
else
|
||||
|
||||
ifdef LOADABLE_MODULE
|
||||
DestSharedLib = $(DESTDIR)$(PROJ_libdir)/$(LIBRARYNAME)$(SHLIBEXT)
|
||||
# Win32.DLL prefers to be located on the "PATH" of binaries.
|
||||
ifeq ($(HOST_OS), $(filter $(HOST_OS), Cygwin MingW))
|
||||
DestSharedLibDir := $(DESTDIR)$(PROJ_bindir)
|
||||
else
|
||||
DestSharedLib = $(DESTDIR)$(PROJ_libdir)/lib$(LIBRARYNAME)$(SHLIBEXT)
|
||||
DestSharedLibDir := $(DESTDIR)$(PROJ_libdir)
|
||||
endif
|
||||
DestSharedLib := $(DestSharedLibDir)/$(SharedPrefix)$(LIBRARYNAME)$(SHLIBEXT)
|
||||
|
||||
install-local:: $(DestSharedLib)
|
||||
|
||||
$(DestSharedLib): $(LibName.SO) $(DESTDIR)$(PROJ_libdir)
|
||||
$(DestSharedLib): $(LibName.SO) $(DestSharedLibDir)
|
||||
$(Echo) Installing $(BuildMode) Shared Library $(DestSharedLib)
|
||||
$(Verb) $(INSTALL) $(LibName.SO) $(DestSharedLib)
|
||||
|
||||
uninstall-local::
|
||||
$(Echo) Uninstalling $(BuildMode) Shared Library $(DestSharedLib)
|
||||
-$(Verb) $(RM) -f $(DESTDIR)$(PROJ_libdir)/lib$(LIBRARYNAME).*
|
||||
-$(Verb) $(RM) -f $(DestSharedLibDir)/$(SharedPrefix)$(LIBRARYNAME).*
|
||||
endif
|
||||
endif
|
||||
|
||||
@ -1341,10 +1312,33 @@ endif
|
||||
endif
|
||||
|
||||
ifeq ($(HOST_OS), $(filter $(HOST_OS), Linux NetBSD FreeBSD))
|
||||
ifneq ($(ARCH), Mips)
|
||||
LD.Flags += -Wl,--version-script=$(LLVM_SRC_ROOT)/autoconf/ExportMap.map
|
||||
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
|
||||
@ -1377,7 +1371,7 @@ $(ToolAliasBuildPath): $(ToolBuildPath)
|
||||
$(Echo) Creating $(BuildMode) Alias $(TOOLALIAS) $(StripWarnMsg)
|
||||
$(Verb) $(RM) -f $(ToolAliasBuildPath)
|
||||
$(Verb) $(AliasTool) $(TOOLEXENAME) $(ToolAliasBuildPath)
|
||||
$(Echo) ======= Finished Creating $(BuildMode) Alias $(TOOLNAME) \
|
||||
$(Echo) ======= Finished Creating $(BuildMode) Alias $(TOOLALIAS) \
|
||||
$(StripWarnMsg)
|
||||
endif
|
||||
|
||||
@ -1626,7 +1620,7 @@ ifdef TARGET
|
||||
TABLEGEN_INC_FILES_COMMON = 1
|
||||
endif
|
||||
|
||||
ifdef LLVMC_BUILD_AUTOGENERATED_INC
|
||||
ifdef LLVMC_BASED_DRIVER
|
||||
TABLEGEN_INC_FILES_COMMON = 1
|
||||
endif
|
||||
|
||||
@ -1750,20 +1744,26 @@ clean-local::
|
||||
|
||||
endif # TARGET
|
||||
|
||||
ifdef LLVMC_BUILD_AUTOGENERATED_INC
|
||||
ifdef LLVMC_BASED_DRIVER
|
||||
|
||||
LLVMCPluginSrc := $(sort $(strip $(wildcard $(PROJ_SRC_DIR)/*.td)) \
|
||||
$(strip $(wildcard $(PROJ_OBJ_DIR)/*.td)))
|
||||
TDSrc := $(sort $(strip $(wildcard $(PROJ_SRC_DIR)/*.td)) \
|
||||
$(strip $(wildcard $(PROJ_OBJ_DIR)/*.td)))
|
||||
|
||||
TDFiles := $(LLVMCPluginSrc) \
|
||||
$(strip $(wildcard $(LLVM_SRC_ROOT)/include/llvm/CompilerDriver/*.td))
|
||||
TDCommon := $(strip $(wildcard \
|
||||
$(LLVM_SRC_ROOT)/include/llvm/CompilerDriver/*.td))
|
||||
|
||||
$(ObjDir)/AutoGenerated.inc.tmp: $(LLVMCPluginSrc) $(ObjDir)/.dir \
|
||||
$(TBLGEN) $(TD_COMMON)
|
||||
$(Echo) "Building LLVMC configuration library with tblgen"
|
||||
TDFiles := $(TDSrc) $(TDCommon)
|
||||
|
||||
$(INCTMPFiles) : $(TBLGEN) $(TDFiles)
|
||||
|
||||
$(ObjDir)/%.inc.tmp: %.td $(ObjDir)/.dir
|
||||
$(Echo) "Building LLVMC compilation graph description with tblgen"
|
||||
$(Verb) $(TableGen) -gen-llvmc -o $(call SYSPATH, $@) $<
|
||||
|
||||
endif # LLVMC_BUILD_AUTOGENERATED_INC
|
||||
clean-local::
|
||||
-$(Verb) $(RM) -f $(INCFiles)
|
||||
|
||||
endif # LLVMC_BASED_DRIVER
|
||||
|
||||
###############################################################################
|
||||
# OTHER RULES: Other rules needed
|
||||
@ -1840,11 +1840,13 @@ check::
|
||||
$(EchoCmd) No test directory ; \
|
||||
fi
|
||||
|
||||
check-lit::
|
||||
check-lit:: check
|
||||
|
||||
check-dg::
|
||||
$(Verb) if test -d "$(PROJ_OBJ_ROOT)/test" ; then \
|
||||
if test -f "$(PROJ_OBJ_ROOT)/test/Makefile" ; then \
|
||||
$(EchoCmd) Running test suite ; \
|
||||
$(MAKE) -C $(PROJ_OBJ_ROOT)/test check-local-lit ; \
|
||||
$(MAKE) -C $(PROJ_OBJ_ROOT)/test check-local-dg ; \
|
||||
else \
|
||||
$(EchoCmd) No Makefile in test directory ; \
|
||||
fi ; \
|
||||
|
@ -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
|
||||
@ -13,3 +13,4 @@ assistance with LLVM.
|
||||
|
||||
If you're writing a package for LLVM, see docs/Packaging.html for our
|
||||
suggestions.
|
||||
|
||||
|
@ -31,7 +31,7 @@ dnl===
|
||||
dnl===-----------------------------------------------------------------------===
|
||||
dnl Initialize autoconf and define the package name, version number and
|
||||
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 in the output of --version option of the generated configure script.
|
||||
@ -101,7 +101,6 @@ for i in `ls ${srcdir}/projects`
|
||||
do
|
||||
if test -d ${srcdir}/projects/${i} ; then
|
||||
case ${i} in
|
||||
CVS) ;;
|
||||
sample) AC_CONFIG_SUBDIRS([projects/sample]) ;;
|
||||
privbracket) AC_CONFIG_SUBDIRS([projects/privbracket]) ;;
|
||||
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(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 to use.
|
||||
case $llvm_cv_platform_type in
|
||||
@ -369,13 +368,13 @@ else
|
||||
AC_SUBST(LLVM_CROSS_COMPILING, [0])
|
||||
fi
|
||||
|
||||
dnl Check to see if there's a "CVS" (or .svn or .git) directory indicating
|
||||
dnl that this build is being done from a checkout. This sets up several
|
||||
dnl defaults for the command line switches. When we build with a CVS directory,
|
||||
dnl Check to see if there's a .svn or .git directory indicating that this
|
||||
dnl build is being done from a checkout. This sets up several defaults for
|
||||
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 release and we get an optimized build without assertions.
|
||||
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"
|
||||
optimize="no"
|
||||
AC_SUBST(CVSBUILD,[[CVSBUILD=1]])
|
||||
@ -392,7 +391,7 @@ dnl===-----------------------------------------------------------------------===
|
||||
|
||||
dnl --enable-optimized : check whether they want to do an optimized build:
|
||||
AC_ARG_ENABLE(optimized, AS_HELP_STRING(
|
||||
--enable-optimized,[Compile with optimizations enabled (default is NO)]),,enableval=$optimize)
|
||||
--enable-optimized,[Compile with optimizations enabled (default is YES)]),,enableval="yes")
|
||||
if test ${enableval} = "no" ; then
|
||||
AC_SUBST(ENABLE_OPTIMIZED,[[]])
|
||||
else
|
||||
@ -410,7 +409,7 @@ fi
|
||||
|
||||
dnl --enable-assertions : check whether they want to turn on assertions or not:
|
||||
AC_ARG_ENABLE(assertions,AS_HELP_STRING(
|
||||
--enable-assertions,[Compile with assertion checks enabled (default is YES)]),, enableval="yes")
|
||||
--enable-assertions,[Compile with assertion checks enabled (default is NO)]),, enableval="no")
|
||||
if test ${enableval} = "yes" ; then
|
||||
AC_SUBST(DISABLE_ASSERTIONS,[[]])
|
||||
else
|
||||
@ -544,13 +543,13 @@ TARGETS_TO_BUILD=""
|
||||
AC_ARG_ENABLE([targets],AS_HELP_STRING([--enable-targets],
|
||||
[Build specific host targets: all or target1,target2,... Valid targets are:
|
||||
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)
|
||||
if test "$enableval" = host-only ; then
|
||||
enableval=host
|
||||
fi
|
||||
case "$enableval" in
|
||||
all) TARGETS_TO_BUILD="X86 Sparc PowerPC Alpha ARM Mips CellSPU PIC16 XCore MSP430 SystemZ Blackfin CBackend MSIL CppBackend 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
|
||||
case "$a_target" in
|
||||
x86) TARGETS_TO_BUILD="X86 $TARGETS_TO_BUILD" ;;
|
||||
@ -567,7 +566,6 @@ case "$enableval" in
|
||||
systemz) TARGETS_TO_BUILD="SystemZ $TARGETS_TO_BUILD" ;;
|
||||
blackfin) TARGETS_TO_BUILD="Blackfin $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" ;;
|
||||
mblaze) TARGETS_TO_BUILD="MBlaze $TARGETS_TO_BUILD" ;;
|
||||
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.
|
||||
for a_target in $TARGETS_TO_BUILD; do
|
||||
if test "$a_target" = "$LLVM_NATIVE_ARCH"; then
|
||||
LLVM_NATIVE_ARCHTARGET="${LLVM_NATIVE_ARCH}Target"
|
||||
AC_DEFINE_UNQUOTED(LLVM_NATIVE_ARCH,$LLVM_NATIVE_ARCHTARGET,
|
||||
AC_DEFINE_UNQUOTED(LLVM_NATIVE_ARCH, $LLVM_NATIVE_ARCH,
|
||||
[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
|
||||
done
|
||||
|
||||
@ -857,35 +863,6 @@ AC_ARG_ENABLE(libffi,AS_HELP_STRING(
|
||||
esac],
|
||||
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=== SECTION 4: Check for programs we need and that they are the right version
|
||||
@ -1011,6 +988,13 @@ fi
|
||||
|
||||
dnl Find the install program
|
||||
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 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(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.
|
||||
AC_LINK_USE_R
|
||||
|
||||
@ -1345,6 +1332,9 @@ fi
|
||||
|
||||
dnl atomic builtins are required for threading support.
|
||||
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_LANG_SOURCE(
|
||||
[[int main() {
|
||||
@ -1356,13 +1346,13 @@ AC_LINK_IFELSE(
|
||||
return 0;
|
||||
}
|
||||
]]),
|
||||
AC_LANG_POP([C++])
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(LLVM_MULTITHREADED, 1, Build multithreading support into LLVM),
|
||||
AC_MSG_RESULT(no)
|
||||
AC_DEFINE(LLVM_MULTITHREADED, 0, Build multithreading support into LLVM)
|
||||
AC_MSG_WARN([LLVM will be built thread-unsafe because atomic builtins are missing]))
|
||||
|
||||
|
||||
dnl===-----------------------------------------------------------------------===
|
||||
dnl===
|
||||
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 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.
|
||||
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/AsmPrinters.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])
|
||||
|
||||
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.
|
||||
AC_CONFIG_FILES([tools/llvm-config/llvm-config.in])
|
||||
|
@ -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])
|
@ -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
|
||||
])
|
@ -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
|
||||
])
|
||||
|
||||
|
@ -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
|
||||
])
|
||||
|
@ -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
|
||||
])
|
||||
|
||||
|
@ -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
|
||||
])
|
@ -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.
|
||||
#
|
||||
|
@ -317,25 +317,27 @@ package llvm is
|
||||
LLVMGhostLinkage,
|
||||
LLVMCommonLinkage,
|
||||
LLVMLinkerPrivateLinkage,
|
||||
LLVMLinkerPrivateWeakLinkage);
|
||||
LLVMLinkerPrivateWeakLinkage,
|
||||
LinkerPrivateWeakDefAutoLinkage);
|
||||
|
||||
for LLVMLinkage use
|
||||
(LLVMExternalLinkage => 0,
|
||||
LLVMAvailableExternallyLinkage => 1,
|
||||
LLVMLinkOnceAnyLinkage => 2,
|
||||
LLVMLinkOnceODRLinkage => 3,
|
||||
LLVMWeakAnyLinkage => 4,
|
||||
LLVMWeakODRLinkage => 5,
|
||||
LLVMAppendingLinkage => 6,
|
||||
LLVMInternalLinkage => 7,
|
||||
LLVMPrivateLinkage => 8,
|
||||
LLVMDLLImportLinkage => 9,
|
||||
LLVMDLLExportLinkage => 10,
|
||||
LLVMExternalWeakLinkage => 11,
|
||||
LLVMGhostLinkage => 12,
|
||||
LLVMCommonLinkage => 13,
|
||||
LLVMLinkerPrivateLinkage => 14,
|
||||
LLVMLinkerPrivateWeakLinkage => 15);
|
||||
(LLVMExternalLinkage => 0,
|
||||
LLVMAvailableExternallyLinkage => 1,
|
||||
LLVMLinkOnceAnyLinkage => 2,
|
||||
LLVMLinkOnceODRLinkage => 3,
|
||||
LLVMWeakAnyLinkage => 4,
|
||||
LLVMWeakODRLinkage => 5,
|
||||
LLVMAppendingLinkage => 6,
|
||||
LLVMInternalLinkage => 7,
|
||||
LLVMPrivateLinkage => 8,
|
||||
LLVMDLLImportLinkage => 9,
|
||||
LLVMDLLExportLinkage => 10,
|
||||
LLVMExternalWeakLinkage => 11,
|
||||
LLVMGhostLinkage => 12,
|
||||
LLVMCommonLinkage => 13,
|
||||
LLVMLinkerPrivateLinkage => 14,
|
||||
LLVMLinkerPrivateWeakLinkage => 15,
|
||||
LinkerPrivateWeakDefAutoLinkage => 16);
|
||||
|
||||
pragma Convention (C, LLVMLinkage);
|
||||
|
||||
|
@ -35,7 +35,6 @@ module TypeKind = struct
|
||||
| Opaque
|
||||
| Vector
|
||||
| Metadata
|
||||
| Union
|
||||
end
|
||||
|
||||
module Linkage = struct
|
||||
@ -210,11 +209,6 @@ external struct_element_types : lltype -> lltype array
|
||||
= "llvm_struct_element_types"
|
||||
external is_packed : lltype -> bool = "llvm_is_packed"
|
||||
|
||||
(*--... Operations on union types ..........................................--*)
|
||||
external union_type : llcontext -> lltype array -> lltype = "llvm_union_type"
|
||||
external union_element_types : lltype -> lltype array
|
||||
= "llvm_union_element_types"
|
||||
|
||||
(*--... Operations on pointer, vector, and array types .....................--*)
|
||||
external array_type : lltype -> int -> lltype = "llvm_array_type"
|
||||
external pointer_type : lltype -> lltype = "llvm_pointer_type"
|
||||
@ -280,6 +274,8 @@ let fold_right_uses f v init =
|
||||
|
||||
(*--... Operations on users ................................................--*)
|
||||
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 .......................--*)
|
||||
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
|
||||
= "llvm_const_packed_struct"
|
||||
external const_vector : llvalue array -> llvalue = "llvm_const_vector"
|
||||
external const_union : lltype -> llvalue -> llvalue = "LLVMConstUnion"
|
||||
|
||||
(*--... Constant expressions ...............................................--*)
|
||||
external align_of : lltype -> llvalue = "LLVMAlignOf"
|
||||
@ -1050,9 +1045,6 @@ let rec string_of_lltype ty =
|
||||
if is_packed ty
|
||||
then "<" ^ s ^ ">"
|
||||
else s
|
||||
| TypeKind.Union -> "union { " ^ (concat2 ", " (
|
||||
Array.map string_of_lltype (union_element_types ty)
|
||||
)) ^ " }"
|
||||
| TypeKind.Array -> "[" ^ (string_of_int (array_length ty)) ^
|
||||
" x " ^ (string_of_lltype (element_type ty)) ^ "]"
|
||||
| TypeKind.Vector -> "<" ^ (string_of_int (vector_size ty)) ^
|
||||
|
@ -72,7 +72,6 @@ module TypeKind : sig
|
||||
| Opaque
|
||||
| Vector
|
||||
| Metadata
|
||||
| Union
|
||||
end
|
||||
|
||||
(** 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"
|
||||
|
||||
|
||||
(** {7 Operations on union types} *)
|
||||
|
||||
(** [union_type context tys] returns the union type in the context [context]
|
||||
containing the types in the array [tys]. See the method
|
||||
[llvm::UnionType::get] *)
|
||||
external union_type : llcontext -> lltype array -> lltype = "llvm_union_type"
|
||||
|
||||
(** [union_element_types uty] returns the constituent types of the union type
|
||||
[uty]. See the method [llvm::UnionType::getElementType]. *)
|
||||
external union_element_types : lltype -> lltype array
|
||||
= "llvm_union_element_types"
|
||||
|
||||
|
||||
(** {7 Operations on pointer, vector, and array types} *)
|
||||
|
||||
(** [array_type ty n] returns the array type containing [n] elements of type
|
||||
@ -557,6 +543,14 @@ val fold_right_uses : (lluse -> 'a -> 'a) -> llvalue -> 'a -> 'a
|
||||
method [llvm::User::getOperand]. *)
|
||||
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} *)
|
||||
|
||||
@ -689,10 +683,6 @@ external const_packed_struct : llcontext -> llvalue array -> llvalue
|
||||
values [elts]. See the method [llvm::ConstantVector::get]. *)
|
||||
external const_vector : llvalue array -> llvalue = "llvm_const_vector"
|
||||
|
||||
(** [const_union ty v] returns the union constant of type [union_type tys] and
|
||||
containing the value [v]. See the method [llvm::ConstantUnion::get]. *)
|
||||
external const_union : lltype -> llvalue -> llvalue = "LLVMConstUnion"
|
||||
|
||||
|
||||
(** {7 Constant expressions} *)
|
||||
|
||||
@ -991,7 +981,7 @@ external const_insertelement : llvalue -> llvalue -> llvalue -> llvalue
|
||||
= "LLVMConstInsertElement"
|
||||
|
||||
(** [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.
|
||||
See the method [llvm::ConstantExpr::getShuffleVector]. *)
|
||||
external const_shufflevector : llvalue -> llvalue -> llvalue -> llvalue
|
||||
|
@ -318,21 +318,6 @@ CAMLprim value llvm_is_packed(LLVMTypeRef StructTy) {
|
||||
return Val_bool(LLVMIsPackedStruct(StructTy));
|
||||
}
|
||||
|
||||
/*--... Operations on union types ..........................................--*/
|
||||
|
||||
/* llcontext -> lltype array -> lltype */
|
||||
CAMLprim LLVMTypeRef llvm_union_type(LLVMContextRef C, value ElementTypes) {
|
||||
return LLVMUnionTypeInContext(C, (LLVMTypeRef *) ElementTypes,
|
||||
Wosize_val(ElementTypes));
|
||||
}
|
||||
|
||||
/* lltype -> lltype array */
|
||||
CAMLprim value llvm_union_element_types(LLVMTypeRef UnionTy) {
|
||||
value Tys = alloc(LLVMCountUnionElementTypes(UnionTy), 0);
|
||||
LLVMGetUnionElementTypes(UnionTy, (LLVMTypeRef *) Tys);
|
||||
return Tys;
|
||||
}
|
||||
|
||||
/*--... Operations on array, pointer, and vector types .....................--*/
|
||||
|
||||
/* lltype -> int -> lltype */
|
||||
@ -452,6 +437,17 @@ CAMLprim LLVMValueRef llvm_operand(LLVMValueRef V, value 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 .......................--*/
|
||||
|
||||
/* llvalue -> bool */
|
||||
@ -964,8 +960,8 @@ CAMLprim LLVMValueRef llvm_param(LLVMValueRef Fn, value Index) {
|
||||
return LLVMGetParam(Fn, Int_val(Index));
|
||||
}
|
||||
|
||||
/* llvalue -> int -> llvalue */
|
||||
CAMLprim value llvm_params(LLVMValueRef Fn, value Index) {
|
||||
/* llvalue -> llvalue */
|
||||
CAMLprim value llvm_params(LLVMValueRef Fn) {
|
||||
value Params = alloc(LLVMCountParams(Fn), 0);
|
||||
LLVMGetParams(Fn, (LLVMValueRef *) Op_val(Params));
|
||||
return Params;
|
||||
|
155
contrib/llvm/configure
vendored
155
contrib/llvm/configure
vendored
@ -1,6 +1,6 @@
|
||||
#! /bin/sh
|
||||
# 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>.
|
||||
#
|
||||
@ -561,8 +561,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
|
||||
# Identity of this package.
|
||||
PACKAGE_NAME='llvm'
|
||||
PACKAGE_TARNAME='-llvm-'
|
||||
PACKAGE_VERSION='2.8svn'
|
||||
PACKAGE_STRING='llvm 2.8svn'
|
||||
PACKAGE_VERSION='2.8rc'
|
||||
PACKAGE_STRING='llvm 2.8rc'
|
||||
PACKAGE_BUGREPORT='llvmbugs@cs.uiuc.edu'
|
||||
|
||||
ac_unique_file="lib/VMCore/Module.cpp"
|
||||
@ -703,8 +703,6 @@ ENABLE_BUILT_CLANG
|
||||
OPTIMIZE_OPTION
|
||||
EXTRA_OPTIONS
|
||||
BINUTILS_INCDIR
|
||||
ENABLE_LLVMC_DYNAMIC
|
||||
ENABLE_LLVMC_DYNAMIC_PLUGINS
|
||||
CXX
|
||||
CXXFLAGS
|
||||
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.
|
||||
# This message is too long to be a string in the A/UX 3.1 sh.
|
||||
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]...
|
||||
|
||||
@ -1386,7 +1384,7 @@ fi
|
||||
|
||||
if test -n "$ac_init_help"; then
|
||||
case $ac_init_help in
|
||||
short | recursive ) echo "Configuration of llvm 2.8svn:";;
|
||||
short | recursive ) echo "Configuration of llvm 2.8rc:";;
|
||||
esac
|
||||
cat <<\_ACEOF
|
||||
|
||||
@ -1416,17 +1414,13 @@ Optional Features:
|
||||
--enable-targets Build specific host targets: all or
|
||||
target1,target2,... Valid targets are: host, x86,
|
||||
x86_64, sparc, powerpc, alpha, arm, mips, spu,
|
||||
pic16, xcore, msp430, systemz, blackfin, cbe, msil,
|
||||
and cpp (default=all)
|
||||
pic16, xcore, msp430, systemz, blackfin, cbe, and
|
||||
cpp (default=all)
|
||||
--enable-cbe-printf-a Enable C Backend output with hex floating point via
|
||||
%a (default is YES)
|
||||
--enable-bindings Build specific language bindings:
|
||||
all,auto,none,{binding-name} (default=auto)
|
||||
--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
|
||||
|
||||
Optional Packages:
|
||||
@ -1539,7 +1533,7 @@ fi
|
||||
test -n "$ac_init_help" && exit $ac_status
|
||||
if $ac_init_version; then
|
||||
cat <<\_ACEOF
|
||||
llvm configure 2.8svn
|
||||
llvm configure 2.8rc
|
||||
generated by GNU Autoconf 2.60
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
$ $0 $@
|
||||
@ -1988,7 +1982,6 @@ for i in `ls ${srcdir}/projects`
|
||||
do
|
||||
if test -d ${srcdir}/projects/${i} ; then
|
||||
case ${i} in
|
||||
CVS) ;;
|
||||
sample) subdirs="$subdirs projects/sample"
|
||||
;;
|
||||
privbracket) subdirs="$subdirs projects/privbracket"
|
||||
@ -4691,7 +4684,7 @@ else
|
||||
|
||||
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"
|
||||
optimize="no"
|
||||
CVSBUILD=CVSBUILD=1
|
||||
@ -4706,7 +4699,7 @@ fi
|
||||
if test "${enable_optimized+set}" = set; then
|
||||
enableval=$enable_optimized;
|
||||
else
|
||||
enableval=$optimize
|
||||
enableval="yes"
|
||||
fi
|
||||
|
||||
if test ${enableval} = "no" ; then
|
||||
@ -4736,7 +4729,7 @@ fi
|
||||
if test "${enable_assertions+set}" = set; then
|
||||
enableval=$enable_assertions;
|
||||
else
|
||||
enableval="yes"
|
||||
enableval="no"
|
||||
fi
|
||||
|
||||
if test ${enableval} = "yes" ; then
|
||||
@ -4962,7 +4955,7 @@ if test "$enableval" = host-only ; then
|
||||
enableval=host
|
||||
fi
|
||||
case "$enableval" in
|
||||
all) TARGETS_TO_BUILD="X86 Sparc PowerPC Alpha ARM Mips CellSPU PIC16 XCore MSP430 SystemZ Blackfin CBackend MSIL CppBackend 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
|
||||
case "$a_target" in
|
||||
x86) TARGETS_TO_BUILD="X86 $TARGETS_TO_BUILD" ;;
|
||||
@ -4979,7 +4972,6 @@ case "$enableval" in
|
||||
systemz) TARGETS_TO_BUILD="SystemZ $TARGETS_TO_BUILD" ;;
|
||||
blackfin) TARGETS_TO_BUILD="Blackfin $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" ;;
|
||||
mblaze) TARGETS_TO_BUILD="MBlaze $TARGETS_TO_BUILD" ;;
|
||||
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.
|
||||
for a_target in $TARGETS_TO_BUILD; do
|
||||
if test "$a_target" = "$LLVM_NATIVE_ARCH"; then
|
||||
LLVM_NATIVE_ARCHTARGET="${LLVM_NATIVE_ARCH}Target"
|
||||
|
||||
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
|
||||
|
||||
fi
|
||||
@ -5374,42 +5383,6 @@ else
|
||||
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_cpp='$CPP $CPPFLAGS'
|
||||
@ -8004,6 +7977,10 @@ test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
|
||||
|
||||
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.
|
||||
set dummy bzip2; ac_word=$2
|
||||
@ -8721,6 +8698,31 @@ fi
|
||||
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 $ECHO_N "checking for compiler -Wl,-R<path> option... $ECHO_C" >&6; }
|
||||
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_status=$lt_dlunknown
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 11390 "configure"
|
||||
#line 11392 "configure"
|
||||
#include "confdefs.h"
|
||||
|
||||
#if HAVE_DLFCN_H
|
||||
@ -19991,6 +19993,12 @@ fi
|
||||
|
||||
{ echo "$as_me:$LINENO: checking for GCC atomic builtins" >&5
|
||||
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
|
||||
/* confdefs.h. */
|
||||
_ACEOF
|
||||
@ -20041,6 +20049,12 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
|
||||
ac_status=$?
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(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 "${ECHO_T}yes" >&6; }
|
||||
|
||||
@ -20067,7 +20081,6 @@ rm -f core conftest.err conftest.$ac_objext \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
|
||||
|
||||
|
||||
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 $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"
|
||||
|
||||
@ -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 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"
|
||||
@ -21027,7 +21045,7 @@ exec 6>&1
|
||||
# report actual input values of CONFIG_FILES etc. instead of their
|
||||
# values after options handling.
|
||||
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
|
||||
|
||||
CONFIG_FILES = $CONFIG_FILES
|
||||
@ -21080,7 +21098,7 @@ Report bugs to <bug-autoconf@gnu.org>."
|
||||
_ACEOF
|
||||
cat >>$CONFIG_STATUS <<_ACEOF
|
||||
ac_cs_version="\\
|
||||
llvm config.status 2.8svn
|
||||
llvm config.status 2.8rc
|
||||
configured by $0, generated by GNU Autoconf 2.60,
|
||||
with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
|
||||
|
||||
@ -21194,6 +21212,7 @@ for ac_config_target in $ac_config_targets
|
||||
do
|
||||
case $ac_config_target in
|
||||
"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/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" ;;
|
||||
@ -21201,7 +21220,7 @@ do
|
||||
"include/llvm/System/DataTypes.h") CONFIG_HEADERS="$CONFIG_HEADERS include/llvm/System/DataTypes.h" ;;
|
||||
"Makefile.config") CONFIG_FILES="$CONFIG_FILES Makefile.config" ;;
|
||||
"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" ;;
|
||||
"setup") CONFIG_COMMANDS="$CONFIG_COMMANDS setup" ;;
|
||||
"Makefile") CONFIG_COMMANDS="$CONFIG_COMMANDS Makefile" ;;
|
||||
@ -21421,8 +21440,6 @@ ENABLE_BUILT_CLANG!$ENABLE_BUILT_CLANG$ac_delim
|
||||
OPTIMIZE_OPTION!$OPTIMIZE_OPTION$ac_delim
|
||||
EXTRA_OPTIONS!$EXTRA_OPTIONS$ac_delim
|
||||
BINUTILS_INCDIR!$BINUTILS_INCDIR$ac_delim
|
||||
ENABLE_LLVMC_DYNAMIC!$ENABLE_LLVMC_DYNAMIC$ac_delim
|
||||
ENABLE_LLVMC_DYNAMIC_PLUGINS!$ENABLE_LLVMC_DYNAMIC_PLUGINS$ac_delim
|
||||
CXX!$CXX$ac_delim
|
||||
CXXFLAGS!$CXXFLAGS$ac_delim
|
||||
ac_ct_CXX!$ac_ct_CXX$ac_delim
|
||||
@ -21514,7 +21531,7 @@ LIBOBJS!$LIBOBJS$ac_delim
|
||||
LTLIBOBJS!$LTLIBOBJS$ac_delim
|
||||
_ACEOF
|
||||
|
||||
if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 95; then
|
||||
if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 93; then
|
||||
break
|
||||
elif $ac_last_try; then
|
||||
{ { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
|
||||
|
@ -204,8 +204,7 @@ typedef enum {
|
||||
LLVMPointerTypeKind, /**< Pointers */
|
||||
LLVMOpaqueTypeKind, /**< Opaque: type with unknown structure */
|
||||
LLVMVectorTypeKind, /**< SIMD 'packed' format, or other vector type */
|
||||
LLVMMetadataTypeKind, /**< Metadata */
|
||||
LLVMUnionTypeKind /**< Unions */
|
||||
LLVMMetadataTypeKind /**< Metadata */
|
||||
} LLVMTypeKind;
|
||||
|
||||
typedef enum {
|
||||
@ -227,7 +226,9 @@ typedef enum {
|
||||
LLVMGhostLinkage, /**< Obsolete */
|
||||
LLVMCommonLinkage, /**< Tentative definitions */
|
||||
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;
|
||||
|
||||
typedef enum {
|
||||
@ -393,13 +394,6 @@ unsigned LLVMCountStructElementTypes(LLVMTypeRef StructTy);
|
||||
void LLVMGetStructElementTypes(LLVMTypeRef StructTy, LLVMTypeRef *Dest);
|
||||
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) */
|
||||
LLVMTypeRef LLVMArrayType(LLVMTypeRef ElementType, unsigned ElementCount);
|
||||
LLVMTypeRef LLVMPointerType(LLVMTypeRef ElementType, unsigned AddressSpace);
|
||||
@ -523,6 +517,8 @@ LLVMValueRef LLVMGetUsedValue(LLVMUseRef U);
|
||||
|
||||
/* Operations on Users */
|
||||
LLVMValueRef LLVMGetOperand(LLVMValueRef Val, unsigned Index);
|
||||
void LLVMSetOperand(LLVMValueRef User, unsigned Index, LLVMValueRef Val);
|
||||
int LLVMGetNumOperands(LLVMValueRef Val);
|
||||
|
||||
/* Operations on constants of any type */
|
||||
LLVMValueRef LLVMConstNull(LLVMTypeRef Ty); /* all zeroes */
|
||||
@ -570,7 +566,6 @@ LLVMValueRef LLVMConstArray(LLVMTypeRef ElementTy,
|
||||
LLVMValueRef LLVMConstStruct(LLVMValueRef *ConstantVals, unsigned Count,
|
||||
LLVMBool Packed);
|
||||
LLVMValueRef LLVMConstVector(LLVMValueRef *ScalarConstantVals, unsigned Size);
|
||||
LLVMValueRef LLVMConstUnion(LLVMTypeRef Ty, LLVMValueRef Val);
|
||||
|
||||
/* Constant expressions */
|
||||
LLVMOpcode LLVMGetConstOpcode(LLVMValueRef ConstantVal);
|
||||
@ -750,6 +745,9 @@ LLVMBasicBlockRef LLVMInsertBasicBlock(LLVMBasicBlockRef InsertBeforeBB,
|
||||
const char *Name);
|
||||
void LLVMDeleteBasicBlock(LLVMBasicBlockRef BB);
|
||||
|
||||
void LLVMMoveBasicBlockBefore(LLVMBasicBlockRef BB, LLVMBasicBlockRef MovePos);
|
||||
void LLVMMoveBasicBlockAfter(LLVMBasicBlockRef BB, LLVMBasicBlockRef MovePos);
|
||||
|
||||
/* Operations on instructions */
|
||||
LLVMBasicBlockRef LLVMGetInstructionParent(LLVMValueRef Inst);
|
||||
LLVMValueRef LLVMGetFirstInstruction(LLVMBasicBlockRef BB);
|
||||
|
@ -51,41 +51,38 @@ typedef int (*EDRegisterReaderCallback)(uint64_t *value, unsigned regID,
|
||||
@typedef EDAssemblySyntax_t
|
||||
An assembly syntax for use in tokenizing instructions.
|
||||
*/
|
||||
typedef enum {
|
||||
enum {
|
||||
/*! @constant kEDAssemblySyntaxX86Intel Intel syntax for i386 and x86_64. */
|
||||
kEDAssemblySyntaxX86Intel = 0,
|
||||
/*! @constant kEDAssemblySyntaxX86ATT AT&T syntax for i386 and x86_64. */
|
||||
kEDAssemblySyntaxX86ATT = 1,
|
||||
kEDAssemblySyntaxARMUAL = 2
|
||||
} EDAssemblySyntax_t;
|
||||
};
|
||||
typedef unsigned EDAssemblySyntax_t;
|
||||
|
||||
/*!
|
||||
@typedef EDDisassemblerRef
|
||||
Encapsulates a disassembler for a single CPU architecture.
|
||||
*/
|
||||
struct EDDisassembler;
|
||||
typedef struct EDDisassembler *EDDisassemblerRef;
|
||||
typedef void *EDDisassemblerRef;
|
||||
|
||||
/*!
|
||||
@typedef EDInstRef
|
||||
Encapsulates a single disassembled instruction in one assembly syntax.
|
||||
*/
|
||||
struct EDInst;
|
||||
typedef struct EDInst *EDInstRef;
|
||||
typedef void *EDInstRef;
|
||||
|
||||
/*!
|
||||
@typedef EDTokenRef
|
||||
Encapsulates a token from the disassembly of an instruction.
|
||||
*/
|
||||
struct EDToken;
|
||||
typedef struct EDToken *EDTokenRef;
|
||||
typedef void *EDTokenRef;
|
||||
|
||||
/*!
|
||||
@typedef EDOperandRef
|
||||
Encapsulates an operand of an instruction.
|
||||
*/
|
||||
struct EDOperand;
|
||||
typedef struct EDOperand *EDOperandRef;
|
||||
typedef void *EDOperandRef;
|
||||
|
||||
/*!
|
||||
@functiongroup Getting a disassembler
|
||||
|
@ -116,6 +116,8 @@ LLVMBool LLVMRemoveModuleProvider(LLVMExecutionEngineRef EE,
|
||||
LLVMBool LLVMFindFunction(LLVMExecutionEngineRef EE, const char *Name,
|
||||
LLVMValueRef *OutFn);
|
||||
|
||||
void *LLVMRecompileAndRelinkFunction(LLVMExecutionEngineRef EE, LLVMValueRef Fn);
|
||||
|
||||
LLVMTargetDataRef LLVMGetExecutionEngineTargetData(LLVMExecutionEngineRef EE);
|
||||
|
||||
void LLVMAddGlobalMapping(LLVMExecutionEngineRef EE, LLVMValueRef Global,
|
||||
|
@ -1,26 +1,26 @@
|
||||
/*===-- llvm-c/Target.h - Target Lib C Iface --------------------*- C++ -*-===*\
|
||||
|* *|
|
||||
|* The LLVM Compiler Infrastructure *|
|
||||
|* *|
|
||||
|* This file is distributed under the University of Illinois Open Source *|
|
||||
|* License. See LICENSE.TXT for details. *|
|
||||
|* *|
|
||||
|*===----------------------------------------------------------------------===*|
|
||||
|* *|
|
||||
|* This header declares the C interface to libLLVMTarget.a, which *|
|
||||
|* implements target information. *|
|
||||
|* *|
|
||||
|* 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 *|
|
||||
|* tools written in such languages. *|
|
||||
|* *|
|
||||
\*===----------------------------------------------------------------------===*/
|
||||
/*===-- llvm-c/Target.h - Target Lib C Iface --------------------*- C++ -*-===*/
|
||||
/* */
|
||||
/* The LLVM Compiler Infrastructure */
|
||||
/* */
|
||||
/* This file is distributed under the University of Illinois Open Source */
|
||||
/* License. See LICENSE.TXT for details. */
|
||||
/* */
|
||||
/*===----------------------------------------------------------------------===*/
|
||||
/* */
|
||||
/* This header declares the C interface to libLLVMTarget.a, which */
|
||||
/* implements target information. */
|
||||
/* */
|
||||
/* 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 */
|
||||
/* tools written in such languages. */
|
||||
/* */
|
||||
/*===----------------------------------------------------------------------===*/
|
||||
|
||||
#ifndef LLVM_C_TARGET_H
|
||||
#define LLVM_C_TARGET_H
|
||||
|
||||
#include "llvm-c/Core.h"
|
||||
#include "llvm/Config/config.h"
|
||||
#include "llvm/Config/llvm-config.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -64,15 +64,10 @@ static inline void LLVMInitializeAllTargets(void) {
|
||||
for JIT applications to ensure that the target gets linked in correctly. */
|
||||
static inline LLVMBool LLVMInitializeNativeTarget(void) {
|
||||
/* If we have a native target, initialize it to ensure it is linked in. */
|
||||
#ifdef LLVM_NATIVE_ARCH
|
||||
#define DoInit2(TARG) \
|
||||
LLVMInitialize ## TARG ## Info (); \
|
||||
LLVMInitialize ## TARG ()
|
||||
#define DoInit(T) DoInit2(T)
|
||||
DoInit(LLVM_NATIVE_ARCH);
|
||||
#ifdef LLVM_NATIVE_TARGET
|
||||
LLVM_NATIVE_TARGETINFO();
|
||||
LLVM_NATIVE_TARGET();
|
||||
return 0;
|
||||
#undef DoInit
|
||||
#undef DoInit2
|
||||
#else
|
||||
return 1;
|
||||
#endif
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include "llvm/System/DataTypes.h"
|
||||
|
||||
#define LTO_API_VERSION 3
|
||||
|
||||
@ -135,11 +136,17 @@ lto_module_dispose(lto_module_t mod);
|
||||
extern const char*
|
||||
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.
|
||||
*/
|
||||
extern unsigned int
|
||||
extern uint32_t
|
||||
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.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
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
|
||||
* "gcc" on the path.
|
||||
* Sets the cpu to generate code for.
|
||||
*/
|
||||
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
|
||||
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
|
||||
|
@ -464,7 +464,7 @@ class APInt {
|
||||
// For small values, return quickly
|
||||
if (numBits <= APINT_BITS_PER_WORD)
|
||||
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.
|
||||
@ -481,7 +481,7 @@ class APInt {
|
||||
// For small values, return quickly.
|
||||
if (numBits < APINT_BITS_PER_WORD)
|
||||
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.
|
||||
|
@ -185,13 +185,12 @@ class DenseMap {
|
||||
++NumTombstones;
|
||||
return true;
|
||||
}
|
||||
bool erase(iterator I) {
|
||||
void erase(iterator I) {
|
||||
BucketT *TheBucket = &*I;
|
||||
TheBucket->second.~ValueT();
|
||||
TheBucket->first = getTombstoneKey();
|
||||
--NumEntries;
|
||||
++NumTombstones;
|
||||
return true;
|
||||
}
|
||||
|
||||
void swap(DenseMap& RHS) {
|
||||
|
@ -58,6 +58,7 @@ class DenseSet {
|
||||
|
||||
class Iterator {
|
||||
typename MapTy::iterator I;
|
||||
friend class DenseSet;
|
||||
public:
|
||||
typedef typename MapTy::iterator::difference_type difference_type;
|
||||
typedef ValueT value_type;
|
||||
@ -77,6 +78,7 @@ class DenseSet {
|
||||
|
||||
class ConstIterator {
|
||||
typename MapTy::const_iterator I;
|
||||
friend class DenseSet;
|
||||
public:
|
||||
typedef typename MapTy::const_iterator::difference_type difference_type;
|
||||
typedef ValueT value_type;
|
||||
@ -103,6 +105,10 @@ class DenseSet {
|
||||
const_iterator begin() const { return ConstIterator(TheMap.begin()); }
|
||||
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) {
|
||||
return TheMap.insert(std::make_pair(V, 0));
|
||||
}
|
||||
|
@ -183,6 +183,16 @@ class df_iterator : public std::iterator<std::forward_iterator_tag,
|
||||
inline bool nodeVisited(NodeType *Node) const {
|
||||
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();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
@ -54,9 +54,9 @@ namespace llvm {
|
||||
/// void Profile(FoldingSetNodeID &ID) const {
|
||||
/// ID.AddString(Name);
|
||||
/// ID.AddInteger(Value);
|
||||
/// }
|
||||
/// ...
|
||||
/// };
|
||||
/// }
|
||||
/// ...
|
||||
/// };
|
||||
///
|
||||
/// To define the folding set itself use the FoldingSet template;
|
||||
///
|
||||
@ -190,26 +190,76 @@ class FoldingSetImpl {
|
||||
|
||||
/// GetNodeProfile - Instantiations of the FoldingSet template implement
|
||||
/// 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.
|
||||
/// 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 classs, one can add objects
|
||||
/// to FoldingSets that were not originally designed to have that behavior.
|
||||
|
||||
template<typename T> struct FoldingSetTrait;
|
||||
|
||||
/// DefaultFoldingSetTrait - This class provides default implementations
|
||||
/// for FoldingSetTrait implementations.
|
||||
///
|
||||
template<typename T> struct FoldingSetTrait {
|
||||
static inline void Profile(const T& X, FoldingSetNodeID& ID) { X.Profile(ID);}
|
||||
static inline void Profile(T& X, FoldingSetNodeID& ID) { X.Profile(ID); }
|
||||
template <typename Ctx>
|
||||
static inline void Profile(T &X, FoldingSetNodeID &ID, Ctx Context) {
|
||||
template<typename T> struct DefaultFoldingSetTrait {
|
||||
static void Profile(const T& X, FoldingSetNodeID& ID) {
|
||||
X.Profile(ID);
|
||||
}
|
||||
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);
|
||||
}
|
||||
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
|
||||
/// 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
|
||||
/// allocation means it requires a non-trivial destructor call.
|
||||
class FoldingSetNodeIDRef {
|
||||
unsigned* Data;
|
||||
const unsigned* Data;
|
||||
size_t Size;
|
||||
public:
|
||||
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; }
|
||||
};
|
||||
|
||||
@ -259,16 +315,17 @@ class FoldingSetNodeID {
|
||||
inline void Add(const T& x) { FoldingSetTrait<T>::Profile(x, *this); }
|
||||
|
||||
/// 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(); }
|
||||
|
||||
/// 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;
|
||||
|
||||
/// operator== - Used to compare two nodes to each other.
|
||||
///
|
||||
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
|
||||
/// 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 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
|
||||
/// 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:
|
||||
/// GetNodeProfile - Each instantiatation of the FoldingSet needs to provide a
|
||||
/// 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);
|
||||
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:
|
||||
@ -354,13 +458,21 @@ class ContextualFoldingSet : public FoldingSetImpl {
|
||||
|
||||
/// GetNodeProfile - Each instantiatation of the FoldingSet needs to provide a
|
||||
/// way to convert nodes into a unique specifier.
|
||||
virtual void GetNodeProfile(FoldingSetNodeID &ID,
|
||||
FoldingSetImpl::Node *N) const {
|
||||
virtual void GetNodeProfile(FoldingSetImpl::Node *N,
|
||||
FoldingSetNodeID &ID) const {
|
||||
T *TN = static_cast<T *>(N);
|
||||
|
||||
// We must use explicit template arguments in case Ctx is a
|
||||
// reference type.
|
||||
FoldingSetTrait<T>::template Profile<Ctx>(*TN, ID, Context);
|
||||
ContextualFoldingSetTrait<T, Ctx>::Profile(*TN, ID, Context);
|
||||
}
|
||||
virtual bool NodeEquals(FoldingSetImpl::Node *N,
|
||||
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:
|
||||
@ -447,8 +559,8 @@ class FoldingSetIterator : public FoldingSetIteratorImpl {
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
/// FoldingSetBucketIteratorImpl - This is the common bucket iterator support
|
||||
/// shared by all folding sets, which knows how to walk a particular bucket
|
||||
/// of a folding set hash table.
|
||||
/// shared by all folding sets, which knows how to walk a particular bucket
|
||||
/// of a folding set hash table.
|
||||
|
||||
class FoldingSetBucketIteratorImpl {
|
||||
protected:
|
||||
@ -549,7 +661,7 @@ class FastFoldingSetNode : public FoldingSetNode {
|
||||
protected:
|
||||
explicit FastFoldingSetNode(const FoldingSetNodeID &ID) : FastID(ID) {}
|
||||
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) {
|
||||
ID.AddPointer(X);
|
||||
}
|
||||
static inline void Profile(T* X, FoldingSetNodeID& ID) {
|
||||
ID.AddPointer(X);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T> struct FoldingSetTrait<const T*> {
|
||||
|
@ -16,14 +16,14 @@ namespace llvm {
|
||||
|
||||
class Interval {
|
||||
private:
|
||||
uint64_t Start;
|
||||
uint64_t End;
|
||||
int64_t Start;
|
||||
int64_t End;
|
||||
|
||||
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; }
|
||||
uint64_t getEnd() const { return End; }
|
||||
int64_t getStart() const { return Start; }
|
||||
int64_t getEnd() const { return End; }
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
|
52
contrib/llvm/include/llvm/ADT/NullablePtr.h
Normal file
52
contrib/llvm/include/llvm/ADT/NullablePtr.h
Normal 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
|
@ -225,7 +225,7 @@ inline T *array_endof(T (&x)[N]) {
|
||||
|
||||
/// Find the length of an array.
|
||||
template<class T, std::size_t N>
|
||||
inline size_t array_lengthof(T (&x)[N]) {
|
||||
inline size_t array_lengthof(T (&)[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 type deduction of T right.
|
||||
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*) {
|
||||
return array_pod_sort_comparator<T>;
|
||||
}
|
||||
|
@ -139,7 +139,12 @@ class ScopedHashTable {
|
||||
}
|
||||
|
||||
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) {
|
||||
|
@ -206,7 +206,7 @@ template <typename T, bool isPodLike>
|
||||
void SmallVectorTemplateBase<T, isPodLike>::grow(size_t MinSize) {
|
||||
size_t CurCapacity = this->capacity();
|
||||
size_t CurSize = this->size();
|
||||
size_t NewCapacity = 2*CurCapacity;
|
||||
size_t NewCapacity = 2*CurCapacity + 1; // Always grow, even from zero.
|
||||
if (NewCapacity < MinSize)
|
||||
NewCapacity = MinSize;
|
||||
T *NewElts = static_cast<T*>(malloc(NewCapacity*sizeof(T)));
|
||||
@ -707,6 +707,36 @@ class SmallVector : public SmallVectorImpl<T> {
|
||||
|
||||
};
|
||||
|
||||
/// 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
|
||||
|
||||
namespace std {
|
||||
|
@ -254,6 +254,10 @@ class StringMap : public StringMapImpl {
|
||||
StringMap() : StringMapImpl(static_cast<unsigned>(sizeof(MapEntryTy))) {}
|
||||
explicit StringMap(unsigned InitialSize)
|
||||
: StringMapImpl(InitialSize, static_cast<unsigned>(sizeof(MapEntryTy))) {}
|
||||
|
||||
explicit StringMap(AllocatorTy A)
|
||||
: StringMapImpl(static_cast<unsigned>(sizeof(MapEntryTy))), Allocator(A) {}
|
||||
|
||||
explicit StringMap(const StringMap &RHS)
|
||||
: StringMapImpl(static_cast<unsigned>(sizeof(MapEntryTy))) {
|
||||
assert(RHS.empty() &&
|
||||
|
@ -149,7 +149,10 @@ namespace llvm {
|
||||
unsigned edit_distance(StringRef Other, bool AllowReplacements = true);
|
||||
|
||||
/// 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
|
||||
@ -228,12 +231,14 @@ namespace llvm {
|
||||
|
||||
/// find_first_of - Find the first character in the string that is \arg C,
|
||||
/// 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
|
||||
/// 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;
|
||||
|
||||
/// 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
|
||||
/// 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;
|
||||
|
||||
/// @}
|
||||
|
@ -15,7 +15,6 @@
|
||||
#define LLVM_ADT_STRINGSET_H
|
||||
|
||||
#include "llvm/ADT/StringMap.h"
|
||||
#include <cassert>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
@ -26,10 +25,10 @@ namespace llvm {
|
||||
class StringSet : public llvm::StringMap<char, AllocatorTy> {
|
||||
typedef llvm::StringMap<char, AllocatorTy> base;
|
||||
public:
|
||||
bool insert(const std::string& InLang) {
|
||||
bool insert(StringRef InLang) {
|
||||
assert(!InLang.empty());
|
||||
const char* KeyStart = &InLang[0];
|
||||
const char* KeyEnd = KeyStart + InLang.size();
|
||||
const char *KeyStart = InLang.data();
|
||||
const char *KeyEnd = KeyStart + InLang.size();
|
||||
return base::insert(llvm::StringMapEntry<char>::
|
||||
Create(KeyStart, KeyEnd, base::getAllocator(), '+'));
|
||||
}
|
||||
|
@ -61,6 +61,26 @@ class StringSwitch {
|
||||
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>
|
||||
StringSwitch& Cases(const char (&S0)[N0], const char (&S1)[N1],
|
||||
const T& Value) {
|
||||
|
@ -24,7 +24,7 @@ class Twine;
|
||||
|
||||
/// 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
|
||||
/// or
|
||||
/// ARCHITECTURE-VENDOR-OPERATING_SYSTEM-ENVIRONMENT
|
||||
@ -35,20 +35,11 @@ class Twine;
|
||||
/// 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
|
||||
/// string; it does not normally change or normalize the triple string, instead
|
||||
/// it provides additional APIs to parse normalized parts out of the triple.
|
||||
/// string; the constructor does not change or normalize the triple string.
|
||||
/// 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,
|
||||
/// 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
|
||||
/// See autoconf/config.guess for a glimpse into what triples look like in
|
||||
/// practice.
|
||||
class Triple {
|
||||
public:
|
||||
@ -117,6 +108,9 @@ class Triple {
|
||||
mutable OSType OS;
|
||||
|
||||
bool isInitialized() const { return Arch != InvalidArch; }
|
||||
static ArchType ParseArch(StringRef ArchName);
|
||||
static VendorType ParseVendor(StringRef VendorName);
|
||||
static OSType ParseOS(StringRef OSName);
|
||||
void Parse() const;
|
||||
|
||||
public:
|
||||
@ -133,6 +127,16 @@ class Triple {
|
||||
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
|
||||
/// @{
|
||||
|
@ -82,13 +82,13 @@ class ValueMap {
|
||||
typedef typename Config::ExtraData ExtraData;
|
||||
MapT Map;
|
||||
ExtraData Data;
|
||||
ValueMap(const ValueMap&); // DO NOT IMPLEMENT
|
||||
ValueMap& operator=(const ValueMap&); // DO NOT IMPLEMENT
|
||||
public:
|
||||
typedef KeyT key_type;
|
||||
typedef ValueT mapped_type;
|
||||
typedef std::pair<KeyT, ValueT> value_type;
|
||||
|
||||
ValueMap(const ValueMap& Other) : Map(Other.Map), Data(Other.Data) {}
|
||||
|
||||
explicit ValueMap(unsigned NumInitBuckets = 64)
|
||||
: Map(NumInitBuckets), Data() {}
|
||||
explicit ValueMap(const ExtraData &Data, unsigned NumInitBuckets = 64)
|
||||
@ -149,7 +149,7 @@ class ValueMap {
|
||||
bool erase(const KeyT &Val) {
|
||||
return Map.erase(Wrap(Val));
|
||||
}
|
||||
bool erase(iterator I) {
|
||||
void erase(iterator I) {
|
||||
return Map.erase(I.base());
|
||||
}
|
||||
|
||||
@ -161,12 +161,6 @@ class ValueMap {
|
||||
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
|
||||
/// somewhere into the ValueMap's array of buckets (i.e. either to a key or
|
||||
/// value in the ValueMap).
|
||||
@ -250,12 +244,6 @@ class ValueMapCallbackVH : public CallbackVH {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
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>
|
||||
struct DenseMapInfo<ValueMapCallbackVH<KeyT, ValueT, Config, ValueInfoT> > {
|
||||
typedef ValueMapCallbackVH<KeyT, ValueT, Config, ValueInfoT> VH;
|
||||
|
@ -614,7 +614,6 @@ class iplist : public Traits {
|
||||
|
||||
template<class Pr3> void sort(Pr3 pred);
|
||||
void sort() { sort(op_less); }
|
||||
void reverse();
|
||||
};
|
||||
|
||||
|
||||
|
@ -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
|
@ -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
|
@ -18,12 +18,9 @@
|
||||
//
|
||||
// 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
|
||||
// of an area is being queried. If Size is 0, two pointers only alias if they
|
||||
// are exactly equal. If size is greater than zero, but small, the two pointers
|
||||
// alias if the areas pointed to overlap. If the size is very large (ie, ~0U),
|
||||
// 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.
|
||||
// of an area is being queried, or UnknownSize if the size is not known.
|
||||
// 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 {
|
||||
protected:
|
||||
const TargetData *TD;
|
||||
|
||||
private:
|
||||
AliasAnalysis *AA; // Previous Alias Analysis to chain to.
|
||||
|
||||
protected:
|
||||
/// InitializeAliasAnalysis - Subclasses must call this method to initialize
|
||||
/// the AliasAnalysis interface before any other methods are called. This is
|
||||
/// typically called by the run* methods of these subclasses. This may be
|
||||
@ -64,6 +64,11 @@ class AliasAnalysis {
|
||||
AliasAnalysis() : TD(0), AA(0) {}
|
||||
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
|
||||
/// null if no TargetData object is available.
|
||||
///
|
||||
@ -84,6 +89,9 @@ class AliasAnalysis {
|
||||
/// if (AA.alias(P1, P2)) { ... }
|
||||
/// 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 };
|
||||
|
||||
/// alias - The main low level interface to the alias analysis implementation.
|
||||
@ -94,6 +102,11 @@ class AliasAnalysis {
|
||||
virtual AliasResult alias(const Value *V1, unsigned V1Size,
|
||||
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
|
||||
/// pointers are no-alias.
|
||||
bool isNoAlias(const Value *V1, unsigned V1Size,
|
||||
@ -130,17 +143,11 @@ class AliasAnalysis {
|
||||
|
||||
// AccessesArguments - This function accesses function arguments in well
|
||||
// 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,
|
||||
|
||||
// AccessesArgumentsAndGlobals - This function has accesses function
|
||||
// arguments and global variables well 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.
|
||||
AccessesArgumentsAndGlobals,
|
||||
|
||||
// OnlyReadsMemory - This function does not perform any non-local stores or
|
||||
@ -154,31 +161,17 @@ class AliasAnalysis {
|
||||
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.
|
||||
virtual ModRefBehavior getModRefBehavior(CallSite CS,
|
||||
std::vector<PointerAccessInfo> *Info = 0);
|
||||
virtual ModRefBehavior getModRefBehavior(ImmutableCallSite CS);
|
||||
|
||||
/// getModRefBehavior - Return the behavior when calling the given function.
|
||||
/// For use when the call site is not known.
|
||||
virtual ModRefBehavior getModRefBehavior(Function *F,
|
||||
std::vector<PointerAccessInfo> *Info = 0);
|
||||
virtual ModRefBehavior getModRefBehavior(const Function *F);
|
||||
|
||||
/// getModRefBehavior - Return the modref behavior of the intrinsic with the
|
||||
/// given id.
|
||||
static ModRefBehavior getModRefBehavior(unsigned iid);
|
||||
/// getIntrinsicModRefBehavior - Return the modref behavior of the intrinsic
|
||||
/// with the given id. Most clients won't need this, because the regular
|
||||
/// getModRefBehavior incorporates this information.
|
||||
static ModRefBehavior getIntrinsicModRefBehavior(unsigned iid);
|
||||
|
||||
/// doesNotAccessMemory - If the specified call is known to never read or
|
||||
/// write memory, return true. If the call only reads from known-constant
|
||||
@ -191,14 +184,14 @@ class AliasAnalysis {
|
||||
///
|
||||
/// This property corresponds to the GCC 'const' attribute.
|
||||
///
|
||||
bool doesNotAccessMemory(CallSite CS) {
|
||||
bool doesNotAccessMemory(ImmutableCallSite CS) {
|
||||
return getModRefBehavior(CS) == DoesNotAccessMemory;
|
||||
}
|
||||
|
||||
/// doesNotAccessMemory - If the specified function is known to never read or
|
||||
/// 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;
|
||||
}
|
||||
|
||||
@ -211,7 +204,7 @@ class AliasAnalysis {
|
||||
///
|
||||
/// This property corresponds to the GCC 'pure' attribute.
|
||||
///
|
||||
bool onlyReadsMemory(CallSite CS) {
|
||||
bool onlyReadsMemory(ImmutableCallSite CS) {
|
||||
ModRefBehavior MRB = getModRefBehavior(CS);
|
||||
return MRB == DoesNotAccessMemory || MRB == OnlyReadsMemory;
|
||||
}
|
||||
@ -220,7 +213,7 @@ class AliasAnalysis {
|
||||
/// non-volatile memory (or not access memory at all), return true. For use
|
||||
/// when the call site is not known.
|
||||
///
|
||||
bool onlyReadsMemory(Function *F) {
|
||||
bool onlyReadsMemory(const Function *F) {
|
||||
ModRefBehavior MRB = getModRefBehavior(F);
|
||||
return MRB == DoesNotAccessMemory || MRB == OnlyReadsMemory;
|
||||
}
|
||||
@ -234,36 +227,36 @@ class AliasAnalysis {
|
||||
/// a particular call site modifies or reads the memory specified by the
|
||||
/// 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
|
||||
/// to the same set of memory locations. This function returns NoModRef if
|
||||
/// the two calls refer to disjoint memory locations, Ref if CS1 reads memory
|
||||
/// written by CS2, Mod if CS1 writes to memory read or written by CS2, or
|
||||
/// ModRef if CS1 might read or write memory accessed by CS2.
|
||||
///
|
||||
virtual ModRefResult getModRefInfo(CallSite CS1, CallSite CS2);
|
||||
/// to the same set of memory locations. See
|
||||
/// http://llvm.org/docs/AliasAnalysis.html#ModRefInfo
|
||||
/// for details.
|
||||
virtual ModRefResult getModRefInfo(ImmutableCallSite CS1,
|
||||
ImmutableCallSite CS2);
|
||||
|
||||
public:
|
||||
/// Convenience functions...
|
||||
ModRefResult getModRefInfo(LoadInst *L, Value *P, unsigned Size);
|
||||
ModRefResult getModRefInfo(StoreInst *S, Value *P, unsigned Size);
|
||||
ModRefResult getModRefInfo(CallInst *C, Value *P, unsigned Size) {
|
||||
return getModRefInfo(CallSite(C), P, Size);
|
||||
ModRefResult getModRefInfo(const LoadInst *L, const Value *P, unsigned Size);
|
||||
ModRefResult getModRefInfo(const StoreInst *S, const Value *P, unsigned Size);
|
||||
ModRefResult getModRefInfo(const VAArgInst* I, const Value* P, unsigned 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) {
|
||||
return getModRefInfo(CallSite(I), P, Size);
|
||||
ModRefResult getModRefInfo(const InvokeInst *I,
|
||||
const Value *P, unsigned Size) {
|
||||
return getModRefInfo(ImmutableCallSite(I), P, Size);
|
||||
}
|
||||
ModRefResult getModRefInfo(VAArgInst* I, Value* P, unsigned Size) {
|
||||
return AliasAnalysis::ModRef;
|
||||
}
|
||||
ModRefResult getModRefInfo(Instruction *I, Value *P, unsigned Size) {
|
||||
ModRefResult getModRefInfo(const Instruction *I,
|
||||
const Value *P, unsigned Size) {
|
||||
switch (I->getOpcode()) {
|
||||
case Instruction::VAArg: return getModRefInfo((VAArgInst*)I, P, Size);
|
||||
case Instruction::Load: return getModRefInfo((LoadInst*)I, P, Size);
|
||||
case Instruction::Store: return getModRefInfo((StoreInst*)I, P, Size);
|
||||
case Instruction::Call: return getModRefInfo((CallInst*)I, P, Size);
|
||||
case Instruction::Invoke: return getModRefInfo((InvokeInst*)I, P, Size);
|
||||
case Instruction::VAArg: return getModRefInfo((const VAArgInst*)I, P,Size);
|
||||
case Instruction::Load: return getModRefInfo((const LoadInst*)I, P, Size);
|
||||
case Instruction::Store: return getModRefInfo((const StoreInst*)I, P,Size);
|
||||
case Instruction::Call: return getModRefInfo((const CallInst*)I, P, Size);
|
||||
case Instruction::Invoke: return getModRefInfo((const InvokeInst*)I,P,Size);
|
||||
default: return NoModRef;
|
||||
}
|
||||
}
|
||||
|
@ -92,7 +92,8 @@ class AliasSet : public ilist_node<AliasSet> {
|
||||
AliasSet *Forward; // Forwarding pointer.
|
||||
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
|
||||
// AliasSets forwarding to it.
|
||||
@ -127,6 +128,11 @@ class AliasSet : public ilist_node<AliasSet> {
|
||||
removeFromTracker(AST);
|
||||
}
|
||||
|
||||
CallSite getCallSite(unsigned i) const {
|
||||
assert(i < CallSites.size());
|
||||
return CallSite(CallSites[i]);
|
||||
}
|
||||
|
||||
public:
|
||||
/// Accessors...
|
||||
bool isRef() const { return AccessTy & Refs; }
|
||||
@ -229,7 +235,7 @@ class AliasSet : public ilist_node<AliasSet> {
|
||||
void addCallSite(CallSite CS, AliasAnalysis &AA);
|
||||
void removeCallSite(CallSite CS) {
|
||||
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.pop_back();
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ template <class Analysis, bool Simple>
|
||||
struct DOTGraphTraitsViewer : public FunctionPass {
|
||||
std::string Name;
|
||||
|
||||
DOTGraphTraitsViewer(std::string GraphName, const void *ID) : FunctionPass(ID) {
|
||||
DOTGraphTraitsViewer(std::string GraphName, char &ID) : FunctionPass(ID) {
|
||||
Name = GraphName;
|
||||
}
|
||||
|
||||
@ -48,7 +48,7 @@ struct DOTGraphTraitsPrinter : public FunctionPass {
|
||||
|
||||
std::string Name;
|
||||
|
||||
DOTGraphTraitsPrinter(std::string GraphName, const void *ID)
|
||||
DOTGraphTraitsPrinter(std::string GraphName, char &ID)
|
||||
: FunctionPass(ID) {
|
||||
Name = GraphName;
|
||||
}
|
||||
|
@ -36,6 +36,12 @@ namespace llvm {
|
||||
class LLVMContext;
|
||||
class raw_ostream;
|
||||
|
||||
class DIFile;
|
||||
class DISubprogram;
|
||||
class DILexicalBlock;
|
||||
class DIVariable;
|
||||
class DIType;
|
||||
|
||||
/// DIDescriptor - A thin wraper around MDNode to access encoded debug info.
|
||||
/// This should not be stored in a container, because underly MDNode may
|
||||
/// change in certain situations.
|
||||
@ -56,11 +62,17 @@ namespace llvm {
|
||||
}
|
||||
|
||||
GlobalVariable *getGlobalVariableField(unsigned Elt) const;
|
||||
Constant *getConstantField(unsigned Elt) const;
|
||||
Function *getFunctionField(unsigned Elt) const;
|
||||
|
||||
public:
|
||||
explicit DIDescriptor() : DbgNode(0) {}
|
||||
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; }
|
||||
|
||||
@ -134,7 +146,7 @@ namespace llvm {
|
||||
public:
|
||||
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 getDirectory() const { return getStringField(4); }
|
||||
StringRef getProducer() const { return getStringField(5); }
|
||||
@ -260,6 +272,10 @@ namespace llvm {
|
||||
StringRef getFilename() const { return getCompileUnit().getFilename();}
|
||||
StringRef getDirectory() const { return getCompileUnit().getDirectory();}
|
||||
|
||||
/// replaceAllUsesWith - Replace all uses of debug info referenced by
|
||||
/// this descriptor.
|
||||
void replaceAllUsesWith(DIDescriptor &D);
|
||||
|
||||
/// print - print type.
|
||||
void print(raw_ostream &OS) const;
|
||||
|
||||
@ -274,6 +290,9 @@ namespace llvm {
|
||||
|
||||
unsigned getEncoding() const { return getUnsignedField(9); }
|
||||
|
||||
/// Verify - Verify that a basic type descriptor is well formed.
|
||||
bool Verify() const;
|
||||
|
||||
/// print - print basic type.
|
||||
void print(raw_ostream &OS) const;
|
||||
|
||||
@ -297,16 +316,14 @@ namespace llvm {
|
||||
/// return base type size.
|
||||
uint64_t getOriginalTypeSize() const;
|
||||
|
||||
/// Verify - Verify that a derived type descriptor is well formed.
|
||||
bool Verify() const;
|
||||
|
||||
/// print - print derived type.
|
||||
void print(raw_ostream &OS) const;
|
||||
|
||||
/// dump - print derived type to dbgs() with a newline.
|
||||
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
|
||||
@ -437,6 +454,7 @@ namespace llvm {
|
||||
unsigned isDefinition() const { return getUnsignedField(10); }
|
||||
|
||||
GlobalVariable *getGlobal() const { return getGlobalVariableField(11); }
|
||||
Constant *getConstant() const { return getConstantField(11); }
|
||||
|
||||
/// Verify - Verify that a global variable descriptor is well formed.
|
||||
bool Verify() const;
|
||||
@ -504,10 +522,18 @@ namespace llvm {
|
||||
public:
|
||||
explicit DILexicalBlock(const MDNode *N = 0) : DIScope(N) {}
|
||||
DIScope getContext() const { return getFieldAs<DIScope>(1); }
|
||||
StringRef getDirectory() const { return getContext().getDirectory(); }
|
||||
StringRef getFilename() const { return getContext().getFilename(); }
|
||||
unsigned getLineNumber() const { return getUnsignedField(2); }
|
||||
unsigned getColumnNumber() const { return getUnsignedField(3); }
|
||||
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.
|
||||
@ -634,6 +660,9 @@ namespace llvm {
|
||||
unsigned RunTimeLang = 0,
|
||||
MDNode *ContainingType = 0);
|
||||
|
||||
/// CreateTemporaryType - Create a temporary forward-declared type.
|
||||
DIType CreateTemporaryType();
|
||||
|
||||
/// CreateArtificialType - Create a new DIType with "artificial" flag set.
|
||||
DIType CreateArtificialType(DIType Ty);
|
||||
|
||||
@ -648,7 +677,8 @@ namespace llvm {
|
||||
unsigned Flags,
|
||||
DIType DerivedFrom,
|
||||
DIArray Elements,
|
||||
unsigned RunTimeLang = 0);
|
||||
unsigned RunTimeLang = 0,
|
||||
MDNode *ContainingType = 0);
|
||||
|
||||
/// CreateSubprogram - Create a new descriptor for the specified subprogram.
|
||||
/// See comments in DISubprogram for descriptions of these fields.
|
||||
@ -678,6 +708,15 @@ namespace llvm {
|
||||
unsigned LineNo, DIType Ty, bool isLocalToUnit,
|
||||
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.
|
||||
DIVariable CreateVariable(unsigned Tag, DIDescriptor Context,
|
||||
StringRef Name,
|
||||
@ -694,8 +733,8 @@ namespace llvm {
|
||||
|
||||
/// CreateLexicalBlock - This creates a descriptor for a lexical block
|
||||
/// with the specified parent context.
|
||||
DILexicalBlock CreateLexicalBlock(DIDescriptor Context, unsigned Line = 0,
|
||||
unsigned Col = 0);
|
||||
DILexicalBlock CreateLexicalBlock(DIDescriptor Context, DIFile F,
|
||||
unsigned Line = 0, unsigned Col = 0);
|
||||
|
||||
/// CreateNameSpace - This creates new descriptor for a namespace
|
||||
/// with the specified parent context.
|
||||
|
@ -702,7 +702,7 @@ class DominatorTree : public FunctionPass {
|
||||
static char ID; // Pass ID, replacement for typeid
|
||||
DominatorTreeBase<BasicBlock>* DT;
|
||||
|
||||
DominatorTree() : FunctionPass(&ID) {
|
||||
DominatorTree() : FunctionPass(ID) {
|
||||
DT = new DominatorTreeBase<BasicBlock>(false);
|
||||
}
|
||||
|
||||
@ -890,7 +890,7 @@ class DominanceFrontierBase : public FunctionPass {
|
||||
const bool IsPostDominators;
|
||||
|
||||
public:
|
||||
DominanceFrontierBase(void *ID, bool isPostDom)
|
||||
DominanceFrontierBase(char &ID, bool isPostDom)
|
||||
: FunctionPass(ID), IsPostDominators(isPostDom) {}
|
||||
|
||||
/// getRoots - Return the root blocks of the current CFG. This may include
|
||||
@ -995,6 +995,9 @@ class DominanceFrontierBase : public FunctionPass {
|
||||
/// print - Convert to human readable form
|
||||
///
|
||||
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:
|
||||
static char ID; // Pass ID, replacement for typeid
|
||||
DominanceFrontier() :
|
||||
DominanceFrontierBase(&ID, false) {}
|
||||
DominanceFrontierBase(ID, false) {}
|
||||
|
||||
BasicBlock *getRoot() const {
|
||||
assert(Roots.size() == 1 && "Should always have entry node!");
|
||||
|
@ -26,7 +26,7 @@ class FindUsedTypes : public ModulePass {
|
||||
std::set<const Type *> UsedTypes;
|
||||
public:
|
||||
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
|
||||
/// the types used in the module.
|
||||
|
@ -48,7 +48,7 @@ class IntervalPartition : public FunctionPass {
|
||||
public:
|
||||
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
|
||||
virtual bool runOnFunction(Function &F);
|
||||
|
@ -12,8 +12,8 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_ANALYSIS_LIVEVALUES_H
|
||||
#define LLVM_ANALYSIS_LIVEVALUES_H
|
||||
#ifndef LLVM_ANALYSIS_LAZYVALUEINFO_H
|
||||
#define LLVM_ANALYSIS_LAZYVALUEINFO_H
|
||||
|
||||
#include "llvm/Pass.h"
|
||||
|
||||
@ -31,7 +31,7 @@ class LazyValueInfo : public FunctionPass {
|
||||
void operator=(const LazyValueInfo&); // DO NOT IMPLEMENT.
|
||||
public:
|
||||
static char ID;
|
||||
LazyValueInfo() : FunctionPass(&ID), PImpl(0) {}
|
||||
LazyValueInfo() : FunctionPass(ID), PImpl(0) {}
|
||||
~LazyValueInfo() { assert(PImpl == 0 && "releaseMemory not called"); }
|
||||
|
||||
/// Tristate - This is used to return true/false/dunno results.
|
||||
@ -57,6 +57,12 @@ class LazyValueInfo : public FunctionPass {
|
||||
/// constant on the specified edge. Return null if not.
|
||||
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.
|
||||
|
||||
|
@ -28,18 +28,20 @@ namespace llvm {
|
||||
LibCallInfo *LCI;
|
||||
|
||||
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) {
|
||||
}
|
||||
~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.
|
||||
return AliasAnalysis::getModRefInfo(CS1,CS2);
|
||||
return AliasAnalysis::getModRefInfo(CS1, CS2);
|
||||
}
|
||||
|
||||
virtual void getAnalysisUsage(AnalysisUsage &AU) const;
|
||||
@ -49,9 +51,20 @@ namespace llvm {
|
||||
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:
|
||||
ModRefResult AnalyzeLibCallDetails(const LibCallFunctionInfo *FI,
|
||||
CallSite CS, Value *P, unsigned Size);
|
||||
ImmutableCallSite CS,
|
||||
const Value *P, unsigned Size);
|
||||
};
|
||||
} // End of llvm namespace
|
||||
|
||||
|
@ -47,7 +47,8 @@ namespace llvm {
|
||||
enum LocResult {
|
||||
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
|
||||
@ -142,7 +143,7 @@ namespace llvm {
|
||||
|
||||
/// getFunctionInfo - Return the LibCallFunctionInfo object corresponding to
|
||||
/// the specified function if we have it. If not, return null.
|
||||
const LibCallFunctionInfo *getFunctionInfo(Function *F) const;
|
||||
const LibCallFunctionInfo *getFunctionInfo(const Function *F) const;
|
||||
|
||||
|
||||
//===------------------------------------------------------------------===//
|
||||
|
@ -91,7 +91,7 @@ class LoopDependenceAnalysis : public LoopPass {
|
||||
|
||||
public:
|
||||
static char ID; // Class identification, replacement for typeinfo
|
||||
LoopDependenceAnalysis() : LoopPass(&ID) {}
|
||||
LoopDependenceAnalysis() : LoopPass(ID) {}
|
||||
|
||||
/// isDependencePair - Check whether two values can possibly give rise to
|
||||
/// a data dependence: that is the case if both are instructions accessing
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include "llvm/ADT/DepthFirstIterator.h"
|
||||
#include "llvm/ADT/GraphTraits.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/Analysis/Dominators.h"
|
||||
#include "llvm/Support/CFG.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
@ -229,13 +230,16 @@ class LoopBase {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// Edge type.
|
||||
typedef std::pair<BlockT*, BlockT*> Edge;
|
||||
|
||||
/// getExitEdges - Return all pairs of (_inside_block_,_outside_block_).
|
||||
typedef std::pair<const BlockT*,const BlockT*> Edge;
|
||||
void getExitEdges(SmallVectorImpl<Edge> &ExitEdges) const {
|
||||
template <typename EdgeT>
|
||||
void getExitEdges(SmallVectorImpl<EdgeT> &ExitEdges) const {
|
||||
// Sort the blocks vector so that we can use binary search to do quick
|
||||
// lookups.
|
||||
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;
|
||||
for (block_iterator BI = block_begin(), BE = block_end(); BI != BE; ++BI)
|
||||
@ -244,7 +248,7 @@ class LoopBase {
|
||||
I != E; ++I)
|
||||
if (!std::binary_search(LoopBBs.begin(), LoopBBs.end(), *I))
|
||||
// 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
|
||||
@ -505,6 +509,12 @@ class LoopBase {
|
||||
}
|
||||
};
|
||||
|
||||
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> {
|
||||
public:
|
||||
Loop() {}
|
||||
@ -552,12 +562,6 @@ class Loop : public LoopBase<BasicBlock, Loop> {
|
||||
///
|
||||
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
|
||||
/// 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,
|
||||
@ -936,7 +940,7 @@ class LoopInfo : public FunctionPass {
|
||||
public:
|
||||
static char ID; // Pass identification, replacement for typeid
|
||||
|
||||
LoopInfo() : FunctionPass(&ID) {}
|
||||
LoopInfo() : FunctionPass(ID) {}
|
||||
|
||||
LoopInfoBase<BasicBlock, Loop>& getBase() { return LI; }
|
||||
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "llvm/Pass.h"
|
||||
#include "llvm/PassManagers.h"
|
||||
#include "llvm/Function.h"
|
||||
#include <deque>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
@ -28,8 +29,7 @@ class PMStack;
|
||||
|
||||
class LoopPass : public Pass {
|
||||
public:
|
||||
explicit LoopPass(intptr_t pid) : Pass(PT_Loop, pid) {}
|
||||
explicit LoopPass(void *pid) : Pass(PT_Loop, pid) {}
|
||||
explicit LoopPass(char &pid) : Pass(PT_Loop, pid) {}
|
||||
|
||||
/// getPrinterPass - Get a pass to print the function corresponding
|
||||
/// to a Loop.
|
||||
@ -58,7 +58,7 @@ class LoopPass : public Pass {
|
||||
|
||||
/// Assign pass manager to manage this pass
|
||||
virtual void assignPassManager(PMStack &PMS,
|
||||
PassManagerType PMT = PMT_LoopPassManager);
|
||||
PassManagerType PMT);
|
||||
|
||||
/// Return what kind of Pass Manager can manage this pass.
|
||||
virtual PassManagerType getPotentialPassManagerType() const {
|
||||
@ -104,10 +104,10 @@ class LPPassManager : public FunctionPass, public PMDataManager {
|
||||
/// Print passes managed by this manager
|
||||
void dumpPassStructure(unsigned Offset);
|
||||
|
||||
Pass *getContainedPass(unsigned N) {
|
||||
LoopPass *getContainedPass(unsigned N) {
|
||||
assert(N < PassVector.size() && "Pass number out of range!");
|
||||
Pass *FP = static_cast<Pass *>(PassVector[N]);
|
||||
return FP;
|
||||
LoopPass *LP = static_cast<LoopPass *>(PassVector[N]);
|
||||
return LP;
|
||||
}
|
||||
|
||||
virtual PassManagerType getPassManagerType() const {
|
||||
|
@ -79,13 +79,20 @@ namespace llvm {
|
||||
//
|
||||
FunctionPass *createScalarEvolutionAliasAnalysisPass();
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
//
|
||||
// createTypeBasedAliasAnalysisPass - This pass implements metadata-based
|
||||
// type-based alias analysis.
|
||||
//
|
||||
ImmutablePass *createTypeBasedAliasAnalysisPass();
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
//
|
||||
// createProfileLoaderPass - This pass loads information from a profile dump
|
||||
// file.
|
||||
//
|
||||
ModulePass *createProfileLoaderPass();
|
||||
extern const PassInfo *ProfileLoaderPassID;
|
||||
extern char &ProfileLoaderPassID;
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
//
|
||||
@ -99,7 +106,7 @@ namespace llvm {
|
||||
// instead of loading it from a previous run.
|
||||
//
|
||||
FunctionPass *createProfileEstimatorPass();
|
||||
extern const PassInfo *ProfileEstimatorPassID;
|
||||
extern char &ProfileEstimatorPassID;
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
//
|
||||
@ -154,6 +161,13 @@ namespace llvm {
|
||||
// print debug info intrinsics in human readable form
|
||||
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.
|
||||
ModulePass *createModuleDebugInfoPrinterPass();
|
||||
}
|
||||
|
@ -98,6 +98,7 @@ namespace llvm {
|
||||
virtual bool runOnFunction(Function &F);
|
||||
virtual void getAnalysisUsage(AnalysisUsage &AU) const;
|
||||
void print(raw_ostream &OS, const Module* = 0) const;
|
||||
Value *computeAllocationCountValue(Value *P, const Type *&Ty) const;
|
||||
private:
|
||||
Function *FF;
|
||||
TargetData *TD;
|
||||
|
@ -25,7 +25,7 @@ struct PostDominatorTree : public FunctionPass {
|
||||
static char ID; // Pass identification, replacement for typeid
|
||||
DominatorTreeBase<BasicBlock>* DT;
|
||||
|
||||
PostDominatorTree() : FunctionPass(&ID) {
|
||||
PostDominatorTree() : FunctionPass(ID) {
|
||||
DT = new DominatorTreeBase<BasicBlock>(true);
|
||||
}
|
||||
|
||||
@ -106,7 +106,7 @@ template <> struct GraphTraits<PostDominatorTree*>
|
||||
struct PostDominanceFrontier : public DominanceFrontierBase {
|
||||
static char ID;
|
||||
PostDominanceFrontier()
|
||||
: DominanceFrontierBase(&ID, true) {}
|
||||
: DominanceFrontierBase(ID, true) {}
|
||||
|
||||
virtual bool runOnFunction(Function &) {
|
||||
Frontiers.clear();
|
||||
|
630
contrib/llvm/include/llvm/Analysis/RegionInfo.h
Normal file
630
contrib/llvm/include/llvm/Analysis/RegionInfo.h
Normal 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
|
||||
|
342
contrib/llvm/include/llvm/Analysis/RegionIterator.h
Normal file
342
contrib/llvm/include/llvm/Analysis/RegionIterator.h
Normal 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
|
26
contrib/llvm/include/llvm/Analysis/RegionPrinter.h
Normal file
26
contrib/llvm/include/llvm/Analysis/RegionPrinter.h
Normal 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
|
@ -44,12 +44,17 @@ namespace llvm {
|
||||
class Loop;
|
||||
class LoopInfo;
|
||||
class Operator;
|
||||
class SCEVUnknown;
|
||||
class SCEV;
|
||||
template<> struct FoldingSetTrait<SCEV>;
|
||||
|
||||
/// SCEV - This class represents an analyzed expression in the program. These
|
||||
/// are opaque objects that the client is not allowed to do much with
|
||||
/// directly.
|
||||
///
|
||||
class SCEV : public FoldingSetNode {
|
||||
friend struct FoldingSetTrait<SCEV>;
|
||||
|
||||
/// FastID - A reference to an Interned FoldingSetNodeID for this node.
|
||||
/// The ScalarEvolution's BumpPtrAllocator holds the data.
|
||||
FoldingSetNodeIDRef FastID;
|
||||
@ -73,9 +78,6 @@ namespace llvm {
|
||||
|
||||
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
|
||||
/// the specified loop.
|
||||
virtual bool isLoopInvariant(const Loop *L) const = 0;
|
||||
@ -125,6 +127,21 @@ namespace llvm {
|
||||
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) {
|
||||
S.print(OS);
|
||||
return OS;
|
||||
@ -175,6 +192,7 @@ namespace llvm {
|
||||
|
||||
friend class SCEVCallbackVH;
|
||||
friend class SCEVExpander;
|
||||
friend class SCEVUnknown;
|
||||
|
||||
/// F - The function we are analyzing.
|
||||
///
|
||||
@ -196,9 +214,14 @@ namespace llvm {
|
||||
/// counts and things.
|
||||
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
|
||||
/// 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
|
||||
/// 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.
|
||||
void ForgetSymbolicName(Instruction *I, const SCEV *SymName);
|
||||
|
||||
@ -350,10 +373,11 @@ namespace llvm {
|
||||
std::pair<BasicBlock *, BasicBlock *>
|
||||
getPredecessorWithUniqueSuccessorForBB(BasicBlock *BB);
|
||||
|
||||
/// isImpliedCond - Test whether the condition described by Pred, LHS,
|
||||
/// and RHS is true whenever the given Cond value evaluates to true.
|
||||
bool isImpliedCond(Value *Cond, ICmpInst::Predicate Pred,
|
||||
/// isImpliedCond - Test whether the condition described by Pred, LHS, and
|
||||
/// RHS is true whenever the given FoundCondValue value evaluates to true.
|
||||
bool isImpliedCond(ICmpInst::Predicate Pred,
|
||||
const SCEV *LHS, const SCEV *RHS,
|
||||
Value *FoundCondValue,
|
||||
bool Inverse);
|
||||
|
||||
/// isImpliedCondOperands - Test whether the condition described by Pred,
|
||||
@ -659,6 +683,11 @@ namespace llvm {
|
||||
private:
|
||||
FoldingSet<SCEV> UniqueSCEVs;
|
||||
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;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "llvm/Analysis/ScalarEvolutionNormalization.h"
|
||||
#include "llvm/Support/IRBuilder.h"
|
||||
#include "llvm/Support/TargetFolder.h"
|
||||
#include "llvm/Support/ValueHandle.h"
|
||||
#include <set>
|
||||
|
||||
namespace llvm {
|
||||
@ -31,8 +32,8 @@ namespace llvm {
|
||||
ScalarEvolution &SE;
|
||||
std::map<std::pair<const SCEV *, Instruction *>, AssertingVH<Value> >
|
||||
InsertedExpressions;
|
||||
std::set<Value*> InsertedValues;
|
||||
std::set<Value*> InsertedPostIncValues;
|
||||
std::set<AssertingVH<Value> > InsertedValues;
|
||||
std::set<AssertingVH<Value> > InsertedPostIncValues;
|
||||
|
||||
/// 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
|
||||
@ -70,13 +71,18 @@ namespace llvm {
|
||||
/// clear - Erase the contents of the InsertedExpressions map so that users
|
||||
/// trying to expand the same expression into multiple BasicBlocks or
|
||||
/// 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
|
||||
/// canonical induction variable of the specified type for the specified
|
||||
/// loop (inserting one if there is none). A canonical induction variable
|
||||
/// 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
|
||||
/// expression into the program. The inserted code is inserted into the
|
||||
|
@ -202,33 +202,14 @@ namespace llvm {
|
||||
op_iterator op_begin() const { return Operands; }
|
||||
op_iterator op_end() const { return Operands + NumOperands; }
|
||||
|
||||
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;
|
||||
}
|
||||
virtual bool isLoopInvariant(const Loop *L) const;
|
||||
|
||||
// hasComputableLoopEvolution - N-ary expressions have computable loop
|
||||
// evolutions iff they have at least one operand that varies with the loop,
|
||||
// but that all varying operands are computable.
|
||||
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 hasComputableLoopEvolution(const Loop *L) 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;
|
||||
}
|
||||
virtual bool hasOperand(const SCEV *O) 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 for the analysis.
|
||||
///
|
||||
class SCEVUnknown : public SCEV {
|
||||
class SCEVUnknown : public SCEV, private CallbackVH {
|
||||
friend class ScalarEvolution;
|
||||
|
||||
Value *V;
|
||||
SCEVUnknown(const FoldingSetNodeIDRef ID, Value *v) :
|
||||
SCEV(ID, scUnknown), V(v) {}
|
||||
// Implement CallbackVH.
|
||||
virtual void deleted();
|
||||
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:
|
||||
Value *getValue() const { return V; }
|
||||
Value *getValue() const { return getValPtr(); }
|
||||
|
||||
/// isSizeOf, isAlignOf, isOffsetOf - Test whether this is a special
|
||||
/// constant representing a type size, alignment, or field offset in
|
||||
|
@ -77,25 +77,6 @@ namespace llvm {
|
||||
///
|
||||
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
|
||||
/// the scalar value indexed is already around as a register, for example if
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===-- AsmAnnotationWriter.h - Itf for annotation .ll files - --*- C++ -*-===//
|
||||
//===-- AssemblyAnnotationWriter.h - Annotation .ll files -------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -32,21 +32,26 @@ class AssemblyAnnotationWriter {
|
||||
|
||||
/// emitFunctionAnnot - This may be implemented to emit a string right before
|
||||
/// 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
|
||||
/// after the basic block label, but before the first instruction in the block.
|
||||
virtual void emitBasicBlockStartAnnot(const BasicBlock *BB, raw_ostream &OS){
|
||||
/// after the basic block label, but before the first instruction in the
|
||||
/// block.
|
||||
virtual void emitBasicBlockStartAnnot(const BasicBlock *BB,
|
||||
formatted_raw_ostream &OS) {
|
||||
}
|
||||
|
||||
/// emitBasicBlockEndAnnot - This may be implemented to emit a string right
|
||||
/// 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
|
||||
/// 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
|
||||
/// right of an instruction or global value.
|
@ -16,6 +16,7 @@
|
||||
|
||||
namespace llvm {
|
||||
class Module;
|
||||
class GlobalVariable;
|
||||
class Function;
|
||||
class CallInst;
|
||||
|
||||
@ -35,6 +36,10 @@ namespace llvm {
|
||||
/// so that it can update all calls to the old function.
|
||||
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
|
||||
/// then this function simply removes the intrinsic.
|
||||
void CheckDebugInfoIntrinsics(Module *M);
|
||||
|
@ -297,7 +297,7 @@ class Archive {
|
||||
/// 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
|
||||
/// 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
|
||||
/// 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
|
||||
@ -306,8 +306,7 @@ class Archive {
|
||||
/// if this form of opening the archive is used that only the symbol table
|
||||
/// lookup methods (getSymbolTable, findModuleDefiningSymbol, and
|
||||
/// findModulesDefiningSymbols) be used.
|
||||
/// @throws std::string if an error occurs opening the file
|
||||
/// @returns an Archive* that represents the archive file.
|
||||
/// @returns an Archive* that represents the archive file, or null on error.
|
||||
/// @brief Open an existing archive and load its symbols.
|
||||
static Archive* OpenAndLoadSymbols(
|
||||
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
|
||||
/// haven't used the writeToDisk method by the time the destructor is
|
||||
/// called, all changes to the archive will be lost.
|
||||
/// @throws std::string if an error occurs
|
||||
/// @brief Destruct in-memory archive
|
||||
~Archive();
|
||||
|
||||
|
@ -88,7 +88,7 @@ class BitstreamWriter {
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
||||
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!");
|
||||
CurValue |= Val << CurBit;
|
||||
if (CurBit + NumBits < 32) {
|
||||
@ -277,10 +277,12 @@ class BitstreamWriter {
|
||||
switch (Op.getEncoding()) {
|
||||
default: assert(0 && "Unknown encoding!");
|
||||
case BitCodeAbbrevOp::Fixed:
|
||||
Emit((unsigned)V, (unsigned)Op.getEncodingData());
|
||||
if (Op.getEncodingData())
|
||||
Emit((unsigned)V, (unsigned)Op.getEncodingData());
|
||||
break;
|
||||
case BitCodeAbbrevOp::VBR:
|
||||
EmitVBR64(V, (unsigned)Op.getEncodingData());
|
||||
if (Op.getEncodingData())
|
||||
EmitVBR64(V, (unsigned)Op.getEncodingData());
|
||||
break;
|
||||
case BitCodeAbbrevOp::Char6:
|
||||
Emit(BitCodeAbbrevOp::EncodeChar6((char)V), 6);
|
||||
|
@ -94,8 +94,7 @@ namespace bitc {
|
||||
TYPE_CODE_FP128 = 14, // LONG DOUBLE (112 bit mantissa)
|
||||
TYPE_CODE_PPC_FP128= 15, // PPC LONG DOUBLE (2 doubles)
|
||||
|
||||
TYPE_CODE_METADATA = 16, // METADATA
|
||||
TYPE_CODE_UNION = 17 // UNION: [eltty x N]
|
||||
TYPE_CODE_METADATA = 16 // METADATA
|
||||
};
|
||||
|
||||
// The type symbol table only has one code (TST_ENTRY_CODE).
|
||||
@ -111,12 +110,20 @@ namespace bitc {
|
||||
|
||||
enum MetadataCodes {
|
||||
METADATA_STRING = 1, // MDSTRING: [values]
|
||||
METADATA_NODE = 2, // MDNODE: [n x (type num, value num)]
|
||||
METADATA_FN_NODE = 3, // FN_MDNODE: [n x (type num, value num)]
|
||||
// FIXME: Remove NODE in favor of NODE2 in LLVM 3.0
|
||||
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_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_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
|
||||
// constant and maintains an implicit current type value.
|
||||
@ -224,7 +231,8 @@ namespace bitc {
|
||||
FUNC_CODE_INST_LOAD = 20, // LOAD: [opty, op, align, vol]
|
||||
// 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_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]
|
||||
// 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
|
||||
@ -242,8 +250,13 @@ namespace bitc {
|
||||
FUNC_CODE_INST_INBOUNDS_GEP= 30, // INBOUNDS_GEP: [n x operands]
|
||||
FUNC_CODE_INST_INDIRECTBR = 31, // INDIRECTBR: [opty, op0, op1, ...]
|
||||
|
||||
FUNC_CODE_DEBUG_LOC = 32, // DEBUG_LOC: [Line,Col,ScopeVal, IAVal]
|
||||
FUNC_CODE_DEBUG_LOC_AGAIN = 33 // DEBUG_LOC_AGAIN
|
||||
// FIXME: Remove DEBUG_LOC in favor of DEBUG_LOC2 in LLVM 3.0
|
||||
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 llvm namespace
|
||||
|
@ -33,8 +33,7 @@ class CallGraphSCC;
|
||||
|
||||
class CallGraphSCCPass : public Pass {
|
||||
public:
|
||||
explicit CallGraphSCCPass(intptr_t pid) : Pass(PT_CallGraphSCC, pid) {}
|
||||
explicit CallGraphSCCPass(void *pid) : Pass(PT_CallGraphSCC, pid) {}
|
||||
explicit CallGraphSCCPass(char &pid) : Pass(PT_CallGraphSCC, pid) {}
|
||||
|
||||
/// createPrinterPass - Get a pass that prints the Module
|
||||
/// corresponding to a CallGraph.
|
||||
@ -64,7 +63,7 @@ class CallGraphSCCPass : public Pass {
|
||||
|
||||
/// Assign pass manager to manager this pass
|
||||
virtual void assignPassManager(PMStack &PMS,
|
||||
PassManagerType PMT =PMT_CallGraphPassManager);
|
||||
PassManagerType PMT);
|
||||
|
||||
/// Return what kind of Pass Manager can manage this pass.
|
||||
virtual PassManagerType getPotentialPassManagerType() const {
|
||||
|
@ -54,6 +54,7 @@ namespace llvm {
|
||||
class Mangler;
|
||||
class TargetLoweringObjectFile;
|
||||
class TargetData;
|
||||
class TargetMachine;
|
||||
class Twine;
|
||||
class Type;
|
||||
|
||||
@ -296,7 +297,7 @@ namespace llvm {
|
||||
MCSymbol *GetBlockAddressSymbol(const BlockAddress *BA) const;
|
||||
MCSymbol *GetBlockAddressSymbol(const BasicBlock *BB) const;
|
||||
|
||||
//===------------------------------------------------------------------===//
|
||||
//===------------------------------------------------------------------===//
|
||||
// Emission Helper Routines.
|
||||
//===------------------------------------------------------------------===//
|
||||
public:
|
||||
@ -327,6 +328,12 @@ namespace llvm {
|
||||
void EmitLabelOffsetDifference(const MCSymbol *Hi, uint64_t Offset,
|
||||
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
|
||||
//===------------------------------------------------------------------===//
|
||||
@ -369,6 +376,10 @@ namespace llvm {
|
||||
/// operands.
|
||||
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
|
||||
//===------------------------------------------------------------------===//
|
||||
|
@ -12,10 +12,35 @@
|
||||
#define LLVM_CODEGEN_CALCSPILLWEIGHTS_H
|
||||
|
||||
#include "llvm/CodeGen/MachineFunctionPass.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
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
|
||||
/// live intervals.
|
||||
@ -23,11 +48,11 @@ namespace llvm {
|
||||
public:
|
||||
static char ID;
|
||||
|
||||
CalculateSpillWeights() : MachineFunctionPass(&ID) {}
|
||||
CalculateSpillWeights() : MachineFunctionPass(ID) {}
|
||||
|
||||
virtual void getAnalysisUsage(AnalysisUsage &au) const;
|
||||
|
||||
virtual bool runOnMachineFunction(MachineFunction &fn);
|
||||
virtual bool runOnMachineFunction(MachineFunction &fn);
|
||||
|
||||
private:
|
||||
/// Returns true if the given live interval is zero length.
|
||||
|
@ -275,6 +275,12 @@ class CCState {
|
||||
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
|
||||
// value. The size and alignment information of the argument is encoded in its
|
||||
// parameter attribute.
|
||||
|
@ -77,6 +77,9 @@ class FunctionLoweringInfo {
|
||||
/// anywhere in the function.
|
||||
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
|
||||
/// function arguments that are inserted after scheduling is completed.
|
||||
SmallVector<MachineInstr*, 8> ArgDbgValues;
|
||||
@ -138,6 +141,13 @@ class FunctionLoweringInfo {
|
||||
assert(R == 0 && "Already initialized this value register!");
|
||||
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
|
||||
|
@ -603,7 +603,7 @@ namespace ISD {
|
||||
/// 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
|
||||
/// 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
|
||||
@ -633,7 +633,6 @@ namespace ISD {
|
||||
/// (the result of the load and the result of the base +/- offset
|
||||
/// computation); a post-indexed store produces one value (the
|
||||
/// the result of the base +/- offset computation).
|
||||
///
|
||||
enum MemIndexedMode {
|
||||
UNINDEXED = 0,
|
||||
PRE_INC,
|
||||
@ -651,10 +650,8 @@ namespace ISD {
|
||||
/// integer result type.
|
||||
/// ZEXTLOAD loads the integer operand and zero extends it to a larger
|
||||
/// integer result type.
|
||||
/// EXTLOAD is used for three things: floating point extending loads,
|
||||
/// integer extending loads [the top bits are undefined], and vector
|
||||
/// extending loads [load into low elt].
|
||||
///
|
||||
/// EXTLOAD is used for two things: floating point extending loads and
|
||||
/// integer extending loads [the top bits are undefined].
|
||||
enum LoadExtType {
|
||||
NON_EXTLOAD = 0,
|
||||
EXTLOAD,
|
||||
|
@ -39,7 +39,7 @@ namespace llvm {
|
||||
/// This class holds information about a machine level values, including
|
||||
/// 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:
|
||||
///
|
||||
/// 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
|
||||
/// 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; }
|
||||
/// For a stack interval, set the defining register.
|
||||
/// 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
|
||||
/// this range.
|
||||
/// this range.
|
||||
bool containsRange(SlotIndex S, SlotIndex E) const {
|
||||
assert((S < E) && "Backwards interval?");
|
||||
return (start <= S && S < end) && (start < E && E <= end);
|
||||
@ -236,7 +236,7 @@ namespace llvm {
|
||||
float weight; // weight of this interval
|
||||
Ranges ranges; // the ranges in which this register is live
|
||||
VNInfoList valnos; // value#'s
|
||||
|
||||
|
||||
struct InstrSlots {
|
||||
enum {
|
||||
LOAD = 0,
|
||||
@ -281,7 +281,7 @@ namespace llvm {
|
||||
while (I->end <= Pos) ++I;
|
||||
return I;
|
||||
}
|
||||
|
||||
|
||||
void clear() {
|
||||
valnos.clear();
|
||||
ranges.clear();
|
||||
@ -305,7 +305,7 @@ namespace llvm {
|
||||
bool containsOneValue() const { return valnos.size() == 1; }
|
||||
|
||||
unsigned getNumValNums() const { return (unsigned)valnos.size(); }
|
||||
|
||||
|
||||
/// getValNumInfo - Returns pointer to the specified val#.
|
||||
///
|
||||
inline VNInfo *getValNumInfo(unsigned ValNo) {
|
||||
@ -336,6 +336,11 @@ namespace llvm {
|
||||
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
|
||||
/// one defined by the its val#.
|
||||
bool isOnlyLROfValNo(const LiveRange *LR) {
|
||||
@ -346,7 +351,7 @@ namespace llvm {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/// MergeValueNumberInto - This method is called when two value nubmers
|
||||
/// are found to be equivalent. This eliminates V1, replacing all
|
||||
/// 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.
|
||||
void Copy(const LiveInterval &RHS, MachineRegisterInfo *MRI,
|
||||
VNInfo::Allocator &VNInfoAllocator);
|
||||
|
||||
|
||||
bool empty() const { return ranges.empty(); }
|
||||
|
||||
/// beginIndex - Return the lowest numbered slot covered by interval.
|
||||
@ -454,17 +459,19 @@ namespace llvm {
|
||||
iterator FindLiveRangeContaining(SlotIndex Idx);
|
||||
|
||||
/// findDefinedVNInfo - Find the by the specified
|
||||
/// index (register interval) or defined
|
||||
/// index (register interval) or defined
|
||||
VNInfo *findDefinedVNInfoForRegInt(SlotIndex Idx) const;
|
||||
|
||||
/// findDefinedVNInfo - Find the VNInfo that's defined by the specified
|
||||
/// register (stack inteval only).
|
||||
VNInfo *findDefinedVNInfoForStackInt(unsigned Reg) const;
|
||||
|
||||
|
||||
|
||||
/// overlaps - Return true if the intersection of the two live intervals is
|
||||
/// not empty.
|
||||
bool overlaps(const LiveInterval& other) const {
|
||||
if (other.empty())
|
||||
return false;
|
||||
return overlapsFrom(other, other.begin());
|
||||
}
|
||||
|
||||
@ -514,6 +521,15 @@ namespace llvm {
|
||||
///
|
||||
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?
|
||||
bool isSpillable() const {
|
||||
return weight != HUGE_VALF;
|
||||
@ -543,6 +559,7 @@ namespace llvm {
|
||||
Ranges::iterator addRangeFrom(LiveRange LR, Ranges::iterator From);
|
||||
void extendIntervalEndTo(Ranges::iterator I, SlotIndex NewEnd);
|
||||
Ranges::iterator extendIntervalStartTo(Ranges::iterator I, SlotIndex NewStr);
|
||||
void markValNoForDeletion(VNInfo *V);
|
||||
|
||||
LiveInterval& operator=(const LiveInterval& rhs); // DO NOT IMPLEMENT
|
||||
|
||||
|
@ -42,7 +42,7 @@ namespace llvm {
|
||||
class TargetInstrInfo;
|
||||
class TargetRegisterClass;
|
||||
class VirtRegMap;
|
||||
|
||||
|
||||
class LiveIntervals : public MachineFunctionPass {
|
||||
MachineFunction* mf_;
|
||||
MachineRegisterInfo* mri_;
|
||||
@ -68,7 +68,7 @@ namespace llvm {
|
||||
|
||||
public:
|
||||
static char ID; // Pass identification, replacement for typeid
|
||||
LiveIntervals() : MachineFunctionPass(&ID) {}
|
||||
LiveIntervals() : MachineFunctionPass(ID) {}
|
||||
|
||||
// Calculate the spill weight to assign to a single instruction.
|
||||
static float getSpillWeight(bool isDef, bool isUse, unsigned loopDepth);
|
||||
@ -105,6 +105,12 @@ namespace llvm {
|
||||
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,"
|
||||
/// where every function is composed of one thousand units. This
|
||||
/// measure scales properly with empty index slots in the function.
|
||||
@ -117,7 +123,7 @@ namespace llvm {
|
||||
unsigned getFuncInstructionCount() {
|
||||
return indexes_->getFunctionSize();
|
||||
}
|
||||
|
||||
|
||||
/// getApproximateInstructionCount - computes an estimate of the number
|
||||
/// of instructions in a given LiveInterval.
|
||||
unsigned getApproximateInstructionCount(LiveInterval& I) {
|
||||
@ -149,7 +155,7 @@ namespace llvm {
|
||||
/// dupInterval - Duplicate a live interval. The caller is responsible for
|
||||
/// managing the allocated memory.
|
||||
LiveInterval *dupInterval(LiveInterval *li);
|
||||
|
||||
|
||||
/// addLiveRangeToEndOfBlock - Given a register and an instruction,
|
||||
/// adds a live range from that instruction to the end of its MBB.
|
||||
LiveRange addLiveRangeToEndOfBlock(unsigned reg,
|
||||
@ -181,7 +187,7 @@ namespace llvm {
|
||||
SlotIndex getInstructionIndex(const MachineInstr *instr) const {
|
||||
return indexes_->getInstructionIndex(instr);
|
||||
}
|
||||
|
||||
|
||||
/// Returns the instruction associated with the given index.
|
||||
MachineInstr* getInstructionFromIndex(SlotIndex index) const {
|
||||
return indexes_->getInstructionFromIndex(index);
|
||||
@ -190,12 +196,32 @@ namespace llvm {
|
||||
/// Return the first index in the given basic block.
|
||||
SlotIndex getMBBStartIdx(const MachineBasicBlock *mbb) const {
|
||||
return indexes_->getMBBStartIdx(mbb);
|
||||
}
|
||||
}
|
||||
|
||||
/// Return the last index in the given basic block.
|
||||
SlotIndex getMBBEndIdx(const MachineBasicBlock *mbb) const {
|
||||
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 {
|
||||
return indexes_->getMBBFromIndex(index);
|
||||
@ -217,6 +243,10 @@ namespace llvm {
|
||||
indexes_->replaceMachineInstrInMaps(MI, NewMI);
|
||||
}
|
||||
|
||||
void InsertMBBInMaps(MachineBasicBlock *MBB) {
|
||||
indexes_->insertMBBInMaps(MBB);
|
||||
}
|
||||
|
||||
bool findLiveInMBBs(SlotIndex Start, SlotIndex End,
|
||||
SmallVectorImpl<MachineBasicBlock*> &MBBs) const {
|
||||
return indexes_->findLiveInMBBs(Start, End, MBBs);
|
||||
@ -276,7 +306,7 @@ namespace llvm {
|
||||
/// within a single basic block.
|
||||
bool intervalIsInOneMBB(const LiveInterval &li) const;
|
||||
|
||||
private:
|
||||
private:
|
||||
/// computeIntervals - Compute live intervals.
|
||||
void computeIntervals();
|
||||
|
||||
@ -290,7 +320,7 @@ namespace llvm {
|
||||
|
||||
/// isPartialRedef - Return true if the specified def at the specific index
|
||||
/// 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,
|
||||
LiveInterval &interval);
|
||||
|
||||
|
@ -39,7 +39,7 @@ namespace llvm {
|
||||
|
||||
public:
|
||||
static char ID; // Pass identification, replacement for typeid
|
||||
LiveStacks() : MachineFunctionPass(&ID) {}
|
||||
LiveStacks() : MachineFunctionPass(ID) {}
|
||||
|
||||
typedef SS2IntervalMap::iterator iterator;
|
||||
typedef SS2IntervalMap::const_iterator const_iterator;
|
||||
|
@ -46,7 +46,7 @@ class TargetRegisterInfo;
|
||||
class LiveVariables : public MachineFunctionPass {
|
||||
public:
|
||||
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
|
||||
/// the program. We represent this with three different pieces of
|
||||
|
@ -15,6 +15,7 @@
|
||||
#define LLVM_CODEGEN_MACHINEFRAMEINFO_H
|
||||
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
//#include "llvm/ADT/IndexedMap.h"
|
||||
#include "llvm/System/DataTypes.h"
|
||||
#include <cassert>
|
||||
#include <vector>
|
||||
@ -30,15 +31,15 @@ class TargetFrameInfo;
|
||||
class BitVector;
|
||||
|
||||
/// 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 {
|
||||
unsigned Reg;
|
||||
int FrameIdx;
|
||||
|
||||
|
||||
public:
|
||||
explicit CalleeSavedInfo(unsigned R, int FI = 0)
|
||||
: Reg(R), FrameIdx(FI) {}
|
||||
|
||||
|
||||
// Accessors.
|
||||
unsigned getReg() const { return Reg; }
|
||||
int getFrameIdx() const { return FrameIdx; }
|
||||
@ -81,7 +82,7 @@ class MachineFrameInfo {
|
||||
// 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.
|
||||
int64_t SPOffset;
|
||||
|
||||
|
||||
// The size of this object on the stack. 0 means a variable sized object,
|
||||
// ~0ULL means a dead object.
|
||||
uint64_t Size;
|
||||
@ -94,13 +95,23 @@ class MachineFrameInfo {
|
||||
// default, fixed objects are immutable unless marked otherwise.
|
||||
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.
|
||||
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),
|
||||
isSpillSlot(isSS) {}
|
||||
isSpillSlot(isSS), MayNeedSP(NSP), PreAllocated(false) {}
|
||||
};
|
||||
|
||||
/// Objects - The list of stack objects allocated...
|
||||
@ -132,7 +143,7 @@ class MachineFrameInfo {
|
||||
/// to be allocated on entry to the function.
|
||||
///
|
||||
uint64_t StackSize;
|
||||
|
||||
|
||||
/// 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
|
||||
/// this is target-dependent, but it is typically used to adjust between
|
||||
@ -143,10 +154,10 @@ class MachineFrameInfo {
|
||||
/// TargetRegisterInfo::getFrameIndexOffset); when generating code, the
|
||||
/// corresponding adjustments are performed directly.
|
||||
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
|
||||
/// 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
|
||||
/// native alignment maintained by the compiler, dynamic alignment code will
|
||||
/// be needed.
|
||||
@ -171,7 +182,7 @@ class MachineFrameInfo {
|
||||
/// insertion.
|
||||
///
|
||||
unsigned MaxCallFrameSize;
|
||||
|
||||
|
||||
/// 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/
|
||||
/// epilog code inserter, this data used for debug info and exception
|
||||
@ -189,8 +200,24 @@ class MachineFrameInfo {
|
||||
///
|
||||
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:
|
||||
explicit MachineFrameInfo(const TargetFrameInfo &tfi) : TFI(tfi) {
|
||||
explicit MachineFrameInfo(const TargetFrameInfo &tfi) : TFI(tfi) {
|
||||
StackSize = NumFixedObjects = OffsetAdjustment = MaxAlignment = 0;
|
||||
HasVarSizedObjects = false;
|
||||
FrameAddressTaken = false;
|
||||
@ -200,6 +227,9 @@ class MachineFrameInfo {
|
||||
StackProtectorIdx = -1;
|
||||
MaxCallFrameSize = 0;
|
||||
CSIValid = false;
|
||||
LocalFrameSize = 0;
|
||||
LocalFrameMaxAlign = 0;
|
||||
UseLocalStackAllocationBlock = false;
|
||||
}
|
||||
|
||||
/// hasStackObjects - Return true if there are any stack objects in this
|
||||
@ -225,8 +255,8 @@ class MachineFrameInfo {
|
||||
bool isFrameAddressTaken() const { return FrameAddressTaken; }
|
||||
void setFrameAddressIsTaken(bool T) { FrameAddressTaken = T; }
|
||||
|
||||
/// isReturnAddressTaken - This method may be called any time after instruction
|
||||
/// selection is complete to determine if there is a call to
|
||||
/// isReturnAddressTaken - This method may be called any time after
|
||||
/// instruction selection is complete to determine if there is a call to
|
||||
/// \@llvm.returnaddress in this function.
|
||||
bool isReturnAddressTaken() const { return ReturnAddressTaken; }
|
||||
void setReturnAddressIsTaken(bool s) { ReturnAddressTaken = s; }
|
||||
@ -239,13 +269,64 @@ class MachineFrameInfo {
|
||||
///
|
||||
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; }
|
||||
|
||||
/// getNumObjects() - Return the number of objects.
|
||||
/// getNumObjects - Return the number of objects.
|
||||
///
|
||||
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.
|
||||
///
|
||||
int64_t getObjectSize(int ObjectIdx) const {
|
||||
@ -276,6 +357,14 @@ class MachineFrameInfo {
|
||||
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
|
||||
/// from the incoming stack pointer.
|
||||
///
|
||||
@ -307,21 +396,21 @@ class MachineFrameInfo {
|
||||
/// setStackSize - Set the size of the stack...
|
||||
///
|
||||
void setStackSize(uint64_t Size) { StackSize = Size; }
|
||||
|
||||
|
||||
/// getOffsetAdjustment - Return the correction for frame offsets.
|
||||
///
|
||||
int getOffsetAdjustment() const { return OffsetAdjustment; }
|
||||
|
||||
|
||||
/// setOffsetAdjustment - Set the correction for frame offsets.
|
||||
///
|
||||
void setOffsetAdjustment(int Adj) { OffsetAdjustment = Adj; }
|
||||
|
||||
/// getMaxAlignment - Return the alignment in bytes that this function must be
|
||||
/// aligned to, which is greater than the default stack alignment provided by
|
||||
/// getMaxAlignment - Return the alignment in bytes that this function must be
|
||||
/// aligned to, which is greater than the default stack alignment provided by
|
||||
/// the target.
|
||||
///
|
||||
unsigned getMaxAlignment() const { return MaxAlignment; }
|
||||
|
||||
|
||||
/// setMaxAlignment - Set the preferred alignment.
|
||||
///
|
||||
void setMaxAlignment(unsigned Align) { MaxAlignment = Align; }
|
||||
@ -350,8 +439,8 @@ class MachineFrameInfo {
|
||||
/// index with a negative value.
|
||||
///
|
||||
int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool Immutable);
|
||||
|
||||
|
||||
|
||||
|
||||
/// isFixedObjectIndex - Returns true if the specified index corresponds to a
|
||||
/// fixed stack object.
|
||||
bool isFixedObjectIndex(int ObjectIdx) const {
|
||||
@ -382,25 +471,26 @@ class MachineFrameInfo {
|
||||
return Objects[ObjectIdx+NumFixedObjects].Size == ~0ULL;
|
||||
}
|
||||
|
||||
/// CreateStackObject - Create a new statically sized stack object,
|
||||
/// returning a nonnegative identifier to represent it.
|
||||
/// CreateStackObject - Create a new statically sized stack object, returning
|
||||
/// 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!");
|
||||
Objects.push_back(StackObject(Size, Alignment, 0, false, isSS));
|
||||
int Index = (int)Objects.size()-NumFixedObjects-1;
|
||||
Objects.push_back(StackObject(Size, Alignment, 0, false, isSS, MayNeedSP));
|
||||
int Index = (int)Objects.size() - NumFixedObjects - 1;
|
||||
assert(Index >= 0 && "Bad frame index!");
|
||||
MaxAlignment = std::max(MaxAlignment, Alignment);
|
||||
return Index;
|
||||
}
|
||||
|
||||
/// CreateSpillStackObject - Create a new statically sized stack
|
||||
/// object that represents a spill slot, returning a nonnegative
|
||||
/// identifier to represent it.
|
||||
/// CreateSpillStackObject - Create a new statically sized stack object that
|
||||
/// represents a spill slot, returning a nonnegative identifier to represent
|
||||
/// it.
|
||||
///
|
||||
int CreateSpillStackObject(uint64_t Size, unsigned Alignment) {
|
||||
CreateStackObject(Size, Alignment, true);
|
||||
int Index = (int)Objects.size()-NumFixedObjects-1;
|
||||
CreateStackObject(Size, Alignment, true, false);
|
||||
int Index = (int)Objects.size() - NumFixedObjects - 1;
|
||||
MaxAlignment = std::max(MaxAlignment, Alignment);
|
||||
return Index;
|
||||
}
|
||||
@ -417,9 +507,10 @@ class MachineFrameInfo {
|
||||
/// variable sized object is created, whether or not the index returned is
|
||||
/// actually used.
|
||||
///
|
||||
int CreateVariableSizedObject() {
|
||||
int CreateVariableSizedObject(unsigned Alignment) {
|
||||
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;
|
||||
}
|
||||
|
||||
@ -431,7 +522,7 @@ class MachineFrameInfo {
|
||||
|
||||
/// setCalleeSavedInfo - Used by prolog/epilog inserter to set the function's
|
||||
/// callee saved information.
|
||||
void setCalleeSavedInfo(const std::vector<CalleeSavedInfo> &CSI) {
|
||||
void setCalleeSavedInfo(const std::vector<CalleeSavedInfo> &CSI) {
|
||||
CSInfo = CSI;
|
||||
}
|
||||
|
||||
@ -452,7 +543,7 @@ class MachineFrameInfo {
|
||||
BitVector getPristineRegs(const MachineBasicBlock *MBB) const;
|
||||
|
||||
/// 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;
|
||||
|
||||
|
@ -266,7 +266,7 @@ class MachineFunction {
|
||||
|
||||
/// verify - Run the current MachineFunction through the machine code
|
||||
/// 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...
|
||||
typedef BasicBlockListType::iterator iterator;
|
||||
|
@ -31,8 +31,7 @@ class MachineFunction;
|
||||
/// override runOnMachineFunction.
|
||||
class MachineFunctionPass : public FunctionPass {
|
||||
protected:
|
||||
explicit MachineFunctionPass(intptr_t ID) : FunctionPass(ID) {}
|
||||
explicit MachineFunctionPass(void *ID) : FunctionPass(ID) {}
|
||||
explicit MachineFunctionPass(char &ID) : FunctionPass(ID) {}
|
||||
|
||||
/// runOnMachineFunction - This method must be overloaded to perform the
|
||||
/// desired machine code transformation or analysis.
|
||||
|
@ -201,12 +201,14 @@ class MachineInstr : public ilist_node<MachineInstr> {
|
||||
/// isLabel - Returns true if the MachineInstr represents a label.
|
||||
///
|
||||
bool isLabel() const {
|
||||
return getOpcode() == TargetOpcode::DBG_LABEL ||
|
||||
return getOpcode() == TargetOpcode::PROLOG_LABEL ||
|
||||
getOpcode() == TargetOpcode::EH_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 isGCLabel() const { return getOpcode() == TargetOpcode::GC_LABEL; }
|
||||
bool isDebugValue() const { return getOpcode() == TargetOpcode::DBG_VALUE; }
|
||||
|
@ -67,7 +67,7 @@ class MachineLoopInfo : public MachineFunctionPass {
|
||||
public:
|
||||
static char ID; // Pass identification, replacement for typeid
|
||||
|
||||
MachineLoopInfo() : MachineFunctionPass(&ID) {}
|
||||
MachineLoopInfo() : MachineFunctionPass(ID) {}
|
||||
|
||||
LoopInfoBase<MachineBasicBlock, MachineLoop>& getBase() { return LI; }
|
||||
|
||||
|
@ -344,7 +344,7 @@ class MachineModuleInfo : public ImmutablePass {
|
||||
VariableDbgInfo.push_back(std::make_pair(N, std::make_pair(Slot, Loc)));
|
||||
}
|
||||
|
||||
VariableDbgInfoMapTy &getVariableDbgInfo();
|
||||
VariableDbgInfoMapTy &getVariableDbgInfo() { return VariableDbgInfo; }
|
||||
|
||||
}; // End class MachineModuleInfo
|
||||
|
||||
|
@ -30,55 +30,55 @@ namespace llvm {
|
||||
/// createUnreachableBlockEliminationPass - The LLVM code generator does not
|
||||
/// 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
|
||||
/// 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
|
||||
/// the entry block.
|
||||
FunctionPass *createUnreachableBlockEliminationPass();
|
||||
|
||||
/// 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 *
|
||||
createMachineFunctionPrinterPass(raw_ostream &OS,
|
||||
const std::string &Banner ="");
|
||||
|
||||
/// 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.
|
||||
///
|
||||
extern const PassInfo *const MachineDominatorsID;
|
||||
///
|
||||
extern char &MachineDominatorsID;
|
||||
|
||||
/// PHIElimination pass - This pass eliminates machine instruction PHI nodes
|
||||
/// by inserting copy instructions. This destroys SSA information, but is the
|
||||
/// desired input for some register allocators. This pass is "required" by
|
||||
/// these register allocator like this: AU.addRequiredID(PHIEliminationID);
|
||||
///
|
||||
extern const PassInfo *const PHIEliminationID;
|
||||
|
||||
extern char &PHIEliminationID;
|
||||
|
||||
/// StrongPHIElimination pass - This pass eliminates machine instruction PHI
|
||||
/// nodes by inserting copy instructions. This destroys SSA information, but
|
||||
/// is the desired input for some register allocators. This pass is
|
||||
/// "required" by these register allocator like this:
|
||||
/// AU.addRequiredID(PHIEliminationID);
|
||||
/// 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
|
||||
/// copy it can.
|
||||
///
|
||||
extern const PassInfo *const SimpleRegisterCoalescingID;
|
||||
extern char &SimpleRegisterCoalescingID;
|
||||
|
||||
/// TwoAddressInstruction pass - This pass reduces two-address instructions to
|
||||
/// use two operands. This destroys SSA information but it is desired by
|
||||
/// register allocators.
|
||||
extern const PassInfo *const TwoAddressInstructionPassID;
|
||||
extern char &TwoAddressInstructionPassID;
|
||||
|
||||
/// UnreachableMachineBlockElimination pass - This pass removes unreachable
|
||||
/// machine basic blocks.
|
||||
extern const PassInfo *const UnreachableMachineBlockElimID;
|
||||
extern char &UnreachableMachineBlockElimID;
|
||||
|
||||
/// DeadMachineInstructionElim pass - This pass removes dead machine
|
||||
/// instructions.
|
||||
@ -114,7 +114,7 @@ namespace llvm {
|
||||
/// and eliminates abstract frame references.
|
||||
///
|
||||
FunctionPass *createPrologEpilogCodeInserter();
|
||||
|
||||
|
||||
/// LowerSubregs Pass - This pass lowers subregs to register-register copies
|
||||
/// which yields suboptimal, but correct code if the register allocator
|
||||
/// cannot coalesce all subreg operations during allocation.
|
||||
@ -145,36 +145,36 @@ namespace llvm {
|
||||
/// IntrinsicLowering Pass - Performs target-independent LLVM IR
|
||||
/// transformations for highly portable strategies.
|
||||
FunctionPass *createGCLoweringPass();
|
||||
|
||||
|
||||
/// MachineCodeAnalysis Pass - Target-independent pass to mark safe points in
|
||||
/// machine code. Must be added very late during code generation, just prior
|
||||
/// to output, and importantly after all CFG transformations (such as branch
|
||||
/// folding).
|
||||
FunctionPass *createGCMachineCodeAnalysisPass();
|
||||
|
||||
|
||||
/// Deleter Pass - Releases GC metadata.
|
||||
///
|
||||
///
|
||||
FunctionPass *createGCInfoDeleter();
|
||||
|
||||
|
||||
/// Creates a pass to print GC metadata.
|
||||
///
|
||||
///
|
||||
FunctionPass *createGCInfoPrinter(raw_ostream &OS);
|
||||
|
||||
|
||||
/// createMachineCSEPass - This pass performs global CSE on machine
|
||||
/// instructions.
|
||||
FunctionPass *createMachineCSEPass();
|
||||
|
||||
/// createMachineLICMPass - This pass performs LICM on machine instructions.
|
||||
///
|
||||
///
|
||||
FunctionPass *createMachineLICMPass(bool PreRegAlloc = true);
|
||||
|
||||
/// createMachineSinkingPass - This pass performs sinking on machine
|
||||
/// instructions.
|
||||
FunctionPass *createMachineSinkingPass();
|
||||
|
||||
/// createOptimizeExtsPass - This pass performs sign / zero extension
|
||||
/// optimization by increasing uses of extended values.
|
||||
FunctionPass *createOptimizeExtsPass();
|
||||
/// createPeepholeOptimizerPass - This pass performs peephole optimizations -
|
||||
/// like extension and comparison eliminations.
|
||||
FunctionPass *createPeepholeOptimizerPass();
|
||||
|
||||
/// createOptimizePHIsPass - This pass optimizes machine instruction PHIs
|
||||
/// to take advantage of opportunities created during DAG legalization.
|
||||
@ -188,19 +188,23 @@ namespace llvm {
|
||||
|
||||
/// createMachineVerifierPass - This pass verifies cenerated machine code
|
||||
/// instructions for correctness.
|
||||
///
|
||||
/// @param allowDoubleDefs ignore double definitions of
|
||||
/// registers. Useful before LiveVariables has run.
|
||||
FunctionPass *createMachineVerifierPass(bool allowDoubleDefs);
|
||||
FunctionPass *createMachineVerifierPass();
|
||||
|
||||
/// createDwarfEHPass - This pass mulches exception handling code into a form
|
||||
/// 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
|
||||
/// the GCC-style builtin setjmp/longjmp (sjlj) to handling EH control flow.
|
||||
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
|
||||
|
||||
#endif
|
||||
|
@ -31,7 +31,7 @@ namespace llvm {
|
||||
public:
|
||||
static char ID;
|
||||
|
||||
ProcessImplicitDefs() : MachineFunctionPass(&ID) {}
|
||||
ProcessImplicitDefs() : MachineFunctionPass(ID) {}
|
||||
|
||||
virtual void getAnalysisUsage(AnalysisUsage &au) const;
|
||||
|
||||
|
@ -78,12 +78,19 @@ ScheduleDAGSDNodes *createTDRRListDAGScheduler(SelectionDAGISel *IS,
|
||||
ScheduleDAGSDNodes *createSourceListDAGScheduler(SelectionDAGISel *IS,
|
||||
CodeGenOpt::Level OptLevel);
|
||||
|
||||
/// createHybridListDAGScheduler - This creates a bottom up hybrid register
|
||||
/// usage reduction list scheduler that make use of latency information to
|
||||
/// avoid stalls for long latency instructions.
|
||||
/// createHybridListDAGScheduler - This creates a bottom up register pressure
|
||||
/// aware list scheduler that make use of latency information to avoid stalls
|
||||
/// for long latency instructions in low register pressure mode. In high
|
||||
/// register pressure mode it schedules to reduce register pressure.
|
||||
ScheduleDAGSDNodes *createHybridListDAGScheduler(SelectionDAGISel *IS,
|
||||
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
|
||||
/// a hazard recognizer.
|
||||
ScheduleDAGSDNodes *createTDListDAGScheduler(SelectionDAGISel *IS,
|
||||
|
@ -977,10 +977,6 @@ class SelectionDAG {
|
||||
/// been verified as a debug information descriptor.
|
||||
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
|
||||
/// "unroll" a vector operation by splitting out the scalars and operating
|
||||
/// on each element individually. If the ResNE is 0, fully unroll the vector
|
||||
|
@ -128,7 +128,8 @@ namespace llvm {
|
||||
friend class SlotIndexes;
|
||||
friend struct DenseMapInfo<SlotIndex>;
|
||||
|
||||
private:
|
||||
enum Slot { LOAD, USE, DEF, STORE, NUM };
|
||||
|
||||
static const unsigned PHI_BIT = 1 << 2;
|
||||
|
||||
PointerIntPair<IndexListEntry*, 3, unsigned> lie;
|
||||
@ -146,6 +147,11 @@ namespace llvm {
|
||||
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) {
|
||||
IndexListEntry *ptrVal = &v.entry();
|
||||
return (unsigned((intptr_t)ptrVal) >> 4) ^
|
||||
@ -153,11 +159,6 @@ namespace llvm {
|
||||
}
|
||||
|
||||
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() {
|
||||
return SlotIndex(IndexListEntry::getEmptyKeyEntry(), 0);
|
||||
}
|
||||
@ -235,16 +236,31 @@ namespace llvm {
|
||||
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.
|
||||
bool isPHI() const {
|
||||
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
|
||||
/// is the one associated with the LOAD slot for the instruction pointed to
|
||||
/// by this index.
|
||||
@ -475,7 +491,7 @@ namespace llvm {
|
||||
public:
|
||||
static char ID;
|
||||
|
||||
SlotIndexes() : MachineFunctionPass(&ID), indexListHead(0) {}
|
||||
SlotIndexes() : MachineFunctionPass(ID), indexListHead(0) {}
|
||||
|
||||
virtual void getAnalysisUsage(AnalysisUsage &au) const;
|
||||
virtual void releaseMemory();
|
||||
@ -494,6 +510,11 @@ namespace llvm {
|
||||
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.
|
||||
SlotIndex getInvalidIndex() {
|
||||
return getZeroIndex();
|
||||
|
@ -105,7 +105,6 @@ class TargetLoweringObjectFileMachO : public TargetLoweringObjectFile {
|
||||
const MCSection *UStringSection;
|
||||
const MCSection *TextCoalSection;
|
||||
const MCSection *ConstTextCoalSection;
|
||||
const MCSection *ConstDataCoalSection;
|
||||
const MCSection *ConstDataSection;
|
||||
const MCSection *DataCoalSection;
|
||||
const MCSection *DataCommonSection;
|
||||
|
@ -159,14 +159,12 @@ namespace llvm {
|
||||
/// getPow2VectorType - Widens the length of the given vector EVT up to
|
||||
/// the nearest power of 2 and returns that type.
|
||||
MVT getPow2VectorType() const {
|
||||
if (!isPow2VectorType()) {
|
||||
unsigned NElts = getVectorNumElements();
|
||||
unsigned Pow2NElts = 1 << Log2_32_Ceil(NElts);
|
||||
return MVT::getVectorVT(getVectorElementType(), Pow2NElts);
|
||||
}
|
||||
else {
|
||||
if (isPow2VectorType())
|
||||
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,
|
||||
@ -350,17 +348,6 @@ namespace llvm {
|
||||
}
|
||||
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
|
||||
@ -374,21 +361,15 @@ namespace llvm {
|
||||
EVT(MVT::SimpleValueType SVT) : V(SVT), LLVMTy(0) { }
|
||||
EVT(MVT S) : V(S), LLVMTy(0) {}
|
||||
|
||||
bool operator==(const EVT VT) const {
|
||||
if (V.SimpleTy == VT.V.SimpleTy) {
|
||||
if (V.SimpleTy == MVT::INVALID_SIMPLE_VALUE_TYPE)
|
||||
return LLVMTy == VT.LLVMTy;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
bool operator==(EVT VT) const {
|
||||
return !(*this != VT);
|
||||
}
|
||||
bool operator!=(const EVT VT) const {
|
||||
if (V.SimpleTy == VT.V.SimpleTy) {
|
||||
if (V.SimpleTy == MVT::INVALID_SIMPLE_VALUE_TYPE)
|
||||
return LLVMTy != VT.LLVMTy;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
bool operator!=(EVT VT) const {
|
||||
if (V.SimpleTy != VT.V.SimpleTy)
|
||||
return true;
|
||||
if (V.SimpleTy == MVT::INVALID_SIMPLE_VALUE_TYPE)
|
||||
return LLVMTy != VT.LLVMTy;
|
||||
return false;
|
||||
}
|
||||
|
||||
/// getFloatingPointVT - Returns the EVT that represents a floating point
|
||||
@ -402,30 +383,32 @@ namespace llvm {
|
||||
/// number of bits.
|
||||
static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth) {
|
||||
MVT M = MVT::getIntegerVT(BitWidth);
|
||||
if (M.SimpleTy == MVT::INVALID_SIMPLE_VALUE_TYPE)
|
||||
return getExtendedIntegerVT(Context, BitWidth);
|
||||
else
|
||||
if (M.SimpleTy != MVT::INVALID_SIMPLE_VALUE_TYPE)
|
||||
return M;
|
||||
return getExtendedIntegerVT(Context, BitWidth);
|
||||
}
|
||||
|
||||
/// getVectorVT - Returns the EVT that represents a vector NumElements in
|
||||
/// length, where each element is of type VT.
|
||||
static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements) {
|
||||
MVT M = MVT::getVectorVT(VT.V, NumElements);
|
||||
if (M.SimpleTy == MVT::INVALID_SIMPLE_VALUE_TYPE)
|
||||
return getExtendedVectorVT(Context, VT, NumElements);
|
||||
else
|
||||
if (M.SimpleTy != MVT::INVALID_SIMPLE_VALUE_TYPE)
|
||||
return M;
|
||||
return getExtendedVectorVT(Context, VT, NumElements);
|
||||
}
|
||||
|
||||
/// getIntVectorWithNumElements - Return any integer vector type that has
|
||||
/// the specified number of elements.
|
||||
static EVT getIntVectorWithNumElements(LLVMContext &C, unsigned NumElts) {
|
||||
MVT M = MVT::getIntVectorWithNumElements(NumElts);
|
||||
if (M.SimpleTy == MVT::INVALID_SIMPLE_VALUE_TYPE)
|
||||
return getVectorVT(C, MVT::i8, NumElts);
|
||||
else
|
||||
return M;
|
||||
switch (NumElts) {
|
||||
default: return getVectorVT(C, MVT::i8, NumElts);
|
||||
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;
|
||||
}
|
||||
return MVT::INVALID_SIMPLE_VALUE_TYPE;
|
||||
}
|
||||
|
||||
/// 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.
|
||||
bool is64BitVector() const {
|
||||
return isSimple() ?
|
||||
(V==MVT::v8i8 || V==MVT::v4i16 || V==MVT::v2i32 ||
|
||||
V==MVT::v1i64 || V==MVT::v2f32) :
|
||||
isExtended64BitVector();
|
||||
if (!isSimple())
|
||||
return 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.
|
||||
bool is128BitVector() const {
|
||||
return isSimple() ?
|
||||
(V==MVT::v16i8 || V==MVT::v8i16 || V==MVT::v4i32 ||
|
||||
V==MVT::v2i64 || V==MVT::v4f32 || V==MVT::v2f64) :
|
||||
isExtended128BitVector();
|
||||
if (!isSimple())
|
||||
return isExtended128BitVector();
|
||||
return (V==MVT::v16i8 || V==MVT::v8i16 || V==MVT::v4i32 ||
|
||||
V==MVT::v2i64 || V==MVT::v4f32 || V==MVT::v2f64);
|
||||
}
|
||||
|
||||
/// is256BitVector - Return true if this is a 256-bit vector type.
|
||||
inline bool is256BitVector() const {
|
||||
return isSimple()
|
||||
? (V==MVT::v8f32 || V==MVT::v4f64 || V==MVT::v32i8 ||
|
||||
V==MVT::v16i16 || V==MVT::v8i32 || V==MVT::v4i64)
|
||||
: isExtended256BitVector();
|
||||
if (!isSimple())
|
||||
return isExtended256BitVector();
|
||||
return (V == MVT::v8f32 || V == MVT::v4f64 || V == MVT::v32i8 ||
|
||||
V == MVT::v16i16 || V == MVT::v8i32 || V == MVT::v4i64);
|
||||
}
|
||||
|
||||
/// is512BitVector - Return true if this is a 512-bit vector type.
|
||||
@ -550,8 +534,7 @@ namespace llvm {
|
||||
assert(isVector() && "Invalid vector type!");
|
||||
if (isSimple())
|
||||
return V.getVectorElementType();
|
||||
else
|
||||
return getExtendedVectorElementType();
|
||||
return getExtendedVectorElementType();
|
||||
}
|
||||
|
||||
/// getVectorNumElements - Given a vector type, return the number of
|
||||
@ -560,16 +543,14 @@ namespace llvm {
|
||||
assert(isVector() && "Invalid vector type!");
|
||||
if (isSimple())
|
||||
return V.getVectorNumElements();
|
||||
else
|
||||
return getExtendedVectorNumElements();
|
||||
return getExtendedVectorNumElements();
|
||||
}
|
||||
|
||||
/// getSizeInBits - Return the size of the specified value type in bits.
|
||||
unsigned getSizeInBits() const {
|
||||
if (isSimple())
|
||||
return V.getSizeInBits();
|
||||
else
|
||||
return getExtendedSizeInBits();
|
||||
return getExtendedSizeInBits();
|
||||
}
|
||||
|
||||
/// getStoreSize - Return the number of bytes overwritten by a store
|
||||
@ -592,8 +573,7 @@ namespace llvm {
|
||||
unsigned BitWidth = getSizeInBits();
|
||||
if (BitWidth <= 8)
|
||||
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
|
||||
@ -604,12 +584,10 @@ namespace llvm {
|
||||
assert(isInteger() && !isVector() && "Invalid integer type!");
|
||||
unsigned EVTSize = getSizeInBits();
|
||||
for (unsigned IntVT = MVT::FIRST_INTEGER_VALUETYPE;
|
||||
IntVT <= MVT::LAST_INTEGER_VALUETYPE;
|
||||
++IntVT) {
|
||||
IntVT <= MVT::LAST_INTEGER_VALUETYPE; ++IntVT) {
|
||||
EVT HalfVT = EVT((MVT::SimpleValueType)IntVT);
|
||||
if(HalfVT.getSizeInBits() * 2 >= EVTSize) {
|
||||
if (HalfVT.getSizeInBits() * 2 >= EVTSize)
|
||||
return HalfVT;
|
||||
}
|
||||
}
|
||||
return getIntegerVT(Context, (EVTSize + 1) / 2);
|
||||
}
|
||||
|
@ -34,12 +34,16 @@ namespace llvmc {
|
||||
std::string OutFile_;
|
||||
|
||||
public:
|
||||
Action (const std::string& C, const StrVector& A,
|
||||
bool S, const std::string& O)
|
||||
: Command_(C), Args_(A), StopCompilation_(S), OutFile_(O)
|
||||
{}
|
||||
void Construct (const std::string& C, const StrVector& A,
|
||||
bool S, const std::string& 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;
|
||||
bool StopCompilation () const { return StopCompilation_; }
|
||||
const std::string& OutFile() { return OutFile_; }
|
||||
|
40
contrib/llvm/include/llvm/CompilerDriver/AutoGenerated.h
Normal file
40
contrib/llvm/include/llvm/CompilerDriver/AutoGenerated.h
Normal 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
|
@ -18,6 +18,8 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace llvmc {
|
||||
|
||||
namespace SaveTempsEnum { enum Values { Cwd, Obj, Unset }; }
|
||||
|
||||
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<SaveTempsEnum::Values> SaveTemps;
|
||||
|
||||
} // End namespace llvmc.
|
||||
|
||||
#endif // LLVM_INCLUDE_COMPILER_DRIVER_BUILTIN_OPTIONS_H
|
||||
|
@ -32,6 +32,7 @@ def actions;
|
||||
|
||||
def alias_option;
|
||||
def switch_option;
|
||||
def switch_list_option;
|
||||
def parameter_option;
|
||||
def parameter_list_option;
|
||||
def prefix_option;
|
||||
@ -39,7 +40,6 @@ def prefix_list_option;
|
||||
|
||||
// Possible option properties.
|
||||
|
||||
def extern;
|
||||
def help;
|
||||
def hidden;
|
||||
def init;
|
||||
@ -93,17 +93,8 @@ def error;
|
||||
def set_option;
|
||||
def unset_option;
|
||||
|
||||
// Increase/decrease the edge weight.
|
||||
// Increase the edge 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.
|
||||
class OptionList<list<dag> l> {
|
||||
@ -117,31 +108,17 @@ class OptionPreprocessor<dag d> {
|
||||
|
||||
// Map from suffixes to language names
|
||||
|
||||
class LangToSuffixes<string str, list<string> lst> {
|
||||
string lang = str;
|
||||
list<string> suffixes = lst;
|
||||
}
|
||||
def lang_to_suffixes;
|
||||
|
||||
class LanguageMap<list<LangToSuffixes> lst> {
|
||||
list<LangToSuffixes> map = lst;
|
||||
class LanguageMap<list<dag> l> {
|
||||
list<dag> map = l;
|
||||
}
|
||||
|
||||
// Compilation graph
|
||||
|
||||
class EdgeBase<string t1, string t2, dag d> {
|
||||
string a = t1;
|
||||
string b = t2;
|
||||
dag weight = d;
|
||||
}
|
||||
|
||||
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;
|
||||
def edge;
|
||||
def optional_edge;
|
||||
|
||||
class CompilationGraph<list<dag> l> {
|
||||
list<dag> edges = l;
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ namespace llvmc {
|
||||
public:
|
||||
|
||||
/// 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.
|
||||
@ -46,7 +46,7 @@ namespace llvmc {
|
||||
virtual ~Edge() {}
|
||||
|
||||
const std::string& ToolName() const { return ToolName_; }
|
||||
virtual unsigned Weight(const InputLanguagesSet& InLangs) const = 0;
|
||||
virtual int Weight(const InputLanguagesSet& InLangs) const = 0;
|
||||
private:
|
||||
std::string ToolName_;
|
||||
};
|
||||
@ -55,7 +55,7 @@ namespace llvmc {
|
||||
class SimpleEdge : public Edge {
|
||||
public:
|
||||
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.
|
||||
@ -132,32 +132,32 @@ namespace llvmc {
|
||||
void insertNode(Tool* T);
|
||||
|
||||
/// insertEdge - Insert a new edge into the graph. Takes ownership
|
||||
/// of the Edge object.
|
||||
void insertEdge(const std::string& A, Edge* E);
|
||||
/// of the Edge object. Returns non-zero value on error.
|
||||
int insertEdge(const std::string& A, Edge* E);
|
||||
|
||||
/// Build - Build target(s) from the input file set. Command-line
|
||||
/// options are passed implicitly as global variables.
|
||||
/// Build - Build target(s) from the input file set. Command-line options
|
||||
/// 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);
|
||||
|
||||
/// Check - Check the compilation graph for common errors like
|
||||
/// cycles, input/output language mismatch and multiple default
|
||||
/// edges. Prints error messages and in case it finds any errors.
|
||||
/// Check - Check the compilation graph for common errors like cycles,
|
||||
/// input/output language mismatch and multiple default edges. Prints error
|
||||
/// messages and in case it finds any errors.
|
||||
int Check();
|
||||
|
||||
/// getNode - Return a reference to the node correponding to the
|
||||
/// given tool name. Throws std::runtime_error.
|
||||
Node& getNode(const std::string& ToolName);
|
||||
const Node& getNode(const std::string& ToolName) const;
|
||||
/// getNode - Return a reference to the node corresponding to the given tool
|
||||
/// name. Returns 0 on error.
|
||||
Node* getNode(const std::string& ToolName);
|
||||
const Node* getNode(const std::string& ToolName) const;
|
||||
|
||||
/// viewGraph - This function is meant for use from the debugger.
|
||||
/// You can just say 'call G->viewGraph()' and a ghostview window
|
||||
/// should pop up from the program, displaying the compilation
|
||||
/// graph. This depends on there being a 'dot' and 'gv' program
|
||||
/// in your path.
|
||||
/// viewGraph - This function is meant for use from the debugger. You can
|
||||
/// just say 'call G->viewGraph()' and a ghostview window should pop up from
|
||||
/// the program, displaying the compilation graph. This depends on there
|
||||
/// being a 'dot' and 'gv' program in your path.
|
||||
void viewGraph();
|
||||
|
||||
/// writeGraph - Write Graphviz .dot source file to the current direcotry.
|
||||
void writeGraph(const std::string& OutputFilename);
|
||||
int writeGraph(const std::string& OutputFilename);
|
||||
|
||||
// GraphTraits support.
|
||||
friend NodesIterator GraphBegin(CompilationGraph*);
|
||||
@ -167,16 +167,15 @@ namespace llvmc {
|
||||
// Helper functions.
|
||||
|
||||
/// getToolsVector - Return a reference to the list of tool names
|
||||
/// corresponding to the given language name. Throws
|
||||
/// std::runtime_error.
|
||||
const tools_vector_type& getToolsVector(const std::string& LangName) const;
|
||||
/// corresponding to the given language name. Returns 0 on error.
|
||||
const tools_vector_type* getToolsVector(const std::string& LangName) const;
|
||||
|
||||
/// PassThroughGraph - Pass the input file through the toolchain
|
||||
/// starting at StartNode.
|
||||
void PassThroughGraph (const llvm::sys::Path& In, const Node* StartNode,
|
||||
const InputLanguagesSet& InLangs,
|
||||
const llvm::sys::Path& TempDir,
|
||||
const LanguageMap& LangMap) const;
|
||||
/// PassThroughGraph - Pass the input file through the toolchain starting at
|
||||
/// StartNode.
|
||||
int PassThroughGraph (const llvm::sys::Path& In, const Node* StartNode,
|
||||
const InputLanguagesSet& InLangs,
|
||||
const llvm::sys::Path& TempDir,
|
||||
const LanguageMap& LangMap) const;
|
||||
|
||||
/// FindToolChain - Find head of the toolchain corresponding to
|
||||
/// the given file.
|
||||
@ -185,26 +184,32 @@ namespace llvmc {
|
||||
InputLanguagesSet& InLangs,
|
||||
const LanguageMap& LangMap) const;
|
||||
|
||||
/// BuildInitial - Traverse the initial parts of the toolchains.
|
||||
void BuildInitial(InputLanguagesSet& InLangs,
|
||||
const llvm::sys::Path& TempDir,
|
||||
const LanguageMap& LangMap);
|
||||
/// BuildInitial - Traverse the initial parts of the toolchains. Returns
|
||||
/// non-zero value on error.
|
||||
int BuildInitial(InputLanguagesSet& InLangs,
|
||||
const llvm::sys::Path& TempDir,
|
||||
const LanguageMap& LangMap);
|
||||
|
||||
/// TopologicalSort - Sort the nodes in topological order.
|
||||
void TopologicalSort(std::vector<const Node*>& Out);
|
||||
/// TopologicalSortFilterJoinNodes - Call TopologicalSort and
|
||||
/// filter the resulting list to include only Join nodes.
|
||||
void TopologicalSortFilterJoinNodes(std::vector<const Node*>& Out);
|
||||
/// TopologicalSort - Sort the nodes in topological order. Returns non-zero
|
||||
/// value on error.
|
||||
int TopologicalSort(std::vector<const Node*>& Out);
|
||||
/// TopologicalSortFilterJoinNodes - Call TopologicalSort and filter the
|
||||
/// 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().
|
||||
|
||||
/// CheckLanguageNames - Check that output/input language names
|
||||
/// match for all nodes.
|
||||
/// CheckLanguageNames - Check that output/input language names match for
|
||||
/// all nodes. Returns non-zero value on error (number of errors
|
||||
/// encountered).
|
||||
int CheckLanguageNames() const;
|
||||
/// CheckMultipleDefaultEdges - check that there are no multiple
|
||||
/// default default edges.
|
||||
/// CheckMultipleDefaultEdges - check that there are no multiple default
|
||||
/// default edges. Returns non-zero value on error (number of errors
|
||||
/// encountered).
|
||||
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();
|
||||
|
||||
};
|
||||
@ -270,7 +275,7 @@ namespace llvmc {
|
||||
}
|
||||
|
||||
inline pointer operator*() const {
|
||||
return &OwningGraph->getNode((*EdgeIter)->ToolName());
|
||||
return OwningGraph->getNode((*EdgeIter)->ToolName());
|
||||
}
|
||||
inline pointer operator->() const {
|
||||
return this->operator*();
|
||||
@ -301,7 +306,7 @@ namespace llvm {
|
||||
typedef llvmc::NodeChildIterator ChildIteratorType;
|
||||
|
||||
static NodeType* getEntryNode(GraphType* G) {
|
||||
return &G->getNode("root");
|
||||
return G->getNode("root");
|
||||
}
|
||||
|
||||
static ChildIteratorType child_begin(NodeType* N) {
|
||||
|
@ -7,28 +7,22 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Exception classes for llvmc.
|
||||
// Error handling.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef 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 {
|
||||
|
||||
/// error_code - This gets thrown during the compilation process if a tool
|
||||
/// invocation returns a non-zero exit code.
|
||||
class error_code: public std::runtime_error {
|
||||
int Code_;
|
||||
public:
|
||||
error_code (int c)
|
||||
: std::runtime_error("Tool returned error code"), Code_(c)
|
||||
{}
|
||||
|
||||
int code() const { return Code_; }
|
||||
};
|
||||
inline void PrintError(llvm::StringRef Err) {
|
||||
extern const char* ProgramName;
|
||||
llvm::errs() << ProgramName << ": " << Err << '\n';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user