IFC @r243836

This commit is contained in:
Neel Natu 2012-12-04 04:37:42 +00:00
commit 32531ccb84
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/projects/bhyve/; revision=243852
2233 changed files with 165287 additions and 77300 deletions

View File

@ -511,6 +511,8 @@ build32:
.endfor
.for _dir in lib/ncurses/ncurses lib/ncurses/ncursesw lib/libmagic
cd ${.CURDIR}/${_dir}; \
WORLDTMP=${WORLDTMP} \
MAKEFLAGS="-m ${.CURDIR}/tools/build/mk ${.MAKEFLAGS}" \
MAKEOBJDIRPREFIX=${OBJTREE}/lib32 ${MAKE} SSP_CFLAGS= DESTDIR= \
DIRPRFX=${_dir}/ -DNO_LINT -DNO_CPU_CFLAGS -DNO_WARNS -DNO_CTF \
-DEARLY_BUILD build-tools
@ -609,7 +611,7 @@ installcheck_DESTDIR:
#
# Check for missing UIDs/GIDs.
#
CHECK_UIDS=
CHECK_UIDS= auditdistd
CHECK_GIDS= audit
.if ${MK_SENDMAIL} != "no"
CHECK_UIDS+= smmsp
@ -1138,7 +1140,7 @@ _aicasm= sys/modules/aic7xxx/aicasm
_share= share/syscons/scrnmaps
.endif
.if ${MK_GCC} != "no" && (${MK_CLANG_IS_CC} == "no" || ${TARGET} == "pc98")
.if ${MK_GCC} != "no"
_gcc_tools= gnu/usr.bin/cc/cc_tools
.endif

View File

@ -52,6 +52,9 @@ OLD_FILES+=usr/include/clang/3.2/unwind.h
# 20120910: NetBSD compat shims removed
OLD_FILES+=usr/include/cam/scsi/scsi_low_pisa.h
OLD_FILES+=usr/include/sys/device_port.h
# 20120909: doc and www supfiles removed
OLD_FILES+=usr/share/examples/cvsup/doc-supfile
OLD_FILES+=usr/share/examples/cvsup/www-supfile
# 20120908: pf cleanup
OLD_FILES+=usr/include/net/if_pflow.h
# 20120816: new clang import which bumps version from 3.1 to 3.2

View File

@ -4,7 +4,9 @@ This file is maintained and copyrighted by M. Warner Losh <imp@freebsd.org>.
See end of file for further details. For commonly done items, please see the
COMMON ITEMS: section later in the file. These instructions assume that you
basically know what you are doing. If not, then please consult the FreeBSD
handbook.
handbook:
http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/makeworld.html
Items affecting the ports and packages system can be found in
/usr/ports/UPDATING. Please read that file before running portupgrade.
@ -24,6 +26,19 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 10.x IS SLOW:
disable the most expensive debugging functionality run
"ln -s 'abort:false,junk:false' /etc/malloc.conf".)
20121201:
With the addition of auditdistd(8), a new auditdistd user is now
depended on during installworld. "mergemaster -p" can be used to add
the user prior to installworld, as documented in the handbook.
20121117:
The sin6_scope_id member variable in struct sockaddr_in6 is now
filled by the kernel before passing the structure to the userland via
sysctl or routing socket. This means the KAME-specific embedded scope
id in sin6_addr.s6_addr[2] is always cleared in userland application.
This behavior can be controlled by net.inet6.ip6.deembed_scopeid.
__FreeBSD_version is bumped to 1000025.
20121105:
On i386 and amd64 systems WITH_CLANG_IS_CC is now the default.
This means that the world and kernel will be compiled with clang

View File

@ -27,7 +27,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd September 5, 2012
.Dd November 26, 2012
.Dt ZFS 8
.Os
.Sh NAME
@ -760,7 +760,7 @@ If no inheritable
.Tn ACE Ns s
exist that affect the mode, then the mode is set in accordance to the requested
mode from the application.
.It Sy aclmode Ns = Ns Cm discard | groupmask | passthrough
.It Sy aclmode Ns = Ns Cm discard | groupmask | passthrough | restricted
Controls how an
.Tn ACL
is modified during
@ -790,6 +790,32 @@ indicates that no changes are made to the
other than creating or updating the necessary
.Tn ACL
entries to represent the new mode of the file or directory.
An
.Sy aclmode
property of
.Cm restricted
will cause the
.Xr chmod 2
operation to return an error when used on any file or directory which has
a non-trivial
.Tn ACL
whose entries can not be represented by a mode.
.Xr chmod 2
is required to change the set user ID, set group ID, or sticky bits on a file
or directory, as they do not have equivalent
.Tn ACL
entries.
In order to use
.Xr chmod 2
on a file or directory with a non-trivial
.Tn ACL
when
.Sy aclmode
is set to
.Cm restricted ,
you must first remove all
.Tn ACL
entries which do not represent the current mode.
.It Sy atime Ns = Ns Cm on | off
Controls whether the access time for files is updated when they are read.
Turning this property off avoids producing write traffic when reading files and
@ -830,7 +856,7 @@ command or unmounted by the
command.
.Pp
This property is not inherited.
.It Sy checksum Ns = Ns Cm on | off | fletcher2 | fletcher4
.It Sy checksum Ns = Ns Cm on | off | fletcher2 | fletcher4 | sha256
Controls the checksum used to verify data integrity. The default value is
.Cm on ,
which automatically selects an appropriate algorithm (currently,

View File

@ -25,7 +25,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd November 28, 2011
.Dd November 15, 2012
.Dt ZPOOL 8
.Os
.Sh NAME

View File

@ -204,6 +204,7 @@ enum ztest_io_type {
ZTEST_IO_WRITE_ZEROES,
ZTEST_IO_TRUNCATE,
ZTEST_IO_SETATTR,
ZTEST_IO_REWRITE,
ZTEST_IO_TYPES
};
@ -330,6 +331,7 @@ ztest_func_t ztest_vdev_add_remove;
ztest_func_t ztest_vdev_aux_add_remove;
ztest_func_t ztest_split_pool;
ztest_func_t ztest_reguid;
ztest_func_t ztest_spa_upgrade;
uint64_t zopt_always = 0ULL * NANOSEC; /* all the time */
uint64_t zopt_incessant = 1ULL * NANOSEC / 10; /* every 1/10 second */
@ -363,6 +365,7 @@ ztest_info_t ztest_info[] = {
{ ztest_reguid, 1, &zopt_sometimes },
{ ztest_spa_rename, 1, &zopt_rarely },
{ ztest_scrub, 1, &zopt_rarely },
{ ztest_spa_upgrade, 1, &zopt_rarely },
{ ztest_dsl_dataset_promote_busy, 1, &zopt_rarely },
{ ztest_vdev_attach_detach, 1, &zopt_rarely },
{ ztest_vdev_LUN_growth, 1, &zopt_rarely },
@ -797,7 +800,7 @@ ztest_get_ashift(void)
}
static nvlist_t *
make_vdev_file(char *path, char *aux, size_t size, uint64_t ashift)
make_vdev_file(char *path, char *aux, char *pool, size_t size, uint64_t ashift)
{
char pathbuf[MAXPATHLEN];
uint64_t vdev;
@ -813,12 +816,13 @@ make_vdev_file(char *path, char *aux, size_t size, uint64_t ashift)
vdev = ztest_shared->zs_vdev_aux;
(void) snprintf(path, sizeof (pathbuf),
ztest_aux_template, ztest_opts.zo_dir,
ztest_opts.zo_pool, aux, vdev);
pool == NULL ? ztest_opts.zo_pool : pool,
aux, vdev);
} else {
vdev = ztest_shared->zs_vdev_next_leaf++;
(void) snprintf(path, sizeof (pathbuf),
ztest_dev_template, ztest_opts.zo_dir,
ztest_opts.zo_pool, vdev);
pool == NULL ? ztest_opts.zo_pool : pool, vdev);
}
}
@ -840,17 +844,18 @@ make_vdev_file(char *path, char *aux, size_t size, uint64_t ashift)
}
static nvlist_t *
make_vdev_raidz(char *path, char *aux, size_t size, uint64_t ashift, int r)
make_vdev_raidz(char *path, char *aux, char *pool, size_t size,
uint64_t ashift, int r)
{
nvlist_t *raidz, **child;
int c;
if (r < 2)
return (make_vdev_file(path, aux, size, ashift));
return (make_vdev_file(path, aux, pool, size, ashift));
child = umem_alloc(r * sizeof (nvlist_t *), UMEM_NOFAIL);
for (c = 0; c < r; c++)
child[c] = make_vdev_file(path, aux, size, ashift);
child[c] = make_vdev_file(path, aux, pool, size, ashift);
VERIFY(nvlist_alloc(&raidz, NV_UNIQUE_NAME, 0) == 0);
VERIFY(nvlist_add_string(raidz, ZPOOL_CONFIG_TYPE,
@ -869,19 +874,19 @@ make_vdev_raidz(char *path, char *aux, size_t size, uint64_t ashift, int r)
}
static nvlist_t *
make_vdev_mirror(char *path, char *aux, size_t size, uint64_t ashift,
int r, int m)
make_vdev_mirror(char *path, char *aux, char *pool, size_t size,
uint64_t ashift, int r, int m)
{
nvlist_t *mirror, **child;
int c;
if (m < 1)
return (make_vdev_raidz(path, aux, size, ashift, r));
return (make_vdev_raidz(path, aux, pool, size, ashift, r));
child = umem_alloc(m * sizeof (nvlist_t *), UMEM_NOFAIL);
for (c = 0; c < m; c++)
child[c] = make_vdev_raidz(path, aux, size, ashift, r);
child[c] = make_vdev_raidz(path, aux, pool, size, ashift, r);
VERIFY(nvlist_alloc(&mirror, NV_UNIQUE_NAME, 0) == 0);
VERIFY(nvlist_add_string(mirror, ZPOOL_CONFIG_TYPE,
@ -898,8 +903,8 @@ make_vdev_mirror(char *path, char *aux, size_t size, uint64_t ashift,
}
static nvlist_t *
make_vdev_root(char *path, char *aux, size_t size, uint64_t ashift,
int log, int r, int m, int t)
make_vdev_root(char *path, char *aux, char *pool, size_t size, uint64_t ashift,
int log, int r, int m, int t)
{
nvlist_t *root, **child;
int c;
@ -909,7 +914,8 @@ make_vdev_root(char *path, char *aux, size_t size, uint64_t ashift,
child = umem_alloc(t * sizeof (nvlist_t *), UMEM_NOFAIL);
for (c = 0; c < t; c++) {
child[c] = make_vdev_mirror(path, aux, size, ashift, r, m);
child[c] = make_vdev_mirror(path, aux, pool, size, ashift,
r, m);
VERIFY(nvlist_add_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
log) == 0);
}
@ -927,6 +933,27 @@ make_vdev_root(char *path, char *aux, size_t size, uint64_t ashift,
return (root);
}
/*
* Find a random spa version. Returns back a random spa version in the
* range [initial_version, SPA_VERSION_FEATURES].
*/
static uint64_t
ztest_random_spa_version(uint64_t initial_version)
{
uint64_t version = initial_version;
if (version <= SPA_VERSION_BEFORE_FEATURES) {
version = version +
ztest_random(SPA_VERSION_BEFORE_FEATURES - version + 1);
}
if (version > SPA_VERSION_BEFORE_FEATURES)
version = SPA_VERSION_FEATURES;
ASSERT(SPA_VERSION_IS_SUPPORTED(version));
return (version);
}
static int
ztest_random_blocksize(void)
{
@ -1841,6 +1868,12 @@ ztest_get_data(void *arg, lr_write_t *lr, char *buf, zio_t *zio)
DMU_READ_NO_PREFETCH);
if (error == 0) {
blkptr_t *obp = dmu_buf_get_blkptr(db);
if (obp) {
ASSERT(BP_IS_HOLE(bp));
*bp = *obp;
}
zgd->zgd_db = db;
zgd->zgd_bp = bp;
@ -1986,6 +2019,9 @@ ztest_remove(ztest_ds_t *zd, ztest_od_t *od, int count)
continue;
}
/*
* No object was found.
*/
if (od->od_object == 0)
continue;
@ -2101,6 +2137,7 @@ ztest_prealloc(ztest_ds_t *zd, uint64_t object, uint64_t offset, uint64_t size)
static void
ztest_io(ztest_ds_t *zd, uint64_t object, uint64_t offset)
{
int err;
ztest_block_tag_t wbt;
dmu_object_info_t doi;
enum ztest_io_type io_type;
@ -2153,6 +2190,25 @@ ztest_io(ztest_ds_t *zd, uint64_t object, uint64_t offset)
case ZTEST_IO_SETATTR:
(void) ztest_setattr(zd, object);
break;
case ZTEST_IO_REWRITE:
(void) rw_rdlock(&ztest_name_lock);
err = ztest_dsl_prop_set_uint64(zd->zd_name,
ZFS_PROP_CHECKSUM, spa_dedup_checksum(ztest_spa),
B_FALSE);
VERIFY(err == 0 || err == ENOSPC);
err = ztest_dsl_prop_set_uint64(zd->zd_name,
ZFS_PROP_COMPRESSION,
ztest_random_dsl_prop(ZFS_PROP_COMPRESSION),
B_FALSE);
VERIFY(err == 0 || err == ENOSPC);
(void) rw_unlock(&ztest_name_lock);
VERIFY0(dmu_read(zd->zd_os, object, offset, blocksize, data,
DMU_READ_NO_PREFETCH));
(void) ztest_write(zd, object, offset, blocksize, data);
break;
}
(void) rw_unlock(&zd->zd_zilog_lock);
@ -2240,7 +2296,12 @@ ztest_zil_remount(ztest_ds_t *zd, uint64_t id)
{
objset_t *os = zd->zd_os;
VERIFY(mutex_lock(&zd->zd_dirobj_lock) == 0);
/*
* We grab the zd_dirobj_lock to ensure that no other thread is
* updating the zil (i.e. adding in-memory log records) and the
* zd_zilog_lock to block any I/O.
*/
VERIFY0(mutex_lock(&zd->zd_dirobj_lock));
(void) rw_wrlock(&zd->zd_zilog_lock);
/* zfsvfs_teardown() */
@ -2269,7 +2330,7 @@ ztest_spa_create_destroy(ztest_ds_t *zd, uint64_t id)
/*
* Attempt to create using a bad file.
*/
nvroot = make_vdev_root("/dev/bogus", NULL, 0, 0, 0, 0, 0, 1);
nvroot = make_vdev_root("/dev/bogus", NULL, NULL, 0, 0, 0, 0, 0, 1);
VERIFY3U(ENOENT, ==,
spa_create("ztest_bad_file", nvroot, NULL, NULL, NULL));
nvlist_free(nvroot);
@ -2277,7 +2338,7 @@ ztest_spa_create_destroy(ztest_ds_t *zd, uint64_t id)
/*
* Attempt to create using a bad mirror.
*/
nvroot = make_vdev_root("/dev/bogus", NULL, 0, 0, 0, 0, 2, 1);
nvroot = make_vdev_root("/dev/bogus", NULL, NULL, 0, 0, 0, 0, 2, 1);
VERIFY3U(ENOENT, ==,
spa_create("ztest_bad_mirror", nvroot, NULL, NULL, NULL));
nvlist_free(nvroot);
@ -2287,7 +2348,7 @@ ztest_spa_create_destroy(ztest_ds_t *zd, uint64_t id)
* what's in the nvroot; we should fail with EEXIST.
*/
(void) rw_rdlock(&ztest_name_lock);
nvroot = make_vdev_root("/dev/bogus", NULL, 0, 0, 0, 0, 0, 1);
nvroot = make_vdev_root("/dev/bogus", NULL, NULL, 0, 0, 0, 0, 0, 1);
VERIFY3U(EEXIST, ==, spa_create(zo->zo_pool, nvroot, NULL, NULL, NULL));
nvlist_free(nvroot);
VERIFY3U(0, ==, spa_open(zo->zo_pool, &spa, FTAG));
@ -2297,6 +2358,78 @@ ztest_spa_create_destroy(ztest_ds_t *zd, uint64_t id)
(void) rw_unlock(&ztest_name_lock);
}
/* ARGSUSED */
void
ztest_spa_upgrade(ztest_ds_t *zd, uint64_t id)
{
spa_t *spa;
uint64_t initial_version = SPA_VERSION_INITIAL;
uint64_t version, newversion;
nvlist_t *nvroot, *props;
char *name;
VERIFY0(mutex_lock(&ztest_vdev_lock));
name = kmem_asprintf("%s_upgrade", ztest_opts.zo_pool);
/*
* Clean up from previous runs.
*/
(void) spa_destroy(name);
nvroot = make_vdev_root(NULL, NULL, name, ztest_opts.zo_vdev_size, 0,
0, ztest_opts.zo_raidz, ztest_opts.zo_mirrors, 1);
/*
* If we're configuring a RAIDZ device then make sure that the
* the initial version is capable of supporting that feature.
*/
switch (ztest_opts.zo_raidz_parity) {
case 0:
case 1:
initial_version = SPA_VERSION_INITIAL;
break;
case 2:
initial_version = SPA_VERSION_RAIDZ2;
break;
case 3:
initial_version = SPA_VERSION_RAIDZ3;
break;
}
/*
* Create a pool with a spa version that can be upgraded. Pick
* a value between initial_version and SPA_VERSION_BEFORE_FEATURES.
*/
do {
version = ztest_random_spa_version(initial_version);
} while (version > SPA_VERSION_BEFORE_FEATURES);
props = fnvlist_alloc();
fnvlist_add_uint64(props,
zpool_prop_to_name(ZPOOL_PROP_VERSION), version);
VERIFY0(spa_create(name, nvroot, props, NULL, NULL));
fnvlist_free(nvroot);
fnvlist_free(props);
VERIFY0(spa_open(name, &spa, FTAG));
VERIFY3U(spa_version(spa), ==, version);
newversion = ztest_random_spa_version(version + 1);
if (ztest_opts.zo_verbose >= 4) {
(void) printf("upgrading spa version from %llu to %llu\n",
(u_longlong_t)version, (u_longlong_t)newversion);
}
spa_upgrade(spa, newversion);
VERIFY3U(spa_version(spa), >, version);
VERIFY3U(spa_version(spa), ==, fnvlist_lookup_uint64(spa->spa_config,
zpool_prop_to_name(ZPOOL_PROP_VERSION)));
spa_close(spa, FTAG);
strfree(name);
VERIFY0(mutex_unlock(&ztest_vdev_lock));
}
static vdev_t *
vdev_lookup_by_path(vdev_t *vd, const char *path)
{
@ -2386,7 +2519,7 @@ ztest_vdev_add_remove(ztest_ds_t *zd, uint64_t id)
/*
* Make 1/4 of the devices be log devices.
*/
nvroot = make_vdev_root(NULL, NULL,
nvroot = make_vdev_root(NULL, NULL, NULL,
ztest_opts.zo_vdev_size, 0,
ztest_random(4) == 0, ztest_opts.zo_raidz,
zs->zs_mirrors, 1);
@ -2463,7 +2596,7 @@ ztest_vdev_aux_add_remove(ztest_ds_t *zd, uint64_t id)
/*
* Add a new device.
*/
nvlist_t *nvroot = make_vdev_root(NULL, aux,
nvlist_t *nvroot = make_vdev_root(NULL, aux, NULL,
(ztest_opts.zo_vdev_size * 5) / 4, 0, 0, 0, 0, 1);
error = spa_vdev_add(spa, nvroot);
if (error != 0)
@ -2732,7 +2865,7 @@ ztest_vdev_attach_detach(ztest_ds_t *zd, uint64_t id)
/*
* Build the nvlist describing newpath.
*/
root = make_vdev_root(newpath, NULL, newvd == NULL ? newsize : 0,
root = make_vdev_root(newpath, NULL, NULL, newvd == NULL ? newsize : 0,
ashift, 0, 0, 0, 1);
error = spa_vdev_attach(spa, oldguid, root, replacing);
@ -4827,8 +4960,8 @@ ztest_ddt_repair(ztest_ds_t *zd, uint64_t id)
*/
for (int i = 0; i < copies; i++) {
uint64_t offset = i * blocksize;
VERIFY(dmu_buf_hold(os, object, offset, FTAG, &db,
DMU_READ_NO_PREFETCH) == 0);
VERIFY0(dmu_buf_hold(os, object, offset, FTAG, &db,
DMU_READ_NO_PREFETCH));
ASSERT(db->db_offset == offset);
ASSERT(db->db_size == blocksize);
ASSERT(ztest_pattern_match(db->db_data, db->db_size, pattern) ||
@ -4844,8 +4977,8 @@ ztest_ddt_repair(ztest_ds_t *zd, uint64_t id)
/*
* Find out what block we got.
*/
VERIFY(dmu_buf_hold(os, object, 0, FTAG, &db,
DMU_READ_NO_PREFETCH) == 0);
VERIFY0(dmu_buf_hold(os, object, 0, FTAG, &db,
DMU_READ_NO_PREFETCH));
blk = *((dmu_buf_impl_t *)db)->db_blkptr;
dmu_buf_rele(db, FTAG);
@ -4900,7 +5033,7 @@ ztest_reguid(ztest_ds_t *zd, uint64_t id)
if (error != 0)
return;
if (ztest_opts.zo_verbose >= 3) {
if (ztest_opts.zo_verbose >= 4) {
(void) printf("Changed guid old %llu -> %llu\n",
(u_longlong_t)orig, (u_longlong_t)spa_guid(spa));
}
@ -5523,6 +5656,8 @@ ztest_freeze(void)
kernel_init(FREAD | FWRITE);
VERIFY3U(0, ==, spa_open(ztest_opts.zo_pool, &spa, FTAG));
VERIFY3U(0, ==, ztest_dataset_open(0));
spa->spa_debug = B_TRUE;
ztest_spa = spa;
/*
* Force the first log block to be transactionally allocated.
@ -5647,7 +5782,7 @@ ztest_init(ztest_shared_t *zs)
ztest_shared->zs_vdev_next_leaf = 0;
zs->zs_splits = 0;
zs->zs_mirrors = ztest_opts.zo_mirrors;
nvroot = make_vdev_root(NULL, NULL, ztest_opts.zo_vdev_size, 0,
nvroot = make_vdev_root(NULL, NULL, NULL, ztest_opts.zo_vdev_size, 0,
0, ztest_opts.zo_raidz, zs->zs_mirrors, 1);
props = make_random_props();
for (int i = 0; i < SPA_FEATURES; i++) {

View File

@ -11,7 +11,7 @@
======================================================================
Major changes between "less" versions 451 and 453
Major changes between "less" versions 451 and 456
* Allow backslash escaping of metacharacters in LESS environment variable.

View File

@ -7,9 +7,9 @@
**************************************************************************
**************************************************************************
Less, version 453
Less, version 456
This is the distribution of less, version 453, released 27 Oct 2012.
This is the distribution of less, version 456, released 08 Nov 2012.
This program is part of the GNU project (http://www.gnu.org).
This program is free software. You may redistribute it and/or

View File

@ -669,7 +669,7 @@ AH_TOP([
/*
* Sizes of various buffers.
*/
#if 0 /* old sizes for small memory machines
#if 0 /* old sizes for small memory machines */
#define CMDBUF_SIZE 512 /* Buffer for multichar commands */
#define UNGOT_SIZE 100 /* Max chars to unget() */
#define LINEBUF_SIZE 1024 /* Max size of line in input file */

View File

@ -182,7 +182,7 @@
/*
* Sizes of various buffers.
*/
#if 0 /* old sizes for small memory machines
#if 0 /* old sizes for small memory machines */
#define CMDBUF_SIZE 512 /* Buffer for multichar commands */
#define UNGOT_SIZE 100 /* Max chars to unget() */
#define LINEBUF_SIZE 1024 /* Max size of line in input file */

View File

@ -438,18 +438,14 @@ LESS(1) LESS(1)
the command line by beginning the command line option with "-+".
Some options like -k or -D require a string to follow the option let-
ter. The string for that option is considered to end when a space,
tab, dash or dollar sign ($) is found. For example, to set two -D
options on MS-DOS, you can separate them with a dollar sign, like this:
ter. The string for that option is considered to end when a dollar
sign ($) is found. For example, you can set two -D options on MS-DOS
like this:
LESS="Dn9.1$Ds4.1"
or a space like this:
LESS="Dn9.1 Ds4.1"
Any character may be included literally in an option string by preced-
ing it with a backslash.
A dollar sign or backslash may be included literally in an option
string by preceding it with a backslash.
-? or --help
This option displays a summary of the commands accepted by less
@ -1612,4 +1608,4 @@ LESS(1) LESS(1)
Version 453: 27 Oct 2012 LESS(1)
Version 456: 08 Nov 2012 LESS(1)

View File

@ -1,4 +1,4 @@
.TH LESS 1 "Version 453: 27 Oct 2012"
.TH LESS 1 "Version 456: 08 Nov 2012"
.SH NAME
less \- opposite of more
.SH SYNOPSIS
@ -456,18 +456,12 @@ to its default value on the command line by beginning the command
line option with "\-+".
.sp
Some options like \-k or \-D require a string to follow the option letter.
The string for that option is considered to end when a space, tab,
dash or dollar sign ($) is found.
For example, to set two \-D options on MS-DOS,
you can separate them with a dollar sign, like this:
The string for that option is considered to end when a dollar sign ($) is found.
For example, you can set two \-D options on MS-DOS like this:
.sp
LESS="Dn9.1$Ds4.1"
.sp
or a space like this:
.sp
LESS="Dn9.1 Ds4.1"
.sp
Any character may be included literally in an option string
A dollar sign or backslash may be included literally in an option string
by preceding it with a backslash.
.IP "\-? or \-\-help"
This option displays a summary of the commands accepted by

View File

@ -51,4 +51,4 @@ LESSECHO(1) LESSECHO(1)
Version 453: 27 Oct 2012 LESSECHO(1)
Version 456: 08 Nov 2012 LESSECHO(1)

View File

@ -1,4 +1,4 @@
.TH LESSECHO 1 "Version 453: 27 Oct 2012"
.TH LESSECHO 1 "Version 456: 08 Nov 2012"
.SH NAME
lessecho \- expand metacharacters
.SH SYNOPSIS

View File

@ -353,4 +353,4 @@ LESSKEY(1) LESSKEY(1)
Version 453: 27 Oct 2012 LESSKEY(1)
Version 456: 08 Nov 2012 LESSKEY(1)

View File

@ -1,4 +1,4 @@
.TH LESSKEY 1 "Version 453: 27 Oct 2012"
.TH LESSKEY 1 "Version 456: 08 Nov 2012"
.SH NAME
lesskey \- specify key bindings for less
.SH SYNOPSIS

View File

@ -149,7 +149,7 @@ scan_option(s)
if (s == NULL)
return;
if (*str == '+')
every_first_cmd = save(++str);
every_first_cmd = save(str+1);
else
ungetsc(str);
free(str);
@ -585,7 +585,6 @@ optstring(s, p_str, printopt, validchars)
} else
{
if (*p == END_OPTION_STRING ||
*p == ' ' || *p == '\t' || *p == '-' ||
(validchars != NULL && strchr(validchars, *p) == NULL))
/* End of option string. */
break;

View File

@ -757,6 +757,9 @@ v451 7/20/12 Fix typo.
v452 10/19/12 Fix --with-regex=none, fix "stty 0", fix Win32.
Don't quit if errors in cmd line options.
v453 10/27/12 Increase buffer sizes.
v454 11/5/12 Fix typo.
v455 11/5/12 Fix typo.
v456 11/8/12 Fix option string incompatibility.
*/
char version[] = "453";
char version[] = "456";

View File

@ -51,6 +51,9 @@
# define _LIBCPP_LITTLE_ENDIAN 0
# define _LIBCPP_BIG_ENDIAN 1
# endif // _BYTE_ORDER == _LITTLE_ENDIAN
# ifndef __LONG_LONG_SUPPORTED
# define _LIBCPP_HAS_NO_LONG_LONG
# endif // __LONG_LONG_SUPPORTED
#endif // __FreeBSD__
#ifdef _WIN32

View File

@ -97,18 +97,26 @@ _LIBCPP_BEGIN_NAMESPACE_STD
using ::size_t;
using ::div_t;
using ::ldiv_t;
#ifndef _LIBCPP_HAS_NO_LONG_LONG
using ::lldiv_t;
#endif // _LIBCPP_HAS_NO_LONG_LONG
using ::atof;
using ::atoi;
using ::atol;
#ifndef _LIBCPP_HAS_NO_LONG_LONG
using ::atoll;
#endif // _LIBCPP_HAS_NO_LONG_LONG
using ::strtod;
using ::strtof;
using ::strtold;
using ::strtol;
#ifndef _LIBCPP_HAS_NO_LONG_LONG
using ::strtoll;
#endif // _LIBCPP_HAS_NO_LONG_LONG
using ::strtoul;
#ifndef _LIBCPP_HAS_NO_LONG_LONG
using ::strtoull;
#endif // _LIBCPP_HAS_NO_LONG_LONG
using ::rand;
using ::srand;
using ::calloc;
@ -125,10 +133,14 @@ using ::bsearch;
using ::qsort;
using ::abs;
using ::labs;
#ifndef _LIBCPP_HAS_NO_LONG_LONG
using ::llabs;
#endif // _LIBCPP_HAS_NO_LONG_LONG
using ::div;
using ::ldiv;
#ifndef _LIBCPP_HAS_NO_LONG_LONG
using ::lldiv;
#endif // _LIBCPP_HAS_NO_LONG_LONG
using ::mblen;
using ::mbtowc;
using ::wctomb;
@ -145,10 +157,14 @@ using ::aligned_alloc;
// MSVC already has the correct prototype in <stdlib.h.h> #ifdef __cplusplus
#if !defined(_MSC_VER) && !defined(__sun__)
inline _LIBCPP_INLINE_VISIBILITY long abs( long __x) _NOEXCEPT {return labs(__x);}
#ifndef _LIBCPP_HAS_NO_LONG_LONG
inline _LIBCPP_INLINE_VISIBILITY long long abs(long long __x) _NOEXCEPT {return llabs(__x);}
#endif // _LIBCPP_HAS_NO_LONG_LONG
inline _LIBCPP_INLINE_VISIBILITY ldiv_t div( long __x, long __y) _NOEXCEPT {return ldiv(__x, __y);}
#ifndef _LIBCPP_HAS_NO_LONG_LONG
inline _LIBCPP_INLINE_VISIBILITY lldiv_t div(long long __x, long long __y) _NOEXCEPT {return lldiv(__x, __y);}
#endif // _LIBCPP_HAS_NO_LONG_LONG
#endif // _MSC_VER
_LIBCPP_END_NAMESPACE_STD

View File

@ -151,9 +151,13 @@ using ::wcstof;
using ::wcstold;
#endif // _MSC_VER
using ::wcstol;
#ifndef _LIBCPP_HAS_NO_LONG_LONG
using ::wcstoll;
#endif // _LIBCPP_HAS_NO_LONG_LONG
using ::wcstoul;
#ifndef _LIBCPP_HAS_NO_LONG_LONG
using ::wcstoull;
#endif // _LIBCPP_HAS_NO_LONG_LONG
using ::wcscpy;
using ::wcsncpy;
using ::wcscat;

View File

@ -143,7 +143,7 @@ public:
{return !(__x == __y);}
friend exception_ptr current_exception() _NOEXCEPT;
_LIBCPP_NORETURN friend void rethrow_exception(exception_ptr);
friend void rethrow_exception(exception_ptr);
};
template<class _Ep>

View File

@ -317,6 +317,10 @@ template <class T, size_t N> T* end(T (&array)[N]);
#include <type_traits>
#include <cstddef>
#include <iosfwd>
#if __APPLE__
#include <Availability.h>
#endif
#ifdef _LIBCPP_DEBUG
#include <cassert>
#endif
@ -795,7 +799,7 @@ public:
typedef basic_streambuf<_CharT,_Traits> streambuf_type;
typedef basic_istream<_CharT,_Traits> istream_type;
private:
streambuf_type* __sbuf_;
mutable streambuf_type* __sbuf_;
class __proxy
{
@ -809,13 +813,14 @@ private:
};
_LIBCPP_INLINE_VISIBILITY
void __test_for_eof()
bool __test_for_eof() const
{
if (__sbuf_ && traits_type::eq_int_type(__sbuf_->sgetc(), traits_type::eof()))
__sbuf_ = 0;
return __sbuf_ == 0;
}
public:
_LIBCPP_INLINE_VISIBILITY istreambuf_iterator() _NOEXCEPT : __sbuf_(0) {}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR istreambuf_iterator() _NOEXCEPT : __sbuf_(0) {}
_LIBCPP_INLINE_VISIBILITY istreambuf_iterator(istream_type& __s) _NOEXCEPT
: __sbuf_(__s.rdbuf()) {__test_for_eof();}
_LIBCPP_INLINE_VISIBILITY istreambuf_iterator(streambuf_type* __s) _NOEXCEPT
@ -828,19 +833,16 @@ public:
_LIBCPP_INLINE_VISIBILITY char_type* operator->() const {return nullptr;}
_LIBCPP_INLINE_VISIBILITY istreambuf_iterator& operator++()
{
if (traits_type::eq_int_type(__sbuf_->snextc(), traits_type::eof()))
__sbuf_ = 0;
__sbuf_->sbumpc();
return *this;
}
_LIBCPP_INLINE_VISIBILITY __proxy operator++(int)
{
char_type __c = __sbuf_->sgetc();
++(*this);
return __proxy(__c, __sbuf_);
return __proxy(__sbuf_->sbumpc(), __sbuf_);
}
_LIBCPP_INLINE_VISIBILITY bool equal(const istreambuf_iterator& __b) const
{return (__sbuf_ == 0) == (__b.__sbuf_ == 0);}
{return __test_for_eof() == __b.__test_for_eof();}
};
template <class _CharT, class _Traits>
@ -882,6 +884,10 @@ public:
_LIBCPP_INLINE_VISIBILITY ostreambuf_iterator& operator++(int) {return *this;}
_LIBCPP_INLINE_VISIBILITY bool failed() const _NOEXCEPT {return __sbuf_ == 0;}
#if !defined(__APPLE__) || \
(defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED > __MAC_10_8) || \
(defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED > __IPHONE_6_0)
template <class _Ch, class _Tr>
friend
_LIBCPP_HIDDEN
@ -889,6 +895,7 @@ public:
__pad_and_output(ostreambuf_iterator<_Ch, _Tr> __s,
const _Ch* __ob, const _Ch* __op, const _Ch* __oe,
ios_base& __iob, _Ch __fl);
#endif
};
template <class _Iter>

View File

@ -192,6 +192,10 @@ template <class charT> class messages_byname;
#include <nl_types.h>
#endif // !_WIN32
#if __APPLE__
#include <Availability.h>
#endif
#include <__undef_min_max>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@ -1587,6 +1591,10 @@ __pad_and_output(_OutputIterator __s,
return __s;
}
#if !defined(__APPLE__) || \
(defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED > __MAC_10_8) || \
(defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED > __IPHONE_6_0)
template <class _CharT, class _Traits>
_LIBCPP_HIDDEN
ostreambuf_iterator<_CharT, _Traits>
@ -1633,6 +1641,8 @@ __pad_and_output(ostreambuf_iterator<_CharT, _Traits> __s,
return __s;
}
#endif
template <class _CharT, class _OutputIterator>
_OutputIterator
num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,

View File

@ -173,10 +173,11 @@ typedef enum {
LLVMUWTable = 1 << 30,
LLVMNonLazyBind = 1 << 31
// FIXME: This attribute is currently not included in the C API as
// a temporary measure until the API/ABI impact to the C API is understood
// and the path forward agreed upon.
//LLVMAddressSafety = 1ULL << 32
/* FIXME: This attribute is currently not included in the C API as
a temporary measure until the API/ABI impact to the C API is understood
and the path forward agreed upon.
LLVMAddressSafety = 1ULL << 32
*/
} LLVMAttribute;
typedef enum {
@ -282,6 +283,7 @@ typedef enum {
LLVMLinkOnceAnyLinkage, /**< Keep one copy of function when linking (inline)*/
LLVMLinkOnceODRLinkage, /**< Same, but only replaced by something
equivalent. */
LLVMLinkOnceODRAutoHideLinkage, /**< Like LinkOnceODR, but possibly hidden. */
LLVMWeakAnyLinkage, /**< Keep one copy of function when linking (weak) */
LLVMWeakODRLinkage, /**< Same, but only replaced by something
equivalent. */
@ -295,9 +297,7 @@ typedef enum {
LLVMGhostLinkage, /**< Obsolete */
LLVMCommonLinkage, /**< Tentative definitions */
LLVMLinkerPrivateLinkage, /**< Like Private, but linker removes. */
LLVMLinkerPrivateWeakLinkage, /**< Like LinkerPrivate, but is weak. */
LLVMLinkerPrivateWeakDefAutoLinkage /**< Like LinkerPrivateWeak, but possibly
hidden. */
LLVMLinkerPrivateWeakLinkage /**< Like LinkerPrivate, but is weak. */
} LLVMLinkage;
typedef enum {
@ -1803,7 +1803,7 @@ LLVMAttribute LLVMGetAttribute(LLVMValueRef Arg);
* Set the alignment for a function parameter.
*
* @see llvm::Argument::addAttr()
* @see llvm::Attribute::constructAlignmentFromInt()
* @see llvm::AttrBuilder::addAlignmentAttr()
*/
void LLVMSetParamAlignment(LLVMValueRef Arg, unsigned align);
@ -1868,6 +1868,27 @@ LLVMValueRef LLVMMDNode(LLVMValueRef *Vals, unsigned Count);
*/
const char *LLVMGetMDString(LLVMValueRef V, unsigned* Len);
/**
* Obtain the number of operands from an MDNode value.
*
* @param V MDNode to get number of operands from.
* @return Number of operands of the MDNode.
*/
unsigned LLVMGetMDNodeNumOperands(LLVMValueRef V);
/**
* Obtain the given MDNode's operands.
*
* The passed LLVMValueRef pointer should point to enough memory to hold all of
* the operands of the given MDNode (see LLVMGetMDNodeNumOperands) as
* LLVMValueRefs. This memory will be populated with the LLVMValueRefs of the
* MDNode's operands.
*
* @param V MDNode to get the operands from.
* @param Dest Destination array for operands.
*/
void LLVMGetMDNodeOperands(LLVMValueRef V, LLVMValueRef *Dest);
/**
* @}
*/
@ -2688,7 +2709,7 @@ namespace llvm {
template<typename T>
inline T **unwrap(LLVMValueRef *Vals, unsigned Length) {
#if DEBUG
#ifdef DEBUG
for (LLVMValueRef *I = Vals, *E = Vals + Length; I != E; ++I)
cast<T>(*I);
#endif

View File

@ -145,6 +145,15 @@ LLVMDisasmContextRef LLVMCreateDisasm(const char *TripleName, void *DisInfo,
int TagType, LLVMOpInfoCallback GetOpInfo,
LLVMSymbolLookupCallback SymbolLookUp);
/**
* Set the disassembler's options. Returns 1 if it can set the Options and 0
* otherwise.
*/
int LLVMSetDisasmOptions(LLVMDisasmContextRef DC, uint64_t Options);
/* The option to produce marked up assembly. */
#define LLVMDisassembler_Option_UseMarkup 1
/**
* Dispose of a disassembler context.
*/

View File

@ -145,7 +145,7 @@ static inline LLVMBool LLVMInitializeNativeTarget(void) {
/*===-- Target Data -------------------------------------------------------===*/
/** Creates target data from a target layout string.
See the constructor llvm::TargetData::TargetData. */
See the constructor llvm::DataLayout::DataLayout. */
LLVMTargetDataRef LLVMCreateTargetData(const char *StringRep);
/** Adds target data information to a pass manager. This does not take ownership
@ -160,48 +160,58 @@ void LLVMAddTargetLibraryInfo(LLVMTargetLibraryInfoRef, LLVMPassManagerRef);
/** Converts target data to a target layout string. The string must be disposed
with LLVMDisposeMessage.
See the constructor llvm::TargetData::TargetData. */
See the constructor llvm::DataLayout::DataLayout. */
char *LLVMCopyStringRepOfTargetData(LLVMTargetDataRef);
/** Returns the byte order of a target, either LLVMBigEndian or
LLVMLittleEndian.
See the method llvm::TargetData::isLittleEndian. */
See the method llvm::DataLayout::isLittleEndian. */
enum LLVMByteOrdering LLVMByteOrder(LLVMTargetDataRef);
/** Returns the pointer size in bytes for a target.
See the method llvm::TargetData::getPointerSize. */
See the method llvm::DataLayout::getPointerSize. */
unsigned LLVMPointerSize(LLVMTargetDataRef);
/** Returns the pointer size in bytes for a target for a specified
address space.
See the method llvm::DataLayout::getPointerSize. */
unsigned LLVMPointerSizeForAS(LLVMTargetDataRef, unsigned AS);
/** Returns the integer type that is the same size as a pointer on a target.
See the method llvm::TargetData::getIntPtrType. */
See the method llvm::DataLayout::getIntPtrType. */
LLVMTypeRef LLVMIntPtrType(LLVMTargetDataRef);
/** Returns the integer type that is the same size as a pointer on a target.
This version allows the address space to be specified.
See the method llvm::DataLayout::getIntPtrType. */
LLVMTypeRef LLVMIntPtrTypeForAS(LLVMTargetDataRef, unsigned AS);
/** Computes the size of a type in bytes for a target.
See the method llvm::TargetData::getTypeSizeInBits. */
See the method llvm::DataLayout::getTypeSizeInBits. */
unsigned long long LLVMSizeOfTypeInBits(LLVMTargetDataRef, LLVMTypeRef);
/** Computes the storage size of a type in bytes for a target.
See the method llvm::TargetData::getTypeStoreSize. */
See the method llvm::DataLayout::getTypeStoreSize. */
unsigned long long LLVMStoreSizeOfType(LLVMTargetDataRef, LLVMTypeRef);
/** Computes the ABI size of a type in bytes for a target.
See the method llvm::TargetData::getTypeAllocSize. */
See the method llvm::DataLayout::getTypeAllocSize. */
unsigned long long LLVMABISizeOfType(LLVMTargetDataRef, LLVMTypeRef);
/** Computes the ABI alignment of a type in bytes for a target.
See the method llvm::TargetData::getTypeABISize. */
See the method llvm::DataLayout::getTypeABISize. */
unsigned LLVMABIAlignmentOfType(LLVMTargetDataRef, LLVMTypeRef);
/** Computes the call frame alignment of a type in bytes for a target.
See the method llvm::TargetData::getTypeABISize. */
See the method llvm::DataLayout::getTypeABISize. */
unsigned LLVMCallFrameAlignmentOfType(LLVMTargetDataRef, LLVMTypeRef);
/** Computes the preferred alignment of a type in bytes for a target.
See the method llvm::TargetData::getTypeABISize. */
See the method llvm::DataLayout::getTypeABISize. */
unsigned LLVMPreferredAlignmentOfType(LLVMTargetDataRef, LLVMTypeRef);
/** Computes the preferred alignment of a global variable in bytes for a target.
See the method llvm::TargetData::getPreferredAlignment. */
See the method llvm::DataLayout::getPreferredAlignment. */
unsigned LLVMPreferredAlignmentOfGlobal(LLVMTargetDataRef,
LLVMValueRef GlobalVar);
@ -216,7 +226,7 @@ unsigned long long LLVMOffsetOfElement(LLVMTargetDataRef, LLVMTypeRef StructTy,
unsigned Element);
/** Deallocates a TargetData.
See the destructor llvm::TargetData::~TargetData. */
See the destructor llvm::DataLayout::~DataLayout. */
void LLVMDisposeTargetData(LLVMTargetDataRef);
/**
@ -227,15 +237,15 @@ void LLVMDisposeTargetData(LLVMTargetDataRef);
}
namespace llvm {
class TargetData;
class DataLayout;
class TargetLibraryInfo;
inline TargetData *unwrap(LLVMTargetDataRef P) {
return reinterpret_cast<TargetData*>(P);
inline DataLayout *unwrap(LLVMTargetDataRef P) {
return reinterpret_cast<DataLayout*>(P);
}
inline LLVMTargetDataRef wrap(const TargetData *P) {
return reinterpret_cast<LLVMTargetDataRef>(const_cast<TargetData*>(P));
inline LLVMTargetDataRef wrap(const DataLayout *P) {
return reinterpret_cast<LLVMTargetDataRef>(const_cast<DataLayout*>(P));
}
inline TargetLibraryInfo *unwrap(LLVMTargetLibraryInfoRef P) {

View File

@ -104,7 +104,7 @@ char *LLVMGetTargetMachineCPU(LLVMTargetMachineRef T);
LLVMDisposeMessage. */
char *LLVMGetTargetMachineFeatureString(LLVMTargetMachineRef T);
/** Returns the llvm::TargetData used for this llvm:TargetMachine. */
/** Returns the llvm::DataLayout used for this llvm:TargetMachine. */
LLVMTargetDataRef LLVMGetTargetMachineData(LLVMTargetMachineRef T);
/** Emits an asm or object file for the given module to the filename. This

View File

@ -36,6 +36,9 @@ extern "C" {
/** See llvm::createBBVectorizePass function. */
void LLVMAddBBVectorizePass(LLVMPassManagerRef PM);
/** See llvm::createLoopVectorizePass function. */
void LLVMAddLoopVectorizePass(LLVMPassManagerRef PM);
/**
* @}
*/

View File

@ -455,14 +455,11 @@ namespace llvm {
/* The sign bit of this number. */
unsigned int sign: 1;
/* For PPCDoubleDouble, we have a second exponent and sign (the second
significand is appended to the first one, although it would be wrong to
regard these as a single number for arithmetic purposes). These fields
are not meaningful for any other type. */
exponent_t exponent2 : 11;
unsigned int sign2: 1;
};
// See friend declaration above. This additional declaration is required in
// order to compile LLVM with IBM xlC compiler.
hash_code hash_value(const APFloat &Arg);
} /* namespace llvm */
#endif /* LLVM_FLOAT_H */

View File

@ -251,7 +251,7 @@ class APInt {
/// constructor.
APInt(unsigned numBits, unsigned numWords, const uint64_t bigVal[]);
/// This constructor interprets the string \arg str in the given radix. The
/// This constructor interprets the string \p str in the given radix. The
/// interpretation stops when the first character that is not suitable for the
/// radix is encountered, or the end of the string. Acceptable radix values
/// are 2, 8, 10, 16, and 36. It is an error for the value implied by the
@ -760,7 +760,7 @@ class APInt {
APInt shl(unsigned shiftAmt) const {
assert(shiftAmt <= BitWidth && "Invalid shift amount");
if (isSingleWord()) {
if (shiftAmt == BitWidth)
if (shiftAmt >= BitWidth)
return APInt(BitWidth, 0); // avoid undefined shift results
return APInt(BitWidth, VAL << shiftAmt);
}
@ -1231,15 +1231,15 @@ class APInt {
}
/// This method determines how many bits are required to hold the APInt
/// equivalent of the string given by \arg str.
/// equivalent of the string given by \p str.
/// @brief Get bits required for string value.
static unsigned getBitsNeeded(StringRef str, uint8_t radix);
/// countLeadingZeros - This function is an APInt version of the
/// countLeadingZeros_{32,64} functions in MathExtras.h. It counts the number
/// of zeros from the most significant bit to the first one bit.
/// @returns BitWidth if the value is zero.
/// @returns the number of zeros from the most significant bit to the first
/// @returns BitWidth if the value is zero, otherwise
/// returns the number of zeros from the most significant bit to the first
/// one bits.
unsigned countLeadingZeros() const {
if (isSingleWord()) {
@ -1252,8 +1252,8 @@ class APInt {
/// countLeadingOnes - This function is an APInt version of the
/// countLeadingOnes_{32,64} functions in MathExtras.h. It counts the number
/// of ones from the most significant bit to the first zero bit.
/// @returns 0 if the high order bit is not set
/// @returns the number of 1 bits from the most significant to the least
/// @returns 0 if the high order bit is not set, otherwise
/// returns the number of 1 bits from the most significant to the least
/// @brief Count the number of leading one bits.
unsigned countLeadingOnes() const;
@ -1266,8 +1266,8 @@ class APInt {
/// countTrailingZeros - This function is an APInt version of the
/// countTrailingZeros_{32,64} functions in MathExtras.h. It counts
/// the number of zeros from the least significant bit to the first set bit.
/// @returns BitWidth if the value is zero.
/// @returns the number of zeros from the least significant bit to the first
/// @returns BitWidth if the value is zero, otherwise
/// returns the number of zeros from the least significant bit to the first
/// one bit.
/// @brief Count the number of trailing zero bits.
unsigned countTrailingZeros() const;
@ -1275,8 +1275,8 @@ class APInt {
/// countTrailingOnes - This function is an APInt version of the
/// countTrailingOnes_{32,64} functions in MathExtras.h. It counts
/// the number of ones from the least significant bit to the first zero bit.
/// @returns BitWidth if the value is all ones.
/// @returns the number of ones from the least significant bit to the first
/// @returns BitWidth if the value is all ones, otherwise
/// returns the number of ones from the least significant bit to the first
/// zero bit.
/// @brief Count the number of trailing one bits.
unsigned countTrailingOnes() const {
@ -1288,8 +1288,8 @@ class APInt {
/// countPopulation - This function is an APInt version of the
/// countPopulation_{32,64} functions in MathExtras.h. It counts the number
/// of 1 bits in the APInt value.
/// @returns 0 if the value is zero.
/// @returns the number of set bits.
/// @returns 0 if the value is zero, otherwise returns the number of set
/// bits.
/// @brief Count the number of bits set.
unsigned countPopulation() const {
if (isSingleWord())
@ -1780,6 +1780,9 @@ inline APInt Not(const APInt& APIVal) {
} // End of APIntOps namespace
// See friend declaration above. This additional declaration is required in
// order to compile LLVM with IBM xlC compiler.
hash_code hash_value(const APInt &Arg);
} // End of llvm namespace
#endif

View File

@ -59,12 +59,17 @@ namespace llvm {
ArrayRef(const T *begin, const T *end)
: Data(begin), Length(end - begin) {}
/// Construct an ArrayRef from a SmallVector.
/*implicit*/ ArrayRef(const SmallVectorTemplateCommon<T> &Vec)
: Data(Vec.data()), Length(Vec.size()) {}
/// Construct an ArrayRef from a SmallVector. This is templated in order to
/// avoid instantiating SmallVectorTemplateCommon<T> whenever we
/// copy-construct an ArrayRef.
template<typename U>
/*implicit*/ ArrayRef(const SmallVectorTemplateCommon<T, U> &Vec)
: Data(Vec.data()), Length(Vec.size()) {
}
/// Construct an ArrayRef from a std::vector.
/*implicit*/ ArrayRef(const std::vector<T> &Vec)
template<typename A>
/*implicit*/ ArrayRef(const std::vector<T, A> &Vec)
: Data(Vec.empty() ? (T*)0 : &Vec[0]), Length(Vec.size()) {}
/// Construct an ArrayRef from a C array.

View File

@ -172,7 +172,7 @@ class BitVector {
unsigned BitPos = Prev % BITWORD_SIZE;
BitWord Copy = Bits[WordPos];
// Mask off previous bits.
Copy &= ~0L << BitPos;
Copy &= ~0UL << BitPos;
if (Copy != 0) {
if (sizeof(BitWord) == 4)
@ -237,6 +237,34 @@ class BitVector {
return *this;
}
/// set - Efficiently set a range of bits in [I, E)
BitVector &set(unsigned I, unsigned E) {
assert(I <= E && "Attempted to set backwards range!");
assert(E <= size() && "Attempted to set out-of-bounds range!");
if (I == E) return *this;
if (I / BITWORD_SIZE == E / BITWORD_SIZE) {
BitWord EMask = 1UL << (E % BITWORD_SIZE);
BitWord IMask = 1UL << (I % BITWORD_SIZE);
BitWord Mask = EMask - IMask;
Bits[I / BITWORD_SIZE] |= Mask;
return *this;
}
BitWord PrefixMask = ~0UL << (I % BITWORD_SIZE);
Bits[I / BITWORD_SIZE] |= PrefixMask;
I = RoundUpToAlignment(I, BITWORD_SIZE);
for (; I + BITWORD_SIZE <= E; I += BITWORD_SIZE)
Bits[I / BITWORD_SIZE] = ~0UL;
BitWord PostfixMask = (1UL << (E % BITWORD_SIZE)) - 1;
Bits[I / BITWORD_SIZE] |= PostfixMask;
return *this;
}
BitVector &reset() {
init_words(Bits, Capacity, false);
return *this;
@ -247,6 +275,34 @@ class BitVector {
return *this;
}
/// reset - Efficiently reset a range of bits in [I, E)
BitVector &reset(unsigned I, unsigned E) {
assert(I <= E && "Attempted to reset backwards range!");
assert(E <= size() && "Attempted to reset out-of-bounds range!");
if (I == E) return *this;
if (I / BITWORD_SIZE == E / BITWORD_SIZE) {
BitWord EMask = 1UL << (E % BITWORD_SIZE);
BitWord IMask = 1UL << (I % BITWORD_SIZE);
BitWord Mask = EMask - IMask;
Bits[I / BITWORD_SIZE] &= ~Mask;
return *this;
}
BitWord PrefixMask = ~0UL << (I % BITWORD_SIZE);
Bits[I / BITWORD_SIZE] &= ~PrefixMask;
I = RoundUpToAlignment(I, BITWORD_SIZE);
for (; I + BITWORD_SIZE <= E; I += BITWORD_SIZE)
Bits[I / BITWORD_SIZE] = 0UL;
BitWord PostfixMask = (1UL << (E % BITWORD_SIZE)) - 1;
Bits[I / BITWORD_SIZE] &= ~PostfixMask;
return *this;
}
BitVector &flip() {
for (unsigned i = 0; i < NumBitWords(size()); ++i)
Bits[i] = ~Bits[i];
@ -311,7 +367,7 @@ class BitVector {
return !(*this == RHS);
}
// Intersection, union, disjoint union.
/// Intersection, union, disjoint union.
BitVector &operator&=(const BitVector &RHS) {
unsigned ThisWords = NumBitWords(size());
unsigned RHSWords = NumBitWords(RHS.size());
@ -328,7 +384,7 @@ class BitVector {
return *this;
}
// reset - Reset bits that are set in RHS. Same as *this &= ~RHS.
/// reset - Reset bits that are set in RHS. Same as *this &= ~RHS.
BitVector &reset(const BitVector &RHS) {
unsigned ThisWords = NumBitWords(size());
unsigned RHSWords = NumBitWords(RHS.size());
@ -338,6 +394,23 @@ class BitVector {
return *this;
}
/// test - Check if (This - RHS) is zero.
/// This is the same as reset(RHS) and any().
bool test(const BitVector &RHS) const {
unsigned ThisWords = NumBitWords(size());
unsigned RHSWords = NumBitWords(RHS.size());
unsigned i;
for (i = 0; i != std::min(ThisWords, RHSWords); ++i)
if ((Bits[i] & ~RHS.Bits[i]) != 0)
return true;
for (; i != ThisWords ; ++i)
if (Bits[i] != 0)
return true;
return false;
}
BitVector &operator|=(const BitVector &RHS) {
if (size() < RHS.size())
resize(RHS.size());
@ -451,8 +524,11 @@ class BitVector {
// Then set any stray high bits of the last used word.
unsigned ExtraBits = Size % BITWORD_SIZE;
if (ExtraBits) {
Bits[UsedWords-1] &= ~(~0L << ExtraBits);
Bits[UsedWords-1] |= (0 - (BitWord)t) << ExtraBits;
BitWord ExtraBitMask = ~0UL << ExtraBits;
if (t)
Bits[UsedWords-1] |= ExtraBitMask;
else
Bits[UsedWords-1] &= ~ExtraBitMask;
}
}

View File

@ -48,17 +48,18 @@ class DAGDeltaAlgorithm {
public:
virtual ~DAGDeltaAlgorithm() {}
/// Run - Minimize the DAG formed by the \arg Changes vertices and the \arg
/// Dependencies edges by executing \see ExecuteOneTest() on subsets of
/// Run - Minimize the DAG formed by the \p Changes vertices and the
/// \p Dependencies edges by executing \see ExecuteOneTest() on subsets of
/// changes and returning the smallest set which still satisfies the test
/// predicate and the input \arg Dependencies.
/// predicate and the input \p Dependencies.
///
/// \param Changes The list of changes.
///
/// \param Dependencies The list of dependencies amongst changes. For each
/// (x,y) in \arg Dependencies, both x and y must be in \arg Changes. The
/// minimization algorithm guarantees that for each tested changed set S, x
/// \in S implies y \in S. It is an error to have cyclic dependencies.
/// (x,y) in \p Dependencies, both x and y must be in \p Changes. The
/// minimization algorithm guarantees that for each tested changed set S,
/// \f$ x \in S \f$ implies \f$ y \in S \f$. It is an error to have cyclic
/// dependencies.
changeset_ty Run(const changeset_ty &Changes,
const std::vector<edge_ty> &Dependencies);
@ -67,7 +68,7 @@ class DAGDeltaAlgorithm {
const changesetlist_ty &Sets,
const changeset_ty &Required) {}
/// ExecuteOneTest - Execute a single test predicate on the change set \arg S.
/// ExecuteOneTest - Execute a single test predicate on the change set \p S.
virtual bool ExecuteOneTest(const changeset_ty &S) = 0;
};

View File

@ -45,23 +45,23 @@ class DeltaAlgorithm {
/// since we always reduce following a success.
std::set<changeset_ty> FailedTestsCache;
/// GetTestResult - Get the test result for the \arg Changes from the
/// GetTestResult - Get the test result for the \p Changes from the
/// cache, executing the test if necessary.
///
/// \param Changes - The change set to test.
/// \return - The test result.
bool GetTestResult(const changeset_ty &Changes);
/// Split - Partition a set of changes \arg S into one or two subsets.
/// Split - Partition a set of changes \p S into one or two subsets.
void Split(const changeset_ty &S, changesetlist_ty &Res);
/// Delta - Minimize a set of \arg Changes which has been partioned into
/// Delta - Minimize a set of \p Changes which has been partioned into
/// smaller sets, by attempting to remove individual subsets.
changeset_ty Delta(const changeset_ty &Changes,
const changesetlist_ty &Sets);
/// Search - Search for a subset (or subsets) in \arg Sets which can be
/// removed from \arg Changes while still satisfying the predicate.
/// Search - Search for a subset (or subsets) in \p Sets which can be
/// removed from \p Changes while still satisfying the predicate.
///
/// \param Res - On success, a subset of Changes which satisfies the
/// predicate.
@ -74,13 +74,13 @@ class DeltaAlgorithm {
virtual void UpdatedSearchState(const changeset_ty &Changes,
const changesetlist_ty &Sets) {}
/// ExecuteOneTest - Execute a single test predicate on the change set \arg S.
/// ExecuteOneTest - Execute a single test predicate on the change set \p S.
virtual bool ExecuteOneTest(const changeset_ty &S) = 0;
public:
virtual ~DeltaAlgorithm();
/// Run - Minimize the set \arg Changes by executing \see ExecuteOneTest() on
/// Run - Minimize the set \p Changes by executing \see ExecuteOneTest() on
/// subsets of changes and returning the smallest set which still satisfies
/// the test predicate.
changeset_ty Run(const changeset_ty &Changes);

View File

@ -420,9 +420,10 @@ class DenseMapBase {
NumBuckets = getNumBuckets();
}
if (NumBuckets-(NewNumEntries+getNumTombstones()) <= NumBuckets/8) {
this->grow(NumBuckets);
this->grow(NumBuckets * 2);
LookupBucketFor(Key, TheBucket);
}
assert(TheBucket);
// Only update the state after we've grown our bucket space appropriately
// so that when growing buckets we have self-consistent entry count.
@ -599,7 +600,7 @@ class DenseMap
unsigned OldNumBuckets = NumBuckets;
BucketT *OldBuckets = Buckets;
allocateBuckets(std::max<unsigned>(64, NextPowerOf2(AtLeast)));
allocateBuckets(std::max<unsigned>(64, NextPowerOf2(AtLeast-1)));
assert(Buckets);
if (!OldBuckets) {
this->BaseT::initEmpty();
@ -825,11 +826,11 @@ class SmallDenseMap
}
void grow(unsigned AtLeast) {
if (AtLeast > InlineBuckets)
AtLeast = std::max<unsigned>(64, NextPowerOf2(AtLeast));
if (AtLeast >= InlineBuckets)
AtLeast = std::max<unsigned>(64, NextPowerOf2(AtLeast-1));
if (Small) {
if (AtLeast <= InlineBuckets)
if (AtLeast < InlineBuckets)
return; // Nothing to do.
// First move the inline buckets into a temporary storage.

View File

@ -31,12 +31,12 @@ struct DenseMapInfo {
template<typename T>
struct DenseMapInfo<T*> {
static inline T* getEmptyKey() {
intptr_t Val = -1;
uintptr_t Val = static_cast<uintptr_t>(-1);
Val <<= PointerLikeTypeTraits<T*>::NumLowBitsAvailable;
return reinterpret_cast<T*>(Val);
}
static inline T* getTombstoneKey() {
intptr_t Val = -2;
uintptr_t Val = static_cast<uintptr_t>(-2);
Val <<= PointerLikeTypeTraits<T*>::NumLowBitsAvailable;
return reinterpret_cast<T*>(Val);
}
@ -105,7 +105,7 @@ template<> struct DenseMapInfo<int> {
// Provide DenseMapInfo for longs.
template<> struct DenseMapInfo<long> {
static inline long getEmptyKey() {
return (1UL << (sizeof(long) * 8 - 1)) - 1L;
return (1UL << (sizeof(long) * 8 - 1)) - 1UL;
}
static inline long getTombstoneKey() { return getEmptyKey() - 1L; }
static unsigned getHashValue(const long& Val) {

View File

@ -33,6 +33,7 @@ namespace llvm {
///
/// Here is a simple example using integers:
///
/// \code
/// EquivalenceClasses<int> EC;
/// EC.unionSets(1, 2); // insert 1, 2 into the same set
/// EC.insert(4); EC.insert(5); // insert 4, 5 into own sets
@ -46,6 +47,7 @@ namespace llvm {
/// cerr << *MI << " "; // Print member.
/// cerr << "\n"; // Finish set.
/// }
/// \endcode
///
/// This example prints:
/// 4

View File

@ -278,6 +278,10 @@ class FoldingSetNodeIDRef {
bool operator==(FoldingSetNodeIDRef) const;
/// Used to compare the "ordering" of two nodes as defined by the
/// profiled bits and their ordering defined by memcmp().
bool operator<(FoldingSetNodeIDRef) const;
const unsigned *getData() const { return Data; }
size_t getSize() const { return Size; }
};
@ -327,6 +331,11 @@ class FoldingSetNodeID {
bool operator==(const FoldingSetNodeID &RHS) const;
bool operator==(const FoldingSetNodeIDRef RHS) const;
/// Used to compare the "ordering" of two nodes as defined by the
/// profiled bits and their ordering defined by memcmp().
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
/// interned data.

View File

@ -409,7 +409,6 @@ bool store_and_advance(char *&buffer_ptr, char *buffer_end, const T& value,
/// combining them, this (as an optimization) directly combines the integers.
template <typename InputIteratorT>
hash_code hash_combine_range_impl(InputIteratorT first, InputIteratorT last) {
typedef typename std::iterator_traits<InputIteratorT>::value_type ValueT;
const size_t seed = get_execution_seed();
char buffer[64], *buffer_ptr = buffer;
char *const buffer_end = buffer_ptr + array_lengthof(buffer);
@ -711,7 +710,7 @@ hash_code hash_combine(const T1 &arg1) {
#endif
// Implementation details for implementatinos of hash_value overloads provided
// Implementation details for implementations of hash_value overloads provided
// here.
namespace hashing {
namespace detail {

View File

@ -33,9 +33,8 @@ class ImmutableListImpl : public FoldingSetNode {
friend class ImmutableListFactory<T>;
// Do not implement.
void operator=(const ImmutableListImpl&);
ImmutableListImpl(const ImmutableListImpl&);
void operator=(const ImmutableListImpl&) LLVM_DELETED_FUNCTION;
ImmutableListImpl(const ImmutableListImpl&) LLVM_DELETED_FUNCTION;
public:
const T& getHead() const { return Head; }

View File

@ -122,8 +122,8 @@ class ImmutableMap {
}
private:
Factory(const Factory& RHS); // DO NOT IMPLEMENT
void operator=(const Factory& RHS); // DO NOT IMPLEMENT
Factory(const Factory& RHS) LLVM_DELETED_FUNCTION;
void operator=(const Factory& RHS) LLVM_DELETED_FUNCTION;
};
bool contains(key_type_ref K) const {

View File

@ -22,7 +22,6 @@
#include <cassert>
#include <functional>
#include <vector>
#include <stdio.h>
namespace llvm {
@ -84,13 +83,13 @@ class ImutAVLTree {
}
return NULL;
}
/// getMaxElement - Find the subtree associated with the highest ranged
/// key value.
ImutAVLTree* getMaxElement() {
ImutAVLTree *T = this;
ImutAVLTree *Right = T->getRight();
while (Right) { T = right; right = T->getRight(); }
ImutAVLTree *Right = T->getRight();
while (Right) { T = Right; Right = T->getRight(); }
return T;
}
@ -258,7 +257,7 @@ class ImutAVLTree {
/// method returns false for an instance of ImutAVLTree, all subtrees
/// will also have this method return false. The converse is not true.
bool isMutable() const { return IsMutable; }
/// hasCachedDigest - Returns true if the digest for this tree is cached.
/// This can only be true if the tree is immutable.
bool hasCachedDigest() const { return IsDigestCached; }
@ -280,7 +279,7 @@ class ImutAVLTree {
assert(isMutable() && "Mutable flag already removed.");
IsMutable = false;
}
/// markedCachedDigest - Clears the NoCachedDigest flag for a tree.
void markedCachedDigest() {
assert(!hasCachedDigest() && "NoCachedDigest flag already removed.");
@ -349,7 +348,7 @@ class ImutAVLTree {
else
factory->Cache[factory->maskCacheIndex(computeDigest())] = next;
}
// We need to clear the mutability bit in case we are
// destroying the node as part of a sweep in ImutAVLFactory::recoverNodes().
IsMutable = false;
@ -415,7 +414,7 @@ class ImutAVLFactory {
TreeTy* getEmptyTree() const { return NULL; }
protected:
//===--------------------------------------------------===//
// A bunch of quick helper functions used for reasoning
// about the properties of trees and their children.
@ -461,7 +460,7 @@ class ImutAVLFactory {
// returned to the caller.
//===--------------------------------------------------===//
TreeTy* createNode(TreeTy* L, value_type_ref V, TreeTy* R) {
TreeTy* createNode(TreeTy* L, value_type_ref V, TreeTy* R) {
BumpPtrAllocator& A = getAllocator();
TreeTy* T;
if (!freeNodes.empty()) {
@ -469,8 +468,7 @@ class ImutAVLFactory {
freeNodes.pop_back();
assert(T != L);
assert(T != R);
}
else {
} else {
T = (TreeTy*) A.Allocate<TreeTy>();
}
new (T) TreeTy(this, L, R, V, incrementHeight(L,R));
@ -513,7 +511,8 @@ class ImutAVLFactory {
return createNode(createNode(LL,L,LRL), LR, createNode(LRR,V,R));
}
else if (hr > hl + 2) {
if (hr > hl + 2) {
assert(!isEmpty(R) && "Right tree cannot be empty to have a height >= 2");
TreeTy *RL = getLeft(R);
@ -529,8 +528,8 @@ class ImutAVLFactory {
return createNode(createNode(L,V,RLL), RL, createNode(RLR,R,RR));
}
else
return createNode(L,V,R);
return createNode(L,V,R);
}
/// add_internal - Creates a new tree that includes the specified
@ -604,7 +603,7 @@ class ImutAVLFactory {
markImmutable(getLeft(T));
markImmutable(getRight(T));
}
public:
TreeTy *getCanonicalTree(TreeTy *TNew) {
if (!TNew)
@ -937,7 +936,7 @@ class ImmutableSet {
private:
TreeTy *Root;
public:
/// Constructs a set from a pointer to a tree root. In general one
/// should use a Factory object to create sets instead of directly
@ -1006,10 +1005,10 @@ class ImmutableSet {
typename TreeTy::Factory *getTreeFactory() const {
return const_cast<typename TreeTy::Factory *>(&F);
}
private:
Factory(const Factory& RHS); // DO NOT IMPLEMENT
void operator=(const Factory& RHS); // DO NOT IMPLEMENT
Factory(const Factory& RHS) LLVM_DELETED_FUNCTION;
void operator=(const Factory& RHS) LLVM_DELETED_FUNCTION;
};
friend class Factory;
@ -1027,11 +1026,11 @@ class ImmutableSet {
return Root && RHS.Root ? Root->isNotEqual(*RHS.Root) : Root != RHS.Root;
}
TreeTy *getRoot() {
TreeTy *getRoot() {
if (Root) { Root->retain(); }
return Root;
}
TreeTy *getRootWithoutRetain() const {
return Root;
}
@ -1092,7 +1091,7 @@ class ImmutableSet {
void validateTree() const { if (Root) Root->validateTree(); }
};
// NOTE: This may some day replace the current ImmutableSet.
template <typename ValT, typename ValInfo = ImutContainerInfo<ValT> >
class ImmutableSetRef {
@ -1101,11 +1100,11 @@ class ImmutableSetRef {
typedef typename ValInfo::value_type_ref value_type_ref;
typedef ImutAVLTree<ValInfo> TreeTy;
typedef typename TreeTy::Factory FactoryTy;
private:
TreeTy *Root;
FactoryTy *Factory;
public:
/// Constructs a set from a pointer to a tree root. In general one
/// should use a Factory object to create sets instead of directly
@ -1133,44 +1132,44 @@ class ImmutableSetRef {
~ImmutableSetRef() {
if (Root) { Root->release(); }
}
static inline ImmutableSetRef getEmptySet(FactoryTy *F) {
return ImmutableSetRef(0, F);
}
ImmutableSetRef add(value_type_ref V) {
return ImmutableSetRef(Factory->add(Root, V), Factory);
}
ImmutableSetRef remove(value_type_ref V) {
return ImmutableSetRef(Factory->remove(Root, V), Factory);
}
/// Returns true if the set contains the specified value.
bool contains(value_type_ref V) const {
return Root ? Root->contains(V) : false;
}
ImmutableSet<ValT> asImmutableSet(bool canonicalize = true) const {
return ImmutableSet<ValT>(canonicalize ?
Factory->getCanonicalTree(Root) : Root);
}
TreeTy *getRootWithoutRetain() const {
return Root;
}
bool operator==(const ImmutableSetRef &RHS) const {
return Root && RHS.Root ? Root->isEqual(*RHS.Root) : Root == RHS.Root;
}
bool operator!=(const ImmutableSetRef &RHS) const {
return Root && RHS.Root ? Root->isNotEqual(*RHS.Root) : Root != RHS.Root;
}
/// isEmpty - Return true if the set contains no elements.
bool isEmpty() const { return !Root; }
/// isSingleton - Return true if the set contains exactly one element.
/// This method runs in constant time.
bool isSingleton() const { return getHeight() == 1; }
@ -1178,7 +1177,7 @@ class ImmutableSetRef {
//===--------------------------------------------------===//
// Iterators.
//===--------------------------------------------------===//
class iterator {
typename TreeTy::iterator itr;
iterator(TreeTy* t) : itr(t) {}
@ -1194,28 +1193,28 @@ class ImmutableSetRef {
inline bool operator!=(const iterator& RHS) const { return RHS.itr != itr; }
inline value_type *operator->() const { return &(operator*()); }
};
iterator begin() const { return iterator(Root); }
iterator end() const { return iterator(); }
//===--------------------------------------------------===//
// Utility methods.
//===--------------------------------------------------===//
unsigned getHeight() const { return Root ? Root->getHeight() : 0; }
static inline void Profile(FoldingSetNodeID& ID, const ImmutableSetRef& S) {
ID.AddPointer(S.Root);
}
inline void Profile(FoldingSetNodeID& ID) const {
return Profile(ID,*this);
}
//===--------------------------------------------------===//
// For testing.
//===--------------------------------------------------===//
void validateTree() const { if (Root) Root->validateTree(); }
};

View File

@ -0,0 +1,90 @@
//===- llvm/ADT/MapVector.h - Map with deterministic value order *- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements a map that provides insertion order iteration. The
// interface is purposefully minimal. The key is assumed to be cheap to copy
// and 2 copies are kept, one for indexing in a DenseMap, one for iteration in
// a std::vector.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ADT_MAPVECTOR_H
#define LLVM_ADT_MAPVECTOR_H
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include <vector>
namespace llvm {
/// This class implements a map that also provides access to all stored values
/// in a deterministic order. The values are kept in a std::vector and the
/// mapping is done with DenseMap from Keys to indexes in that vector.
template<typename KeyT, typename ValueT,
typename MapType = llvm::DenseMap<KeyT, unsigned>,
typename VectorType = std::vector<std::pair<KeyT, ValueT> > >
class MapVector {
typedef typename VectorType::size_type SizeType;
MapType Map;
VectorType Vector;
public:
typedef typename VectorType::iterator iterator;
typedef typename VectorType::const_iterator const_iterator;
SizeType size() const {
return Vector.size();
}
iterator begin() {
return Vector.begin();
}
const_iterator begin() const {
return Vector.begin();
}
iterator end() {
return Vector.end();
}
const_iterator end() const {
return Vector.end();
}
bool empty() const {
return Vector.empty();
}
void clear() {
Map.clear();
Vector.clear();
}
ValueT &operator[](const KeyT &Key) {
std::pair<KeyT, unsigned> Pair = std::make_pair(Key, 0);
std::pair<typename MapType::iterator, bool> Result = Map.insert(Pair);
unsigned &I = Result.first->second;
if (Result.second) {
Vector.push_back(std::make_pair(Key, ValueT()));
I = Vector.size() - 1;
}
return Vector[I].second;
}
unsigned count(const KeyT &Key) const {
typename MapType::const_iterator Pos = Map.find(Key);
return Pos == Map.end()? 0 : 1;
}
};
}
#endif

View File

@ -16,8 +16,13 @@
#ifndef LLVM_ADT_OPTIONAL
#define LLVM_ADT_OPTIONAL
#include "llvm/Support/Compiler.h"
#include <cassert>
#if LLVM_USE_RVALUE_REFERENCES
#include <utility>
#endif
namespace llvm {
template<typename T>
@ -28,6 +33,10 @@ class Optional {
explicit Optional() : x(), hasVal(false) {}
Optional(const T &y) : x(y), hasVal(true) {}
#if LLVM_USE_RVALUE_REFERENCES
Optional(T &&y) : x(std::forward<T>(y)), hasVal(true) {}
#endif
static inline Optional create(const T* y) {
return y ? Optional(*y) : Optional();
}

View File

@ -14,6 +14,7 @@
#ifndef LLVM_ADT_OWNING_PTR_H
#define LLVM_ADT_OWNING_PTR_H
#include "llvm/Support/Compiler.h"
#include <cassert>
#include <cstddef>
@ -25,12 +26,21 @@ namespace llvm {
/// pointee object can be taken away from OwningPtr by using the take method.
template<class T>
class OwningPtr {
OwningPtr(OwningPtr const &); // DO NOT IMPLEMENT
OwningPtr &operator=(OwningPtr const &); // DO NOT IMPLEMENT
OwningPtr(OwningPtr const &) LLVM_DELETED_FUNCTION;
OwningPtr &operator=(OwningPtr const &) LLVM_DELETED_FUNCTION;
T *Ptr;
public:
explicit OwningPtr(T *P = 0) : Ptr(P) {}
#if LLVM_USE_RVALUE_REFERENCES
OwningPtr(OwningPtr &&Other) : Ptr(Other.take()) {}
OwningPtr &operator=(OwningPtr &&Other) {
reset(Other.take());
return *this;
}
#endif
~OwningPtr() {
delete Ptr;
}
@ -79,12 +89,21 @@ inline void swap(OwningPtr<T> &a, OwningPtr<T> &b) {
/// functionality as OwningPtr, except that it works for array types.
template<class T>
class OwningArrayPtr {
OwningArrayPtr(OwningArrayPtr const &); // DO NOT IMPLEMENT
OwningArrayPtr &operator=(OwningArrayPtr const &); // DO NOT IMPLEMENT
OwningArrayPtr(OwningArrayPtr const &) LLVM_DELETED_FUNCTION;
OwningArrayPtr &operator=(OwningArrayPtr const &) LLVM_DELETED_FUNCTION;
T *Ptr;
public:
explicit OwningArrayPtr(T *P = 0) : Ptr(P) {}
#if LLVM_USE_RVALUE_REFERENCES
OwningArrayPtr(OwningArrayPtr &&Other) : Ptr(Other.take()) {}
OwningArrayPtr &operator=(OwningArrayPtr &&Other) {
reset(Other.take());
return *this;
}
#endif
~OwningArrayPtr() {
delete [] Ptr;
}

View File

@ -19,32 +19,32 @@
namespace llvm {
template <typename T, unsigned BitNum, bool isSigned>
template <typename T, unsigned BitNum, typename BitVectorTy, bool isSigned>
class PackedVectorBase;
// This won't be necessary if we can specialize members without specializing
// the parent template.
template <typename T, unsigned BitNum>
class PackedVectorBase<T, BitNum, false> {
template <typename T, unsigned BitNum, typename BitVectorTy>
class PackedVectorBase<T, BitNum, BitVectorTy, false> {
protected:
static T getValue(const llvm::BitVector &Bits, unsigned Idx) {
static T getValue(const BitVectorTy &Bits, unsigned Idx) {
T val = T();
for (unsigned i = 0; i != BitNum; ++i)
val = T(val | ((Bits[(Idx << (BitNum-1)) + i] ? 1UL : 0UL) << i));
return val;
}
static void setValue(llvm::BitVector &Bits, unsigned Idx, T val) {
static void setValue(BitVectorTy &Bits, unsigned Idx, T val) {
assert((val >> BitNum) == 0 && "value is too big");
for (unsigned i = 0; i != BitNum; ++i)
Bits[(Idx << (BitNum-1)) + i] = val & (T(1) << i);
}
};
template <typename T, unsigned BitNum>
class PackedVectorBase<T, BitNum, true> {
template <typename T, unsigned BitNum, typename BitVectorTy>
class PackedVectorBase<T, BitNum, BitVectorTy, true> {
protected:
static T getValue(const llvm::BitVector &Bits, unsigned Idx) {
static T getValue(const BitVectorTy &Bits, unsigned Idx) {
T val = T();
for (unsigned i = 0; i != BitNum-1; ++i)
val = T(val | ((Bits[(Idx << (BitNum-1)) + i] ? 1UL : 0UL) << i));
@ -53,7 +53,7 @@ class PackedVectorBase<T, BitNum, true> {
return val;
}
static void setValue(llvm::BitVector &Bits, unsigned Idx, T val) {
static void setValue(BitVectorTy &Bits, unsigned Idx, T val) {
if (val < 0) {
val = ~val;
Bits.set((Idx << (BitNum-1)) + BitNum-1);
@ -71,11 +71,12 @@ class PackedVectorBase<T, BitNum, true> {
/// @endcode
/// will create a vector accepting values -2, -1, 0, 1. Any other value will hit
/// an assertion.
template <typename T, unsigned BitNum>
class PackedVector : public PackedVectorBase<T, BitNum,
template <typename T, unsigned BitNum, typename BitVectorTy = BitVector>
class PackedVector : public PackedVectorBase<T, BitNum, BitVectorTy,
std::numeric_limits<T>::is_signed> {
llvm::BitVector Bits;
typedef PackedVectorBase<T, BitNum, std::numeric_limits<T>::is_signed> base;
BitVectorTy Bits;
typedef PackedVectorBase<T, BitNum, BitVectorTy,
std::numeric_limits<T>::is_signed> base;
public:
class reference {

View File

@ -135,12 +135,12 @@ template<typename PointerTy, unsigned IntBits, typename IntType>
struct DenseMapInfo<PointerIntPair<PointerTy, IntBits, IntType> > {
typedef PointerIntPair<PointerTy, IntBits, IntType> Ty;
static Ty getEmptyKey() {
intptr_t Val = -1;
uintptr_t Val = static_cast<uintptr_t>(-1);
Val <<= PointerLikeTypeTraits<PointerTy>::NumLowBitsAvailable;
return Ty(reinterpret_cast<PointerTy>(Val), IntType((1 << IntBits)-1));
}
static Ty getTombstoneKey() {
intptr_t Val = -2;
uintptr_t Val = static_cast<uintptr_t>(-2);
Val <<= PointerLikeTypeTraits<PointerTy>::NumLowBitsAvailable;
return Ty(reinterpret_cast<PointerTy>(Val), IntType(0));
}

View File

@ -90,8 +90,8 @@ class ScopedHashTableScope {
/// LastValInScope - This is the last value that was inserted for this scope
/// or null if none have been inserted yet.
ScopedHashTableVal<K, V> *LastValInScope;
void operator=(ScopedHashTableScope&); // DO NOT IMPLEMENT
ScopedHashTableScope(ScopedHashTableScope&); // DO NOT IMPLEMENT
void operator=(ScopedHashTableScope&) LLVM_DELETED_FUNCTION;
ScopedHashTableScope(ScopedHashTableScope&) LLVM_DELETED_FUNCTION;
public:
ScopedHashTableScope(ScopedHashTable<K, V, KInfo, AllocatorTy> &HT);
~ScopedHashTableScope();

View File

@ -27,10 +27,11 @@
namespace llvm {
/// \brief A vector that has set insertion semantics.
///
/// This adapter class provides a way to keep a set of things that also has the
/// property of a deterministic iteration order. The order of iteration is the
/// order of insertion.
/// @brief A vector that has set insertion semantics.
template <typename T, typename Vector = std::vector<T>,
typename Set = SmallSet<T, 16> >
class SetVector {
@ -45,59 +46,59 @@ class SetVector {
typedef typename vector_type::const_iterator const_iterator;
typedef typename vector_type::size_type size_type;
/// @brief Construct an empty SetVector
/// \brief Construct an empty SetVector
SetVector() {}
/// @brief Initialize a SetVector with a range of elements
/// \brief Initialize a SetVector with a range of elements
template<typename It>
SetVector(It Start, It End) {
insert(Start, End);
}
/// @brief Determine if the SetVector is empty or not.
/// \brief Determine if the SetVector is empty or not.
bool empty() const {
return vector_.empty();
}
/// @brief Determine the number of elements in the SetVector.
/// \brief Determine the number of elements in the SetVector.
size_type size() const {
return vector_.size();
}
/// @brief Get an iterator to the beginning of the SetVector.
/// \brief Get an iterator to the beginning of the SetVector.
iterator begin() {
return vector_.begin();
}
/// @brief Get a const_iterator to the beginning of the SetVector.
/// \brief Get a const_iterator to the beginning of the SetVector.
const_iterator begin() const {
return vector_.begin();
}
/// @brief Get an iterator to the end of the SetVector.
/// \brief Get an iterator to the end of the SetVector.
iterator end() {
return vector_.end();
}
/// @brief Get a const_iterator to the end of the SetVector.
/// \brief Get a const_iterator to the end of the SetVector.
const_iterator end() const {
return vector_.end();
}
/// @brief Return the last element of the SetVector.
/// \brief Return the last element of the SetVector.
const T &back() const {
assert(!empty() && "Cannot call back() on empty SetVector!");
return vector_.back();
}
/// @brief Index into the SetVector.
/// \brief Index into the SetVector.
const_reference operator[](size_type n) const {
assert(n < vector_.size() && "SetVector access out of range!");
return vector_[n];
}
/// @returns true iff the element was inserted into the SetVector.
/// @brief Insert a new element into the SetVector.
/// \brief Insert a new element into the SetVector.
/// \returns true iff the element was inserted into the SetVector.
bool insert(const value_type &X) {
bool result = set_.insert(X);
if (result)
@ -105,7 +106,7 @@ class SetVector {
return result;
}
/// @brief Insert a range of elements into the SetVector.
/// \brief Insert a range of elements into the SetVector.
template<typename It>
void insert(It Start, It End) {
for (; Start != End; ++Start)
@ -113,7 +114,7 @@ class SetVector {
vector_.push_back(*Start);
}
/// @brief Remove an item from the set vector.
/// \brief Remove an item from the set vector.
bool remove(const value_type& X) {
if (set_.erase(X)) {
typename vector_type::iterator I =
@ -125,20 +126,44 @@ class SetVector {
return false;
}
/// \brief Remove items from the set vector based on a predicate function.
///
/// This is intended to be equivalent to the following code, if we could
/// write it:
///
/// \code
/// V.erase(std::remove_if(V.begin(), V.end(), P), V.end());
/// \endcode
///
/// However, SetVector doesn't expose non-const iterators, making any
/// algorithm like remove_if impossible to use.
///
/// \returns true if any element is removed.
template <typename UnaryPredicate>
bool remove_if(UnaryPredicate P) {
typename vector_type::iterator I
= std::remove_if(vector_.begin(), vector_.end(),
TestAndEraseFromSet<UnaryPredicate>(P, set_));
if (I == vector_.end())
return false;
vector_.erase(I, vector_.end());
return true;
}
/// @returns 0 if the element is not in the SetVector, 1 if it is.
/// @brief Count the number of elements of a given key in the SetVector.
/// \brief Count the number of elements of a given key in the SetVector.
/// \returns 0 if the element is not in the SetVector, 1 if it is.
size_type count(const key_type &key) const {
return set_.count(key);
}
/// @brief Completely clear the SetVector
/// \brief Completely clear the SetVector
void clear() {
set_.clear();
vector_.clear();
}
/// @brief Remove the last element of the SetVector.
/// \brief Remove the last element of the SetVector.
void pop_back() {
assert(!empty() && "Cannot remove an element from an empty SetVector!");
set_.erase(back());
@ -160,18 +185,41 @@ class SetVector {
}
private:
/// \brief A wrapper predicate designed for use with std::remove_if.
///
/// This predicate wraps a predicate suitable for use with std::remove_if to
/// call set_.erase(x) on each element which is slated for removal.
template <typename UnaryPredicate>
class TestAndEraseFromSet {
UnaryPredicate P;
set_type &set_;
public:
typedef typename UnaryPredicate::argument_type argument_type;
TestAndEraseFromSet(UnaryPredicate P, set_type &set_) : P(P), set_(set_) {}
bool operator()(argument_type Arg) {
if (P(Arg)) {
set_.erase(Arg);
return true;
}
return false;
}
};
set_type set_; ///< The set.
vector_type vector_; ///< The vector.
};
/// SmallSetVector - A SetVector that performs no allocations if smaller than
/// \brief A SetVector that performs no allocations if smaller than
/// a certain size.
template <typename T, unsigned N>
class SmallSetVector : public SetVector<T, SmallVector<T, N>, SmallSet<T, N> > {
public:
SmallSetVector() {}
/// @brief Initialize a SmallSetVector with a range of elements
/// \brief Initialize a SmallSetVector with a range of elements
template<typename It>
SmallSetVector(It Start, It End) {
this->insert(Start, End);

View File

@ -300,6 +300,21 @@ class SmallBitVector {
return *this;
}
/// set - Efficiently set a range of bits in [I, E)
SmallBitVector &set(unsigned I, unsigned E) {
assert(I <= E && "Attempted to set backwards range!");
assert(E <= size() && "Attempted to set out-of-bounds range!");
if (I == E) return *this;
if (isSmall()) {
uintptr_t EMask = ((uintptr_t)1) << E;
uintptr_t IMask = ((uintptr_t)1) << I;
uintptr_t Mask = EMask - IMask;
setSmallBits(getSmallBits() | Mask);
} else
getPointer()->set(I, E);
return *this;
}
SmallBitVector &reset() {
if (isSmall())
setSmallBits(0);
@ -316,6 +331,21 @@ class SmallBitVector {
return *this;
}
/// reset - Efficiently reset a range of bits in [I, E)
SmallBitVector &reset(unsigned I, unsigned E) {
assert(I <= E && "Attempted to reset backwards range!");
assert(E <= size() && "Attempted to reset out-of-bounds range!");
if (I == E) return *this;
if (isSmall()) {
uintptr_t EMask = ((uintptr_t)1) << E;
uintptr_t IMask = ((uintptr_t)1) << I;
uintptr_t Mask = EMask - IMask;
setSmallBits(getSmallBits() & ~Mask);
} else
getPointer()->reset(I, E);
return *this;
}
SmallBitVector &flip() {
if (isSmall())
setSmallBits(~getSmallBits());

View File

@ -15,12 +15,13 @@
#ifndef LLVM_ADT_SMALLPTRSET_H
#define LLVM_ADT_SMALLPTRSET_H
#include "llvm/Support/Compiler.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/PointerLikeTypeTraits.h"
#include <cassert>
#include <cstddef>
#include <cstring>
#include <iterator>
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/PointerLikeTypeTraits.h"
namespace llvm {
@ -132,7 +133,7 @@ class SmallPtrSetImpl {
/// Grow - Allocate a larger backing store for the buckets and move it over.
void Grow(unsigned NewSize);
void operator=(const SmallPtrSetImpl &RHS); // DO NOT IMPLEMENT.
void operator=(const SmallPtrSetImpl &RHS) LLVM_DELETED_FUNCTION;
protected:
/// swap - Swaps the elements of two sets.
/// Note: This method assumes that both sets have the same small size.

View File

@ -44,25 +44,25 @@ class SmallString : public SmallVector<char, InternalLen> {
/// @name String Assignment
/// @{
/// Assign from a repeated element
/// Assign from a repeated element.
void assign(size_t NumElts, char Elt) {
this->SmallVectorImpl<char>::assign(NumElts, Elt);
}
/// Assign from an iterator pair
/// Assign from an iterator pair.
template<typename in_iter>
void assign(in_iter S, in_iter E) {
this->clear();
SmallVectorImpl<char>::append(S, E);
}
/// Assign from a StringRef
/// Assign from a StringRef.
void assign(StringRef RHS) {
this->clear();
SmallVectorImpl<char>::append(RHS.begin(), RHS.end());
}
/// Assign from a SmallVector
/// Assign from a SmallVector.
void assign(const SmallVectorImpl<char> &RHS) {
this->clear();
SmallVectorImpl<char>::append(RHS.begin(), RHS.end());
@ -72,7 +72,7 @@ class SmallString : public SmallVector<char, InternalLen> {
/// @name String Concatenation
/// @{
/// Append from an iterator pair
/// Append from an iterator pair.
template<typename in_iter>
void append(in_iter S, in_iter E) {
SmallVectorImpl<char>::append(S, E);
@ -83,12 +83,12 @@ class SmallString : public SmallVector<char, InternalLen> {
}
/// Append from a StringRef
/// Append from a StringRef.
void append(StringRef RHS) {
SmallVectorImpl<char>::append(RHS.begin(), RHS.end());
}
/// Append from a SmallVector
/// Append from a SmallVector.
void append(const SmallVectorImpl<char> &RHS) {
SmallVectorImpl<char>::append(RHS.begin(), RHS.end());
}
@ -97,19 +97,19 @@ class SmallString : public SmallVector<char, InternalLen> {
/// @name String Comparison
/// @{
/// equals - Check for string equality, this is more efficient than
/// compare() when the relative ordering of inequal strings isn't needed.
/// Check for string equality. This is more efficient than compare() when
/// the relative ordering of inequal strings isn't needed.
bool equals(StringRef RHS) const {
return str().equals(RHS);
}
/// equals_lower - Check for string equality, ignoring case.
/// Check for string equality, ignoring case.
bool equals_lower(StringRef RHS) const {
return str().equals_lower(RHS);
}
/// compare - Compare two strings; the result is -1, 0, or 1 if this string
/// is lexicographically less than, equal to, or greater than the \arg RHS.
/// Compare two strings; the result is -1, 0, or 1 if this string is
/// lexicographically less than, equal to, or greater than the \p RHS.
int compare(StringRef RHS) const {
return str().compare(RHS);
}
@ -129,12 +129,12 @@ class SmallString : public SmallVector<char, InternalLen> {
/// @name String Predicates
/// @{
/// startswith - Check if this string starts with the given \arg Prefix.
/// startswith - Check if this string starts with the given \p Prefix.
bool startswith(StringRef Prefix) const {
return str().startswith(Prefix);
}
/// endswith - Check if this string ends with the given \arg Suffix.
/// endswith - Check if this string ends with the given \p Suffix.
bool endswith(StringRef Suffix) const {
return str().endswith(Suffix);
}
@ -143,76 +143,76 @@ class SmallString : public SmallVector<char, InternalLen> {
/// @name String Searching
/// @{
/// find - Search for the first character \arg C in the string.
/// find - Search for the first character \p C in the string.
///
/// \return - The index of the first occurrence of \arg C, or npos if not
/// \return - The index of the first occurrence of \p C, or npos if not
/// found.
size_t find(char C, size_t From = 0) const {
return str().find(C, From);
}
/// find - Search for the first string \arg Str in the string.
/// Search for the first string \p Str in the string.
///
/// \return - The index of the first occurrence of \arg Str, or npos if not
/// \returns The index of the first occurrence of \p Str, or npos if not
/// found.
size_t find(StringRef Str, size_t From = 0) const {
return str().find(Str, From);
}
/// rfind - Search for the last character \arg C in the string.
/// Search for the last character \p C in the string.
///
/// \return - The index of the last occurrence of \arg C, or npos if not
/// \returns The index of the last occurrence of \p C, or npos if not
/// found.
size_t rfind(char C, size_t From = StringRef::npos) const {
return str().rfind(C, From);
}
/// rfind - Search for the last string \arg Str in the string.
/// Search for the last string \p Str in the string.
///
/// \return - The index of the last occurrence of \arg Str, or npos if not
/// \returns The index of the last occurrence of \p Str, or npos if not
/// found.
size_t rfind(StringRef Str) const {
return str().rfind(Str);
}
/// find_first_of - Find the first character in the string that is \arg C,
/// or npos if not found. Same as find.
/// Find the first character in the string that is \p C, or npos if not
/// found. Same as find.
size_t find_first_of(char C, size_t From = 0) const {
return str().find_first_of(C, From);
}
/// find_first_of - Find the first character in the string that is in \arg
/// Chars, or npos if not found.
/// Find the first character in the string that is in \p Chars, or npos if
/// not found.
///
/// Note: O(size() + Chars.size())
/// Complexity: O(size() + Chars.size())
size_t find_first_of(StringRef Chars, size_t From = 0) const {
return str().find_first_of(Chars, From);
}
/// find_first_not_of - Find the first character in the string that is not
/// \arg C or npos if not found.
/// Find the first character in the string that is not \p C or npos if not
/// found.
size_t find_first_not_of(char C, size_t From = 0) const {
return str().find_first_not_of(C, From);
}
/// find_first_not_of - Find the first character in the string that is not
/// in the string \arg Chars, or npos if not found.
/// Find the first character in the string that is not in the string
/// \p Chars, or npos if not found.
///
/// Note: O(size() + Chars.size())
/// Complexity: O(size() + Chars.size())
size_t find_first_not_of(StringRef Chars, size_t From = 0) const {
return str().find_first_not_of(Chars, From);
}
/// find_last_of - Find the last character in the string that is \arg C, or
/// npos if not found.
/// Find the last character in the string that is \p C, or npos if not
/// found.
size_t find_last_of(char C, size_t From = StringRef::npos) const {
return str().find_last_of(C, From);
}
/// find_last_of - Find the last character in the string that is in \arg C,
/// or npos if not found.
/// Find the last character in the string that is in \p C, or npos if not
/// found.
///
/// Note: O(size() + Chars.size())
/// Complexity: O(size() + Chars.size())
size_t find_last_of(
StringRef Chars, size_t From = StringRef::npos) const {
return str().find_last_of(Chars, From);
@ -222,13 +222,13 @@ class SmallString : public SmallVector<char, InternalLen> {
/// @name Helpful Algorithms
/// @{
/// count - Return the number of occurrences of \arg C in the string.
/// Return the number of occurrences of \p C in the string.
size_t count(char C) const {
return str().count(C);
}
/// count - Return the number of non-overlapped occurrences of \arg Str in
/// the string.
/// Return the number of non-overlapped occurrences of \p Str in the
/// string.
size_t count(StringRef Str) const {
return str().count(Str);
}
@ -237,36 +237,36 @@ class SmallString : public SmallVector<char, InternalLen> {
/// @name Substring Operations
/// @{
/// substr - Return a reference to the substring from [Start, Start + N).
/// Return a reference to the substring from [Start, Start + N).
///
/// \param Start - The index of the starting character in the substring; if
/// \param Start The index of the starting character in the substring; if
/// the index is npos or greater than the length of the string then the
/// empty substring will be returned.
///
/// \param N - The number of characters to included in the substring. If N
/// \param N The number of characters to included in the substring. If \p N
/// exceeds the number of characters remaining in the string, the string
/// suffix (starting with \arg Start) will be returned.
/// suffix (starting with \p Start) will be returned.
StringRef substr(size_t Start, size_t N = StringRef::npos) const {
return str().substr(Start, N);
}
/// slice - Return a reference to the substring from [Start, End).
/// Return a reference to the substring from [Start, End).
///
/// \param Start - The index of the starting character in the substring; if
/// \param Start The index of the starting character in the substring; if
/// the index is npos or greater than the length of the string then the
/// empty substring will be returned.
///
/// \param End - The index following the last character to include in the
/// substring. If this is npos, or less than \arg Start, or exceeds the
/// \param End The index following the last character to include in the
/// substring. If this is npos, or less than \p Start, or exceeds the
/// number of characters remaining in the string, the string suffix
/// (starting with \arg Start) will be returned.
/// (starting with \p Start) will be returned.
StringRef slice(size_t Start, size_t End) const {
return str().slice(Start, End);
}
// Extra methods.
/// Explicit conversion to StringRef
/// Explicit conversion to StringRef.
StringRef str() const { return StringRef(this->begin(), this->size()); }
// TODO: Make this const, if it's safe...

View File

@ -14,6 +14,7 @@
#ifndef LLVM_ADT_SMALLVECTOR_H
#define LLVM_ADT_SMALLVECTOR_H
#include "llvm/Support/AlignOf.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/type_traits.h"
#include <algorithm>
@ -32,22 +33,52 @@ class SmallVectorBase {
protected:
void *BeginX, *EndX, *CapacityX;
protected:
SmallVectorBase(void *FirstEl, size_t Size)
: BeginX(FirstEl), EndX(FirstEl), CapacityX((char*)FirstEl+Size) {}
/// grow_pod - This is an implementation of the grow() method which only works
/// on POD-like data types and is out of line to reduce code duplication.
void grow_pod(void *FirstEl, size_t MinSizeInBytes, size_t TSize);
public:
/// size_in_bytes - This returns size()*sizeof(T).
size_t size_in_bytes() const {
return size_t((char*)EndX - (char*)BeginX);
}
/// capacity_in_bytes - This returns capacity()*sizeof(T).
size_t capacity_in_bytes() const {
return size_t((char*)CapacityX - (char*)BeginX);
}
bool empty() const { return BeginX == EndX; }
};
template <typename T, unsigned N> struct SmallVectorStorage;
/// SmallVectorTemplateCommon - This is the part of SmallVectorTemplateBase
/// which does not depend on whether the type T is a POD. The extra dummy
/// template argument is used by ArrayRef to avoid unnecessarily requiring T
/// to be complete.
template <typename T, typename = void>
class SmallVectorTemplateCommon : public SmallVectorBase {
private:
template <typename, unsigned> friend struct SmallVectorStorage;
// Allocate raw space for N elements of type T. If T has a ctor or dtor, we
// don't want it to be automatically run, so we need to represent the space as
// something else. An array of char would work great, but might not be
// aligned sufficiently. Instead we use some number of union instances for
// the space, which guarantee maximal alignment.
union U {
double D;
long double LD;
long long L;
void *P;
} FirstEl;
// something else. Use an array of char of sufficient alignment.
typedef llvm::AlignedCharArrayUnion<T> U;
U FirstEl;
// Space after 'FirstEl' is clobbered, do not add any instance vars after it.
protected:
SmallVectorBase(size_t Size)
: BeginX(&FirstEl), EndX(&FirstEl), CapacityX((char*)&FirstEl+Size) {}
SmallVectorTemplateCommon(size_t Size) : SmallVectorBase(&FirstEl, Size) {}
void grow_pod(size_t MinSizeInBytes, size_t TSize) {
SmallVectorBase::grow_pod(&FirstEl, MinSizeInBytes, TSize);
}
/// isSmall - Return true if this is a smallvector which has not had dynamic
/// memory allocated for it.
@ -60,30 +91,6 @@ class SmallVectorBase {
BeginX = EndX = CapacityX = &FirstEl;
}
/// grow_pod - This is an implementation of the grow() method which only works
/// on POD-like data types and is out of line to reduce code duplication.
void grow_pod(size_t MinSizeInBytes, size_t TSize);
public:
/// size_in_bytes - This returns size()*sizeof(T).
size_t size_in_bytes() const {
return size_t((char*)EndX - (char*)BeginX);
}
/// capacity_in_bytes - This returns capacity()*sizeof(T).
size_t capacity_in_bytes() const {
return size_t((char*)CapacityX - (char*)BeginX);
}
bool empty() const { return BeginX == EndX; }
};
template <typename T>
class SmallVectorTemplateCommon : public SmallVectorBase {
protected:
SmallVectorTemplateCommon(size_t Size) : SmallVectorBase(Size) {}
void setEnd(T *P) { this->EndX = P; }
public:
typedef size_t size_type;
@ -677,8 +684,8 @@ class SmallVectorImpl : public SmallVectorTemplateBase<T, isPodLike<T>::value> {
RHS.begin(), RHS.end());
}
/// set_size - Set the array size to \arg N, which the current array must have
/// enough capacity for.
/// Set the array size to \p N, which the current array must have enough
/// capacity for.
///
/// This does not construct or destroy any elements in the vector.
///
@ -844,6 +851,17 @@ SmallVectorImpl<T> &SmallVectorImpl<T>::operator=(SmallVectorImpl<T> &&RHS) {
}
#endif
/// Storage for the SmallVector elements which aren't contained in
/// SmallVectorTemplateCommon. There are 'N-1' elements here. The remaining '1'
/// element is in the base class. This is specialized for the N=1 and N=0 cases
/// to avoid allocating unnecessary storage.
template <typename T, unsigned N>
struct SmallVectorStorage {
typename SmallVectorTemplateCommon<T>::U InlineElts[N - 1];
};
template <typename T> struct SmallVectorStorage<T, 1> {};
template <typename T> struct SmallVectorStorage<T, 0> {};
/// SmallVector - This is a 'vector' (really, a variable-sized array), optimized
/// for the case when the array is small. It contains some number of elements
/// in-place, which allows it to avoid heap allocation when the actual number of
@ -854,41 +872,23 @@ SmallVectorImpl<T> &SmallVectorImpl<T>::operator=(SmallVectorImpl<T> &&RHS) {
///
template <typename T, unsigned N>
class SmallVector : public SmallVectorImpl<T> {
/// InlineElts - These are 'N-1' elements that are stored inline in the body
/// of the vector. The extra '1' element is stored in SmallVectorImpl.
typedef typename SmallVectorImpl<T>::U U;
enum {
// MinUs - The number of U's require to cover N T's.
MinUs = (static_cast<unsigned int>(sizeof(T))*N +
static_cast<unsigned int>(sizeof(U)) - 1) /
static_cast<unsigned int>(sizeof(U)),
// NumInlineEltsElts - The number of elements actually in this array. There
// is already one in the parent class, and we have to round up to avoid
// having a zero-element array.
NumInlineEltsElts = MinUs > 1 ? (MinUs - 1) : 1,
// NumTsAvailable - The number of T's we actually have space for, which may
// be more than N due to rounding.
NumTsAvailable = (NumInlineEltsElts+1)*static_cast<unsigned int>(sizeof(U))/
static_cast<unsigned int>(sizeof(T))
};
U InlineElts[NumInlineEltsElts];
/// Storage - Inline space for elements which aren't stored in the base class.
SmallVectorStorage<T, N> Storage;
public:
SmallVector() : SmallVectorImpl<T>(NumTsAvailable) {
SmallVector() : SmallVectorImpl<T>(N) {
}
explicit SmallVector(unsigned Size, const T &Value = T())
: SmallVectorImpl<T>(NumTsAvailable) {
: SmallVectorImpl<T>(N) {
this->assign(Size, Value);
}
template<typename ItTy>
SmallVector(ItTy S, ItTy E) : SmallVectorImpl<T>(NumTsAvailable) {
SmallVector(ItTy S, ItTy E) : SmallVectorImpl<T>(N) {
this->append(S, E);
}
SmallVector(const SmallVector &RHS) : SmallVectorImpl<T>(NumTsAvailable) {
SmallVector(const SmallVector &RHS) : SmallVectorImpl<T>(N) {
if (!RHS.empty())
SmallVectorImpl<T>::operator=(RHS);
}
@ -899,7 +899,7 @@ class SmallVector : public SmallVectorImpl<T> {
}
#if LLVM_USE_RVALUE_REFERENCES
SmallVector(SmallVector &&RHS) : SmallVectorImpl<T>(NumTsAvailable) {
SmallVector(SmallVector &&RHS) : SmallVectorImpl<T>(N) {
if (!RHS.empty())
SmallVectorImpl<T>::operator=(::std::move(RHS));
}
@ -912,48 +912,6 @@ 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->assign(Size, Value);
}
template<typename ItTy>
SmallVector(ItTy S, ItTy E) : SmallVectorImpl<T>(0) {
this->append(S, E);
}
SmallVector(const SmallVector &RHS) : SmallVectorImpl<T>(0) {
if (!RHS.empty())
SmallVectorImpl<T>::operator=(RHS);
}
const SmallVector &operator=(const SmallVector &RHS) {
SmallVectorImpl<T>::operator=(RHS);
return *this;
}
#if LLVM_USE_RVALUE_REFERENCES
SmallVector(SmallVector &&RHS) : SmallVectorImpl<T>(0) {
if (!RHS.empty())
SmallVectorImpl<T>::operator=(::std::move(RHS));
}
const SmallVector &operator=(SmallVector &&RHS) {
SmallVectorImpl<T>::operator=(::std::move(RHS));
return *this;
}
#endif
};
template<typename T, unsigned N>
static inline size_t capacity_in_bytes(const SmallVector<T, N> &X) {
return X.capacity_in_bytes();

View File

@ -158,7 +158,7 @@ struct SparseBitVectorElement
&& "Word Position outside of element");
// Mask off previous bits.
Copy &= ~0L << BitPos;
Copy &= ~0UL << BitPos;
if (Copy != 0) {
if (sizeof(BitWord) == 4)
@ -262,6 +262,22 @@ struct SparseBitVectorElement
}
};
template <unsigned ElementSize>
struct ilist_traits<SparseBitVectorElement<ElementSize> >
: public ilist_default_traits<SparseBitVectorElement<ElementSize> > {
typedef SparseBitVectorElement<ElementSize> Element;
Element *createSentinel() const { return static_cast<Element *>(&Sentinel); }
static void destroySentinel(Element *) {}
Element *provideInitialHead() const { return createSentinel(); }
Element *ensureHead(Element *) const { return createSentinel(); }
static void noteHead(Element *, Element *) {}
private:
mutable ilist_half_node<Element> Sentinel;
};
template <unsigned ElementSize = 128>
class SparseBitVector {
typedef ilist<SparseBitVectorElement<ElementSize> > ElementList;

View File

@ -110,9 +110,9 @@ struct SparseSetValFunctor<KeyT, KeyT, KeyFunctorT> {
/// For sets that may grow to thousands of elements, SparseT should be set to
/// uint16_t or uint32_t.
///
/// @param ValueT The type of objects in the set.
/// @param KeyFunctorT A functor that computes an unsigned index from KeyT.
/// @param SparseT An unsigned integer type. See above.
/// @tparam ValueT The type of objects in the set.
/// @tparam KeyFunctorT A functor that computes an unsigned index from KeyT.
/// @tparam SparseT An unsigned integer type. See above.
///
template<typename ValueT,
typename KeyFunctorT = llvm::identity<unsigned>,
@ -128,8 +128,8 @@ class SparseSet {
// Disable copy construction and assignment.
// This data structure is not meant to be used that way.
SparseSet(const SparseSet&); // DO NOT IMPLEMENT.
SparseSet &operator=(const SparseSet&); // DO NOT IMPLEMENT.
SparseSet(const SparseSet&) LLVM_DELETED_FUNCTION;
SparseSet &operator=(const SparseSet&) LLVM_DELETED_FUNCTION;
public:
typedef ValueT value_type;

View File

@ -21,7 +21,7 @@ namespace llvm {
template<typename T> class SmallVectorImpl;
/// hexdigit - Return the hexadecimal character for the
/// given number \arg X (which should be less than 16).
/// given number \p X (which should be less than 16).
static inline char hexdigit(unsigned X, bool LowerCase = false) {
const char HexChar = LowerCase ? 'a' : 'A';
return X < 10 ? '0' + X : HexChar + X - 10;
@ -125,10 +125,29 @@ void SplitString(StringRef Source,
// X*33+c -> X*33^c
static inline unsigned HashString(StringRef Str, unsigned Result = 0) {
for (unsigned i = 0, e = Str.size(); i != e; ++i)
Result = Result * 33 + Str[i];
Result = Result * 33 + (unsigned char)Str[i];
return Result;
}
/// Returns the English suffix for an ordinal integer (-st, -nd, -rd, -th).
static inline StringRef getOrdinalSuffix(unsigned Val) {
// It is critically important that we do this perfectly for
// user-written sequences with over 100 elements.
switch (Val % 100) {
case 11:
case 12:
case 13:
return "th";
default:
switch (Val % 10) {
case 1: return "st";
case 2: return "nd";
case 3: return "rd";
default: return "th";
}
}
}
} // End llvm namespace
#endif

View File

@ -138,7 +138,7 @@ namespace llvm {
}
/// compare - Compare two strings; the result is -1, 0, or 1 if this string
/// is lexicographically less than, equal to, or greater than the \arg RHS.
/// is lexicographically less than, equal to, or greater than the \p RHS.
int compare(StringRef RHS) const {
// Check the prefix for a mismatch.
if (int Res = compareMemory(Data, RHS.Data, min(Length, RHS.Length)))
@ -205,13 +205,13 @@ namespace llvm {
/// @name String Predicates
/// @{
/// startswith - Check if this string starts with the given \arg Prefix.
/// Check if this string starts with the given \p Prefix.
bool startswith(StringRef Prefix) const {
return Length >= Prefix.Length &&
compareMemory(Data, Prefix.Data, Prefix.Length) == 0;
}
/// endswith - Check if this string ends with the given \arg Suffix.
/// Check if this string ends with the given \p Suffix.
bool endswith(StringRef Suffix) const {
return Length >= Suffix.Length &&
compareMemory(end() - Suffix.Length, Suffix.Data, Suffix.Length) == 0;
@ -221,9 +221,9 @@ namespace llvm {
/// @name String Searching
/// @{
/// find - Search for the first character \arg C in the string.
/// Search for the first character \p C in the string.
///
/// \return - The index of the first occurrence of \arg C, or npos if not
/// \returns The index of the first occurrence of \p C, or npos if not
/// found.
size_t find(char C, size_t From = 0) const {
for (size_t i = min(From, Length), e = Length; i != e; ++i)
@ -232,15 +232,15 @@ namespace llvm {
return npos;
}
/// find - Search for the first string \arg Str in the string.
/// Search for the first string \p Str in the string.
///
/// \return - The index of the first occurrence of \arg Str, or npos if not
/// \returns The index of the first occurrence of \p Str, or npos if not
/// found.
size_t find(StringRef Str, size_t From = 0) const;
/// rfind - Search for the last character \arg C in the string.
/// Search for the last character \p C in the string.
///
/// \return - The index of the last occurrence of \arg C, or npos if not
/// \returns The index of the last occurrence of \p C, or npos if not
/// found.
size_t rfind(char C, size_t From = npos) const {
From = min(From, Length);
@ -253,61 +253,61 @@ namespace llvm {
return npos;
}
/// rfind - Search for the last string \arg Str in the string.
/// Search for the last string \p Str in the string.
///
/// \return - The index of the last occurrence of \arg Str, or npos if not
/// \returns The index of the last occurrence of \p Str, or npos if not
/// found.
size_t rfind(StringRef Str) const;
/// find_first_of - Find the first character in the string that is \arg C,
/// or npos if not found. Same as find.
/// Find the first character in the string that is \p C, or npos if not
/// found. Same as find.
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.
/// Find the first character in the string that is in \p Chars, or npos if
/// not found.
///
/// Note: O(size() + Chars.size())
/// Complexity: 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
/// \arg C or npos if not found.
/// Find the first character in the string that is not \p C or npos if not
/// found.
size_type find_first_not_of(char C, size_t From = 0) const;
/// find_first_not_of - Find the first character in the string that is not
/// in the string \arg Chars, or npos if not found.
/// Find the first character in the string that is not in the string
/// \p Chars, or npos if not found.
///
/// Note: O(size() + Chars.size())
/// Complexity: O(size() + Chars.size())
size_type find_first_not_of(StringRef Chars, size_t From = 0) const;
/// find_last_of - Find the last character in the string that is \arg C, or
/// npos if not found.
/// Find the last character in the string that is \p C, or npos if not
/// found.
size_type find_last_of(char C, size_t From = npos) const {
return rfind(C, From);
}
/// find_last_of - Find the last character in the string that is in \arg C,
/// or npos if not found.
/// Find the last character in the string that is in \p C, or npos if not
/// found.
///
/// Note: O(size() + Chars.size())
/// Complexity: O(size() + Chars.size())
size_type find_last_of(StringRef Chars, size_t From = npos) const;
/// find_last_not_of - Find the last character in the string that is not
/// \arg C, or npos if not found.
/// Find the last character in the string that is not \p C, or npos if not
/// found.
size_type find_last_not_of(char C, size_t From = npos) const;
/// find_last_not_of - Find the last character in the string that is not in
/// \arg Chars, or npos if not found.
/// Find the last character in the string that is not in \p Chars, or
/// npos if not found.
///
/// Note: O(size() + Chars.size())
/// Complexity: O(size() + Chars.size())
size_type find_last_not_of(StringRef Chars, size_t From = npos) const;
/// @}
/// @name Helpful Algorithms
/// @{
/// count - Return the number of occurrences of \arg C in the string.
/// Return the number of occurrences of \p C in the string.
size_t count(char C) const {
size_t Count = 0;
for (size_t i = 0, e = Length; i != e; ++i)
@ -316,18 +316,17 @@ namespace llvm {
return Count;
}
/// count - Return the number of non-overlapped occurrences of \arg Str in
/// Return the number of non-overlapped occurrences of \p Str in
/// the string.
size_t count(StringRef Str) const;
/// getAsInteger - Parse the current string as an integer of the specified
/// radix. If Radix is specified as zero, this does radix autosensing using
/// Parse the current string as an integer of the specified radix. If
/// \p Radix is specified as zero, this does radix autosensing using
/// extended C rules: 0 is octal, 0x is hex, 0b is binary.
///
/// If the string is invalid or if only a subset of the string is valid,
/// this returns true to signify the error. The string is considered
/// erroneous if empty or if it overflows T.
///
template <typename T>
typename enable_if_c<std::numeric_limits<T>::is_signed, bool>::type
getAsInteger(unsigned Radix, T &Result) const {
@ -350,13 +349,12 @@ namespace llvm {
return false;
}
/// getAsInteger - Parse the current string as an integer of the
/// specified radix, or of an autosensed radix if the radix given
/// is 0. The current value in Result is discarded, and the
/// storage is changed to be wide enough to store the parsed
/// integer.
/// Parse the current string as an integer of the specified \p Radix, or of
/// an autosensed radix if the \p Radix given is 0. The current value in
/// \p Result is discarded, and the storage is changed to be wide enough to
/// store the parsed integer.
///
/// Returns true if the string does not solely consist of a valid
/// \returns true if the string does not solely consist of a valid
/// non-empty number in the appropriate base.
///
/// APInt::fromString is superficially similar but assumes the
@ -367,70 +365,70 @@ namespace llvm {
/// @name String Operations
/// @{
// lower - Convert the given ASCII string to lowercase.
// Convert the given ASCII string to lowercase.
std::string lower() const;
/// upper - Convert the given ASCII string to uppercase.
/// Convert the given ASCII string to uppercase.
std::string upper() const;
/// @}
/// @name Substring Operations
/// @{
/// substr - Return a reference to the substring from [Start, Start + N).
/// Return a reference to the substring from [Start, Start + N).
///
/// \param Start - The index of the starting character in the substring; if
/// \param Start The index of the starting character in the substring; if
/// the index is npos or greater than the length of the string then the
/// empty substring will be returned.
///
/// \param N - The number of characters to included in the substring. If N
/// \param N The number of characters to included in the substring. If N
/// exceeds the number of characters remaining in the string, the string
/// suffix (starting with \arg Start) will be returned.
/// suffix (starting with \p Start) will be returned.
StringRef substr(size_t Start, size_t N = npos) const {
Start = min(Start, Length);
return StringRef(Data + Start, min(N, Length - Start));
}
/// drop_front - Return a StringRef equal to 'this' but with the first
/// elements dropped.
/// Return a StringRef equal to 'this' but with the first \p N elements
/// dropped.
StringRef drop_front(unsigned N = 1) const {
assert(size() >= N && "Dropping more elements than exist");
return substr(N);
}
/// drop_back - Return a StringRef equal to 'this' but with the last
/// elements dropped.
/// Return a StringRef equal to 'this' but with the last \p N elements
/// dropped.
StringRef drop_back(unsigned N = 1) const {
assert(size() >= N && "Dropping more elements than exist");
return substr(0, size()-N);
}
/// slice - Return a reference to the substring from [Start, End).
/// Return a reference to the substring from [Start, End).
///
/// \param Start - The index of the starting character in the substring; if
/// \param Start The index of the starting character in the substring; if
/// the index is npos or greater than the length of the string then the
/// empty substring will be returned.
///
/// \param End - The index following the last character to include in the
/// substring. If this is npos, or less than \arg Start, or exceeds the
/// \param End The index following the last character to include in the
/// substring. If this is npos, or less than \p Start, or exceeds the
/// number of characters remaining in the string, the string suffix
/// (starting with \arg Start) will be returned.
/// (starting with \p Start) will be returned.
StringRef slice(size_t Start, size_t End) const {
Start = min(Start, Length);
End = min(max(Start, End), Length);
return StringRef(Data + Start, End - Start);
}
/// split - Split into two substrings around the first occurrence of a
/// separator character.
/// Split into two substrings around the first occurrence of a separator
/// character.
///
/// If \arg Separator is in the string, then the result is a pair (LHS, RHS)
/// If \p Separator is in the string, then the result is a pair (LHS, RHS)
/// such that (*this == LHS + Separator + RHS) is true and RHS is
/// maximal. If \arg Separator is not in the string, then the result is a
/// maximal. If \p Separator is not in the string, then the result is a
/// pair (LHS, RHS) where (*this == LHS) and (RHS == "").
///
/// \param Separator - The character to split on.
/// \return - The split substrings.
/// \param Separator The character to split on.
/// \returns The split substrings.
std::pair<StringRef, StringRef> split(char Separator) const {
size_t Idx = find(Separator);
if (Idx == npos)
@ -438,12 +436,12 @@ namespace llvm {
return std::make_pair(slice(0, Idx), slice(Idx+1, npos));
}
/// split - Split into two substrings around the first occurrence of a
/// separator string.
/// Split into two substrings around the first occurrence of a separator
/// string.
///
/// If \arg Separator is in the string, then the result is a pair (LHS, RHS)
/// If \p Separator is in the string, then the result is a pair (LHS, RHS)
/// such that (*this == LHS + Separator + RHS) is true and RHS is
/// maximal. If \arg Separator is not in the string, then the result is a
/// maximal. If \p Separator is not in the string, then the result is a
/// pair (LHS, RHS) where (*this == LHS) and (RHS == "").
///
/// \param Separator - The string to split on.
@ -455,14 +453,13 @@ namespace llvm {
return std::make_pair(slice(0, Idx), slice(Idx + Separator.size(), npos));
}
/// split - Split into substrings around the occurrences of a separator
/// string.
/// Split into substrings around the occurrences of a separator string.
///
/// Each substring is stored in \arg A. If \arg MaxSplit is >= 0, at most
/// \arg MaxSplit splits are done and consequently <= \arg MaxSplit
/// Each substring is stored in \p A. If \p MaxSplit is >= 0, at most
/// \p MaxSplit splits are done and consequently <= \p MaxSplit
/// elements are added to A.
/// If \arg KeepEmpty is false, empty strings are not added to \arg A. They
/// still count when considering \arg MaxSplit
/// If \p KeepEmpty is false, empty strings are not added to \p A. They
/// still count when considering \p MaxSplit
/// An useful invariant is that
/// Separator.join(A) == *this if MaxSplit == -1 and KeepEmpty == true
///
@ -474,12 +471,12 @@ namespace llvm {
StringRef Separator, int MaxSplit = -1,
bool KeepEmpty = true) const;
/// rsplit - Split into two substrings around the last occurrence of a
/// separator character.
/// Split into two substrings around the last occurrence of a separator
/// character.
///
/// If \arg Separator is in the string, then the result is a pair (LHS, RHS)
/// If \p Separator is in the string, then the result is a pair (LHS, RHS)
/// such that (*this == LHS + Separator + RHS) is true and RHS is
/// minimal. If \arg Separator is not in the string, then the result is a
/// minimal. If \p Separator is not in the string, then the result is a
/// pair (LHS, RHS) where (*this == LHS) and (RHS == "").
///
/// \param Separator - The character to split on.
@ -491,20 +488,20 @@ namespace llvm {
return std::make_pair(slice(0, Idx), slice(Idx+1, npos));
}
/// ltrim - Return string with consecutive characters in \arg Chars starting
/// from the left removed.
/// Return string with consecutive characters in \p Chars starting from
/// the left removed.
StringRef ltrim(StringRef Chars = " \t\n\v\f\r") const {
return drop_front(std::min(Length, find_first_not_of(Chars)));
}
/// rtrim - Return string with consecutive characters in \arg Chars starting
/// from the right removed.
/// Return string with consecutive characters in \p Chars starting from
/// the right removed.
StringRef rtrim(StringRef Chars = " \t\n\v\f\r") const {
return drop_back(Length - std::min(Length, find_last_not_of(Chars) + 1));
}
/// trim - Return string with consecutive characters in \arg Chars starting
/// from the left and right removed.
/// Return string with consecutive characters in \p Chars starting from
/// the left and right removed.
StringRef trim(StringRef Chars = " \t\n\v\f\r") const {
return ltrim(Chars).rtrim(Chars);
}

View File

@ -29,8 +29,13 @@ namespace llvm {
assert(!InLang.empty());
const char *KeyStart = InLang.data();
const char *KeyEnd = KeyStart + InLang.size();
return base::insert(llvm::StringMapEntry<char>::
Create(KeyStart, KeyEnd, base::getAllocator(), '+'));
llvm::StringMapEntry<char> *Entry = llvm::StringMapEntry<char>::
Create(KeyStart, KeyEnd, base::getAllocator(), '+');
if (!base::insert(Entry)) {
Entry->Destroy(base::getAllocator());
return false;
}
return true;
}
};
}

View File

@ -1,334 +0,0 @@
//===- llvm/ADT/Trie.h ---- Generic trie structure --------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This class defines a generic trie structure. The trie structure
// is immutable after creation, but the payload contained within it is not.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ADT_TRIE_H
#define LLVM_ADT_TRIE_H
#include "llvm/ADT/GraphTraits.h"
#include "llvm/Support/DOTGraphTraits.h"
#include <cassert>
#include <vector>
namespace llvm {
// FIXME:
// - Labels are usually small, maybe it's better to use SmallString
// - Should we use char* during construction?
// - Should we templatize Empty with traits-like interface?
template<class Payload>
class Trie {
friend class GraphTraits<Trie<Payload> >;
friend class DOTGraphTraits<Trie<Payload> >;
public:
class Node {
friend class Trie;
public:
typedef std::vector<Node*> NodeVectorType;
typedef typename NodeVectorType::iterator iterator;
typedef typename NodeVectorType::const_iterator const_iterator;
private:
enum QueryResult {
Same = -3,
StringIsPrefix = -2,
LabelIsPrefix = -1,
DontMatch = 0,
HaveCommonPart
};
struct NodeCmp {
bool operator() (Node* N1, Node* N2) {
return (N1->Label[0] < N2->Label[0]);
}
bool operator() (Node* N, char Id) {
return (N->Label[0] < Id);
}
};
std::string Label;
Payload Data;
NodeVectorType Children;
// Do not implement
Node(const Node&);
Node& operator=(const Node&);
inline void addEdge(Node* N) {
if (Children.empty())
Children.push_back(N);
else {
iterator I = std::lower_bound(Children.begin(), Children.end(),
N, NodeCmp());
// FIXME: no dups are allowed
Children.insert(I, N);
}
}
inline void setEdge(Node* N) {
char Id = N->Label[0];
iterator I = std::lower_bound(Children.begin(), Children.end(),
Id, NodeCmp());
assert(I != Children.end() && "Node does not exists!");
*I = N;
}
QueryResult query(const std::string& s) const {
unsigned i, l;
unsigned l1 = s.length();
unsigned l2 = Label.length();
// Find the length of common part
l = std::min(l1, l2);
i = 0;
while ((i < l) && (s[i] == Label[i]))
++i;
if (i == l) { // One is prefix of another, find who is who
if (l1 == l2)
return Same;
else if (i == l1)
return StringIsPrefix;
else
return LabelIsPrefix;
} else // s and Label have common (possible empty) part, return its length
return (QueryResult)i;
}
public:
inline explicit Node(const Payload& data, const std::string& label = ""):
Label(label), Data(data) { }
inline const Payload& data() const { return Data; }
inline void setData(const Payload& data) { Data = data; }
inline const std::string& label() const { return Label; }
#if 0
inline void dump() {
llvm::cerr << "Node: " << this << "\n"
<< "Label: " << Label << "\n"
<< "Children:\n";
for (iterator I = Children.begin(), E = Children.end(); I != E; ++I)
llvm::cerr << (*I)->Label << "\n";
}
#endif
inline Node* getEdge(char Id) {
Node* fNode = NULL;
iterator I = std::lower_bound(Children.begin(), Children.end(),
Id, NodeCmp());
if (I != Children.end() && (*I)->Label[0] == Id)
fNode = *I;
return fNode;
}
inline iterator begin() { return Children.begin(); }
inline const_iterator begin() const { return Children.begin(); }
inline iterator end () { return Children.end(); }
inline const_iterator end () const { return Children.end(); }
inline size_t size () const { return Children.size(); }
inline bool empty() const { return Children.empty(); }
inline const Node* &front() const { return Children.front(); }
inline Node* &front() { return Children.front(); }
inline const Node* &back() const { return Children.back(); }
inline Node* &back() { return Children.back(); }
};
private:
std::vector<Node*> Nodes;
Payload Empty;
inline Node* addNode(const Payload& data, const std::string label = "") {
Node* N = new Node(data, label);
Nodes.push_back(N);
return N;
}
inline Node* splitEdge(Node* N, char Id, size_t index) {
Node* eNode = N->getEdge(Id);
assert(eNode && "Node doesn't exist");
const std::string &l = eNode->Label;
assert(index > 0 && index < l.length() && "Trying to split too far!");
std::string l1 = l.substr(0, index);
std::string l2 = l.substr(index);
Node* nNode = addNode(Empty, l1);
N->setEdge(nNode);
eNode->Label = l2;
nNode->addEdge(eNode);
return nNode;
}
// Do not implement
Trie(const Trie&);
Trie& operator=(const Trie&);
public:
inline explicit Trie(const Payload& empty):Empty(empty) {
addNode(Empty);
}
inline ~Trie() {
for (unsigned i = 0, e = Nodes.size(); i != e; ++i)
delete Nodes[i];
}
inline Node* getRoot() const { return Nodes[0]; }
bool addString(const std::string& s, const Payload& data);
const Payload& lookup(const std::string& s) const;
};
// Define this out-of-line to dissuade the C++ compiler from inlining it.
template<class Payload>
bool Trie<Payload>::addString(const std::string& s, const Payload& data) {
Node* cNode = getRoot();
Node* tNode = NULL;
std::string s1(s);
while (tNode == NULL) {
char Id = s1[0];
if (Node* nNode = cNode->getEdge(Id)) {
typename Node::QueryResult r = nNode->query(s1);
switch (r) {
case Node::Same:
case Node::StringIsPrefix:
// Currently we don't allow to have two strings in the trie one
// being a prefix of another. This should be fixed.
assert(0 && "FIXME!");
return false;
case Node::DontMatch:
llvm_unreachable("Impossible!");
case Node::LabelIsPrefix:
s1 = s1.substr(nNode->label().length());
cNode = nNode;
break;
default:
nNode = splitEdge(cNode, Id, r);
tNode = addNode(data, s1.substr(r));
nNode->addEdge(tNode);
}
} else {
tNode = addNode(data, s1);
cNode->addEdge(tNode);
}
}
return true;
}
template<class Payload>
const Payload& Trie<Payload>::lookup(const std::string& s) const {
Node* cNode = getRoot();
Node* tNode = NULL;
std::string s1(s);
while (tNode == NULL) {
char Id = s1[0];
if (Node* nNode = cNode->getEdge(Id)) {
typename Node::QueryResult r = nNode->query(s1);
switch (r) {
case Node::Same:
tNode = nNode;
break;
case Node::StringIsPrefix:
return Empty;
case Node::DontMatch:
llvm_unreachable("Impossible!");
case Node::LabelIsPrefix:
s1 = s1.substr(nNode->label().length());
cNode = nNode;
break;
default:
return Empty;
}
} else
return Empty;
}
return tNode->data();
}
template<class Payload>
struct GraphTraits<Trie<Payload> > {
typedef Trie<Payload> TrieType;
typedef typename TrieType::Node NodeType;
typedef typename NodeType::iterator ChildIteratorType;
static inline NodeType *getEntryNode(const TrieType& T) {
return T.getRoot();
}
static inline ChildIteratorType child_begin(NodeType *N) {
return N->begin();
}
static inline ChildIteratorType child_end(NodeType *N) { return N->end(); }
typedef typename std::vector<NodeType*>::const_iterator nodes_iterator;
static inline nodes_iterator nodes_begin(const TrieType& G) {
return G.Nodes.begin();
}
static inline nodes_iterator nodes_end(const TrieType& G) {
return G.Nodes.end();
}
};
template<class Payload>
struct DOTGraphTraits<Trie<Payload> > : public DefaultDOTGraphTraits {
typedef typename Trie<Payload>::Node NodeType;
typedef typename GraphTraits<Trie<Payload> >::ChildIteratorType EdgeIter;
static std::string getGraphName(const Trie<Payload>& T) {
return "Trie";
}
static std::string getNodeLabel(NodeType* Node, const Trie<Payload>& T) {
if (T.getRoot() == Node)
return "<Root>";
else
return Node->label();
}
static std::string getEdgeSourceLabel(NodeType* Node, EdgeIter I) {
NodeType* N = *I;
return N->label().substr(0, 1);
}
static std::string getNodeAttributes(const NodeType* Node,
const Trie<Payload>& T) {
if (Node->data() != T.Empty)
return "color=blue";
return "";
}
};
} // end of llvm namespace
#endif // LLVM_ADT_TRIE_H

View File

@ -65,7 +65,9 @@ class Triple {
nvptx, // NVPTX: 32-bit
nvptx64, // NVPTX: 64-bit
le32, // le32: generic little-endian 32-bit CPU (PNaCl / Emscripten)
amdil // amdil: amd IL
amdil, // amdil: amd IL
spir, // SPIR: standard portable IR for OpenCL 32-bit version
spir64 // SPIR: standard portable IR for OpenCL 64-bit version
};
enum VendorType {
UnknownVendor,
@ -74,7 +76,9 @@ class Triple {
PC,
SCEI,
BGP,
BGQ
BGQ,
Freescale,
IBM
};
enum OSType {
UnknownOS,
@ -99,7 +103,8 @@ class Triple {
RTEMS,
NativeClient,
CNK, // BG/P Compute-Node Kernel
Bitrig
Bitrig,
AIX
};
enum EnvironmentType {
UnknownEnvironment,
@ -109,7 +114,8 @@ class Triple {
GNUEABIHF,
EABI,
MachO,
ANDROIDEABI
Android,
ELF
};
private:
@ -341,7 +347,7 @@ class Triple {
/// to a known type.
void setEnvironment(EnvironmentType Kind);
/// setTriple - Set all components to the new triple \arg Str.
/// setTriple - Set all components to the new triple \p Str.
void setTriple(const Twine &Str);
/// setArchName - Set the architecture (first) component of the
@ -392,11 +398,10 @@ class Triple {
/// @name Static helpers for IDs.
/// @{
/// getArchTypeName - Get the canonical name for the \arg Kind
/// architecture.
/// getArchTypeName - Get the canonical name for the \p Kind architecture.
static const char *getArchTypeName(ArchType Kind);
/// getArchTypePrefix - Get the "prefix" canonical name for the \arg Kind
/// getArchTypePrefix - Get the "prefix" canonical name for the \p Kind
/// architecture. This is the prefix used by the architecture specific
/// builtins, and is suitable for passing to \see
/// Intrinsic::getIntrinsicForGCCBuiltin().
@ -404,15 +409,13 @@ class Triple {
/// \return - The architecture prefix, or 0 if none is defined.
static const char *getArchTypePrefix(ArchType Kind);
/// getVendorTypeName - Get the canonical name for the \arg Kind
/// vendor.
/// getVendorTypeName - Get the canonical name for the \p Kind vendor.
static const char *getVendorTypeName(VendorType Kind);
/// getOSTypeName - Get the canonical name for the \arg Kind operating
/// system.
/// getOSTypeName - Get the canonical name for the \p Kind operating system.
static const char *getOSTypeName(OSType Kind);
/// getEnvironmentTypeName - Get the canonical name for the \arg Kind
/// getEnvironmentTypeName - Get the canonical name for the \p Kind
/// environment.
static const char *getEnvironmentTypeName(EnvironmentType Kind);
@ -424,11 +427,6 @@ class Triple {
/// architecture name (e.g., "x86").
static ArchType getArchTypeForLLVMName(StringRef Str);
/// getArchTypeForDarwinArchName - Get the architecture type for a "Darwin"
/// architecture name, for example as accepted by "gcc -arch" (see also
/// arch(3)).
static ArchType getArchTypeForDarwinArchName(StringRef Str);
/// @}
};

View File

@ -44,7 +44,7 @@ namespace llvm {
/// itself, and renders as an empty string. This can be returned from APIs to
/// effectively nullify any concatenations performed on the result.
///
/// \b Implementation \n
/// \b Implementation
///
/// Given the nature of a Twine, it is not possible for the Twine's
/// concatenation method to construct interior nodes; the result must be
@ -67,7 +67,7 @@ namespace llvm {
///
/// These invariants are check by \see isValid().
///
/// \b Efficiency Considerations \n
/// \b Efficiency Considerations
///
/// The Twine is designed to yield efficient and small code for common
/// situations. For this reason, the concat() method is inlined so that
@ -303,37 +303,37 @@ namespace llvm {
LHS.character = static_cast<char>(Val);
}
/// Construct a twine to print \arg Val as an unsigned decimal integer.
/// Construct a twine to print \p Val as an unsigned decimal integer.
explicit Twine(unsigned Val)
: LHSKind(DecUIKind), RHSKind(EmptyKind) {
LHS.decUI = Val;
}
/// Construct a twine to print \arg Val as a signed decimal integer.
/// Construct a twine to print \p Val as a signed decimal integer.
explicit Twine(int Val)
: LHSKind(DecIKind), RHSKind(EmptyKind) {
LHS.decI = Val;
}
/// Construct a twine to print \arg Val as an unsigned decimal integer.
/// Construct a twine to print \p Val as an unsigned decimal integer.
explicit Twine(const unsigned long &Val)
: LHSKind(DecULKind), RHSKind(EmptyKind) {
LHS.decUL = &Val;
}
/// Construct a twine to print \arg Val as a signed decimal integer.
/// Construct a twine to print \p Val as a signed decimal integer.
explicit Twine(const long &Val)
: LHSKind(DecLKind), RHSKind(EmptyKind) {
LHS.decL = &Val;
}
/// Construct a twine to print \arg Val as an unsigned decimal integer.
/// Construct a twine to print \p Val as an unsigned decimal integer.
explicit Twine(const unsigned long long &Val)
: LHSKind(DecULLKind), RHSKind(EmptyKind) {
LHS.decULL = &Val;
}
/// Construct a twine to print \arg Val as a signed decimal integer.
/// Construct a twine to print \p Val as a signed decimal integer.
explicit Twine(const long long &Val)
: LHSKind(DecLLKind), RHSKind(EmptyKind) {
LHS.decLL = &Val;
@ -370,7 +370,7 @@ namespace llvm {
/// @name Numeric Conversions
/// @{
// Construct a twine to print \arg Val as an unsigned hexadecimal integer.
// Construct a twine to print \p Val as an unsigned hexadecimal integer.
static Twine utohexstr(const uint64_t &Val) {
Child LHS, RHS;
LHS.uHex = &Val;
@ -447,17 +447,17 @@ namespace llvm {
/// The returned StringRef's size does not include the null terminator.
StringRef toNullTerminatedStringRef(SmallVectorImpl<char> &Out) const;
/// print - Write the concatenated string represented by this twine to the
/// stream \arg OS.
/// Write the concatenated string represented by this twine to the
/// stream \p OS.
void print(raw_ostream &OS) const;
/// dump - Dump the concatenated string represented by this twine to stderr.
/// Dump the concatenated string represented by this twine to stderr.
void dump() const;
/// print - Write the representation of this twine to the stream \arg OS.
/// Write the representation of this twine to the stream \p OS.
void printRepr(raw_ostream &OS) const;
/// dumpRepr - Dump the representation of this twine to stderr.
/// Dump the representation of this twine to stderr.
void dumpRepr() const;
/// @}

View File

@ -80,8 +80,8 @@ class ValueMap {
typedef typename Config::ExtraData ExtraData;
MapT Map;
ExtraData Data;
ValueMap(const ValueMap&); // DO NOT IMPLEMENT
ValueMap& operator=(const ValueMap&); // DO NOT IMPLEMENT
ValueMap(const ValueMap&) LLVM_DELETED_FUNCTION;
ValueMap& operator=(const ValueMap&) LLVM_DELETED_FUNCTION;
public:
typedef KeyT key_type;
typedef ValueT mapped_type;

View File

@ -38,6 +38,7 @@
#ifndef LLVM_ADT_ILIST_H
#define LLVM_ADT_ILIST_H
#include "llvm/Support/Compiler.h"
#include <algorithm>
#include <cassert>
#include <cstddef>
@ -331,8 +332,8 @@ class iplist : public Traits {
// No fundamental reason why iplist can't be copyable, but the default
// copy/copy-assign won't do.
iplist(const iplist &); // do not implement
void operator=(const iplist &); // do not implement
iplist(const iplist &) LLVM_DELETED_FUNCTION;
void operator=(const iplist &) LLVM_DELETED_FUNCTION;
public:
typedef NodeTy *pointer;

View File

@ -0,0 +1,41 @@
//===--------- llvm/AddressingMode.h - Addressing Mode -------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// This file contains addressing mode data structures which are shared
// between LSR and a number of places in the codegen.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ADDRESSING_MODE_H
#define LLVM_ADDRESSING_MODE_H
#include "llvm/Support/DataTypes.h"
namespace llvm {
class GlobalValue;
/// AddrMode - This represents an addressing mode of:
/// BaseGV + BaseOffs + BaseReg + Scale*ScaleReg
/// If BaseGV is null, there is no BaseGV.
/// If BaseOffs is zero, there is no base offset.
/// If HasBaseReg is false, there is no base register.
/// If Scale is zero, there is no ScaleReg. Scale of 1 indicates a reg with
/// no scale.
///
struct AddrMode {
GlobalValue *BaseGV;
int64_t BaseOffs;
bool HasBaseReg;
int64_t Scale;
AddrMode() : BaseGV(0), BaseOffs(0), HasBaseReg(false), Scale(0) {}
};
} // End llvm namespace
#endif

View File

@ -45,7 +45,8 @@ namespace llvm {
class LoadInst;
class StoreInst;
class VAArgInst;
class TargetData;
class DataLayout;
class TargetLibraryInfo;
class Pass;
class AnalysisUsage;
class MemTransferInst;
@ -54,7 +55,8 @@ class DominatorTree;
class AliasAnalysis {
protected:
const TargetData *TD;
const DataLayout *TD;
const TargetLibraryInfo *TLI;
private:
AliasAnalysis *AA; // Previous Alias Analysis to chain to.
@ -73,7 +75,7 @@ class AliasAnalysis {
public:
static char ID; // Class identification, replacement for typeinfo
AliasAnalysis() : TD(0), AA(0) {}
AliasAnalysis() : TD(0), TLI(0), AA(0) {}
virtual ~AliasAnalysis(); // We want to be subclassed
/// UnknownSize - This is a special value which can be used with the
@ -81,12 +83,17 @@ class AliasAnalysis {
/// know the sizes of the potential memory references.
static uint64_t const UnknownSize = ~UINT64_C(0);
/// getTargetData - Return a pointer to the current TargetData object, or
/// null if no TargetData object is available.
/// getDataLayout - Return a pointer to the current DataLayout object, or
/// null if no DataLayout object is available.
///
const TargetData *getTargetData() const { return TD; }
const DataLayout *getDataLayout() const { return TD; }
/// getTypeStoreSize - Return the TargetData store size for the given type,
/// getTargetLibraryInfo - Return a pointer to the current TargetLibraryInfo
/// object, or null if no TargetLibraryInfo object is available.
///
const TargetLibraryInfo *getTargetLibraryInfo() const { return TLI; }
/// getTypeStoreSize - Return the DataLayout store size for the given type,
/// if known, or a conservative value otherwise.
///
uint64_t getTypeStoreSize(Type *Ty);
@ -187,6 +194,11 @@ class AliasAnalysis {
return isNoAlias(Location(V1, V1Size), Location(V2, V2Size));
}
/// isNoAlias - A convenience wrapper.
bool isNoAlias(const Value *V1, const Value *V2) {
return isNoAlias(Location(V1), Location(V2));
}
/// isMustAlias - A convenience wrapper.
bool isMustAlias(const Location &LocA, const Location &LocB) {
return alias(LocA, LocB) == MustAlias;

View File

@ -109,7 +109,6 @@ class AliasSet : public ilist_node<AliasSet> {
PointerRec *PtrList, **PtrListEnd; // Doubly linked list of nodes.
AliasSet *Forward; // Forwarding pointer.
AliasSet *Next, *Prev; // Doubly linked list of AliasSets.
// All instructions without a specific address in this alias set.
std::vector<AssertingVH<Instruction> > UnknownInsts;
@ -226,8 +225,8 @@ class AliasSet : public ilist_node<AliasSet> {
AccessTy(NoModRef), AliasTy(MustAlias), Volatile(false) {
}
AliasSet(const AliasSet &AS); // do not implement
void operator=(const AliasSet &AS); // do not implement
AliasSet(const AliasSet &AS) LLVM_DELETED_FUNCTION;
void operator=(const AliasSet &AS) LLVM_DELETED_FUNCTION;
PointerRec *getSomePointer() const {
return PtrList;

View File

@ -28,11 +28,14 @@ class raw_ostream;
///
/// This is a function analysis pass which provides information on the relative
/// probabilities of each "edge" in the function's CFG where such an edge is
/// defined by a pair of basic blocks. The probability for a given block and
/// a successor block are always relative to the probabilities of the other
/// successor blocks. Another way of looking at it is that the probabilities
/// for a given block B and each of its successors should sum to exactly
/// one (100%).
/// defined by a pair (PredBlock and an index in the successors). The
/// probability of an edge from one block is always relative to the
/// probabilities of other edges from the block. The probabilites of all edges
/// from a block sum to exactly one (100%).
/// We use a pair (PredBlock and an index in the successors) to uniquely
/// identify an edge, since we can have multiple edges from Src to Dst.
/// As an example, we can have a switch which jumps to Dst with value 0 and
/// value 10.
class BranchProbabilityInfo : public FunctionPass {
public:
static char ID;
@ -51,6 +54,12 @@ class BranchProbabilityInfo : public FunctionPass {
/// (0%) and one (100%) of this edge executing, relative to other edges
/// leaving the 'Src' block. The returned probability is never zero, and can
/// only be one if the source block has only one successor.
BranchProbability getEdgeProbability(const BasicBlock *Src,
unsigned IndexInSuccessors) const;
/// \brief Get the probability of going from Src to Dst.
///
/// It returns the sum of all probabilities for edges from Src to Dst.
BranchProbability getEdgeProbability(const BasicBlock *Src,
const BasicBlock *Dst) const;
@ -74,25 +83,34 @@ class BranchProbabilityInfo : public FunctionPass {
raw_ostream &printEdgeProbability(raw_ostream &OS, const BasicBlock *Src,
const BasicBlock *Dst) const;
/// \brief Get the raw edge weight calculated for the block pair.
/// \brief Get the raw edge weight calculated for the edge.
///
/// This returns the raw edge weight. It is guaranteed to fall between 1 and
/// UINT32_MAX. Note that the raw edge weight is not meaningful in isolation.
/// This interface should be very carefully, and primarily by routines that
/// are updating the analysis by later calling setEdgeWeight.
uint32_t getEdgeWeight(const BasicBlock *Src,
unsigned IndexInSuccessors) const;
/// \brief Get the raw edge weight calculated for the block pair.
///
/// This returns the sum of all raw edge weights from Src to Dst.
/// It is guaranteed to fall between 1 and UINT32_MAX.
uint32_t getEdgeWeight(const BasicBlock *Src, const BasicBlock *Dst) const;
/// \brief Set the raw edge weight for the block pair.
/// \brief Set the raw edge weight for a given edge.
///
/// This allows a pass to explicitly set the edge weight for a block. It can
/// This allows a pass to explicitly set the edge weight for an edge. It can
/// be used when updating the CFG to update and preserve the branch
/// probability information. Read the implementation of how these edge
/// weights are calculated carefully before using!
void setEdgeWeight(const BasicBlock *Src, const BasicBlock *Dst,
void setEdgeWeight(const BasicBlock *Src, unsigned IndexInSuccessors,
uint32_t Weight);
private:
typedef std::pair<const BasicBlock *, const BasicBlock *> Edge;
// Since we allow duplicate edges from one basic block to another, we use
// a pair (PredBlock and an index in the successors) to specify an edge.
typedef std::pair<const BasicBlock *, unsigned> Edge;
// Default weight value. Used when we don't have information about the edge.
// TODO: DEFAULT_WEIGHT makes sense during static predication, when none of

View File

@ -185,9 +185,9 @@ class CallGraphNode {
/// in the CalledFunctions array of this or other CallGraphNodes.
unsigned NumReferences;
CallGraphNode(const CallGraphNode &); // DO NOT IMPLEMENT
void operator=(const CallGraphNode &); // DO NOT IMPLEMENT
CallGraphNode(const CallGraphNode &) LLVM_DELETED_FUNCTION;
void operator=(const CallGraphNode &) LLVM_DELETED_FUNCTION;
void DropRef() { --NumReferences; }
void AddRef() { ++NumReferences; }
public:

View File

@ -46,7 +46,7 @@ namespace llvm {
/// capture) return false. To search it, return true.
///
/// U->getUser() is always an Instruction.
virtual bool shouldExplore(Use *U) = 0;
virtual bool shouldExplore(Use *U);
/// captured - Information about the pointer was captured by the user of
/// use U. Return true to stop the traversal or false to continue looking

View File

@ -22,11 +22,11 @@ namespace llvm {
class BasicBlock;
class Function;
class Instruction;
class TargetData;
class DataLayout;
class Value;
/// \brief Check whether an instruction is likely to be "free" when lowered.
bool isInstructionFree(const Instruction *I, const TargetData *TD = 0);
bool isInstructionFree(const Instruction *I, const DataLayout *TD = 0);
/// \brief Check whether a call will lower to something small.
///
@ -85,10 +85,10 @@ namespace llvm {
NumRets(0) {}
/// \brief Add information about a block to the current state.
void analyzeBasicBlock(const BasicBlock *BB, const TargetData *TD = 0);
void analyzeBasicBlock(const BasicBlock *BB, const DataLayout *TD = 0);
/// \brief Add information about a function to the current state.
void analyzeFunction(Function *F, const TargetData *TD = 0);
void analyzeFunction(Function *F, const DataLayout *TD = 0);
};
}

View File

@ -12,7 +12,7 @@
//
// Also, to supplement the basic VMCore ConstantExpr simplifications,
// this file declares some additional folding routines that can make use of
// TargetData information. These functions cannot go in VMCore due to library
// DataLayout information. These functions cannot go in VMCore due to library
// dependency issues.
//
//===----------------------------------------------------------------------===//
@ -24,7 +24,7 @@ namespace llvm {
class Constant;
class ConstantExpr;
class Instruction;
class TargetData;
class DataLayout;
class TargetLibraryInfo;
class Function;
class Type;
@ -36,14 +36,14 @@ namespace llvm {
/// Note that this fails if not all of the operands are constant. Otherwise,
/// this function can only fail when attempting to fold instructions like loads
/// and stores, which have no constant expression form.
Constant *ConstantFoldInstruction(Instruction *I, const TargetData *TD = 0,
Constant *ConstantFoldInstruction(Instruction *I, const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0);
/// ConstantFoldConstantExpression - Attempt to fold the constant expression
/// using the specified TargetData. If successful, the constant result is
/// using the specified DataLayout. If successful, the constant result is
/// result is returned, if not, null is returned.
Constant *ConstantFoldConstantExpression(const ConstantExpr *CE,
const TargetData *TD = 0,
const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0);
/// ConstantFoldInstOperands - Attempt to constant fold an instruction with the
@ -54,7 +54,7 @@ Constant *ConstantFoldConstantExpression(const ConstantExpr *CE,
///
Constant *ConstantFoldInstOperands(unsigned Opcode, Type *DestTy,
ArrayRef<Constant *> Ops,
const TargetData *TD = 0,
const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0);
/// ConstantFoldCompareInstOperands - Attempt to constant fold a compare
@ -63,7 +63,7 @@ Constant *ConstantFoldInstOperands(unsigned Opcode, Type *DestTy,
///
Constant *ConstantFoldCompareInstOperands(unsigned Predicate,
Constant *LHS, Constant *RHS,
const TargetData *TD = 0,
const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0);
/// ConstantFoldInsertValueInstruction - Attempt to constant fold an insertvalue
@ -75,7 +75,7 @@ Constant *ConstantFoldInsertValueInstruction(Constant *Agg, Constant *Val,
/// ConstantFoldLoadFromConstPtr - Return the value that a load from C would
/// produce if it is constant and determinable. If this is not determinable,
/// return null.
Constant *ConstantFoldLoadFromConstPtr(Constant *C, const TargetData *TD = 0);
Constant *ConstantFoldLoadFromConstPtr(Constant *C, const DataLayout *TD = 0);
/// ConstantFoldLoadThroughGEPConstantExpr - Given a constant and a
/// getelementptr constantexpr, return the constant value being addressed by the

View File

@ -0,0 +1,885 @@
//===-- llvm/Analysis/DependenceAnalysis.h -------------------- -*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// DependenceAnalysis is an LLVM pass that analyses dependences between memory
// accesses. Currently, it is an implementation of the approach described in
//
// Practical Dependence Testing
// Goff, Kennedy, Tseng
// PLDI 1991
//
// There's a single entry point that analyzes the dependence between a pair
// of memory references in a function, returning either NULL, for no dependence,
// or a more-or-less detailed description of the dependence between them.
//
// Please note that this is work in progress and the interface is subject to
// change.
//
// Plausible changes:
// Return a set of more precise dependences instead of just one dependence
// summarizing all.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_DEPENDENCEANALYSIS_H
#define LLVM_ANALYSIS_DEPENDENCEANALYSIS_H
#include "llvm/Instructions.h"
#include "llvm/Pass.h"
#include "llvm/ADT/SmallBitVector.h"
namespace llvm {
class AliasAnalysis;
class Loop;
class LoopInfo;
class ScalarEvolution;
class SCEV;
class SCEVConstant;
class raw_ostream;
/// Dependence - This class represents a dependence between two memory
/// memory references in a function. It contains minimal information and
/// is used in the very common situation where the compiler is unable to
/// determine anything beyond the existence of a dependence; that is, it
/// represents a confused dependence (see also FullDependence). In most
/// cases (for output, flow, and anti dependences), the dependence implies
/// an ordering, where the source must precede the destination; in contrast,
/// input dependences are unordered.
class Dependence {
public:
Dependence(const Instruction *Source,
const Instruction *Destination) :
Src(Source), Dst(Destination) {}
virtual ~Dependence() {}
/// Dependence::DVEntry - Each level in the distance/direction vector
/// has a direction (or perhaps a union of several directions), and
/// perhaps a distance.
struct DVEntry {
enum { NONE = 0,
LT = 1,
EQ = 2,
LE = 3,
GT = 4,
NE = 5,
GE = 6,
ALL = 7 };
unsigned char Direction : 3; // Init to ALL, then refine.
bool Scalar : 1; // Init to true.
bool PeelFirst : 1; // Peeling the first iteration will break dependence.
bool PeelLast : 1; // Peeling the last iteration will break the dependence.
bool Splitable : 1; // Splitting the loop will break dependence.
const SCEV *Distance; // NULL implies no distance available.
DVEntry() : Direction(ALL), Scalar(true), PeelFirst(false),
PeelLast(false), Splitable(false), Distance(NULL) { }
};
/// getSrc - Returns the source instruction for this dependence.
///
const Instruction *getSrc() const { return Src; }
/// getDst - Returns the destination instruction for this dependence.
///
const Instruction *getDst() const { return Dst; }
/// isInput - Returns true if this is an input dependence.
///
bool isInput() const;
/// isOutput - Returns true if this is an output dependence.
///
bool isOutput() const;
/// isFlow - Returns true if this is a flow (aka true) dependence.
///
bool isFlow() const;
/// isAnti - Returns true if this is an anti dependence.
///
bool isAnti() const;
/// isOrdered - Returns true if dependence is Output, Flow, or Anti
///
bool isOrdered() const { return isOutput() || isFlow() || isAnti(); }
/// isUnordered - Returns true if dependence is Input
///
bool isUnordered() const { return isInput(); }
/// isLoopIndependent - Returns true if this is a loop-independent
/// dependence.
virtual bool isLoopIndependent() const { return true; }
/// isConfused - Returns true if this dependence is confused
/// (the compiler understands nothing and makes worst-case
/// assumptions).
virtual bool isConfused() const { return true; }
/// isConsistent - Returns true if this dependence is consistent
/// (occurs every time the source and destination are executed).
virtual bool isConsistent() const { return false; }
/// getLevels - Returns the number of common loops surrounding the
/// source and destination of the dependence.
virtual unsigned getLevels() const { return 0; }
/// getDirection - Returns the direction associated with a particular
/// level.
virtual unsigned getDirection(unsigned Level) const { return DVEntry::ALL; }
/// getDistance - Returns the distance (or NULL) associated with a
/// particular level.
virtual const SCEV *getDistance(unsigned Level) const { return NULL; }
/// isPeelFirst - Returns true if peeling the first iteration from
/// this loop will break this dependence.
virtual bool isPeelFirst(unsigned Level) const { return false; }
/// isPeelLast - Returns true if peeling the last iteration from
/// this loop will break this dependence.
virtual bool isPeelLast(unsigned Level) const { return false; }
/// isSplitable - Returns true if splitting this loop will break
/// the dependence.
virtual bool isSplitable(unsigned Level) const { return false; }
/// isScalar - Returns true if a particular level is scalar; that is,
/// if no subscript in the source or destination mention the induction
/// variable associated with the loop at this level.
virtual bool isScalar(unsigned Level) const;
/// dump - For debugging purposes, dumps a dependence to OS.
///
void dump(raw_ostream &OS) const;
private:
const Instruction *Src, *Dst;
friend class DependenceAnalysis;
};
/// FullDependence - This class represents a dependence between two memory
/// references in a function. It contains detailed information about the
/// dependence (direction vectors, etc) and is used when the compiler is
/// able to accurately analyze the interaction of the references; that is,
/// it is not a confused dependence (see Dependence). In most cases
/// (for output, flow, and anti dependences), the dependence implies an
/// ordering, where the source must precede the destination; in contrast,
/// input dependences are unordered.
class FullDependence : public Dependence {
public:
FullDependence(const Instruction *Src,
const Instruction *Dst,
bool LoopIndependent,
unsigned Levels);
~FullDependence() {
delete DV;
}
/// isLoopIndependent - Returns true if this is a loop-independent
/// dependence.
bool isLoopIndependent() const { return LoopIndependent; }
/// isConfused - Returns true if this dependence is confused
/// (the compiler understands nothing and makes worst-case
/// assumptions).
bool isConfused() const { return false; }
/// isConsistent - Returns true if this dependence is consistent
/// (occurs every time the source and destination are executed).
bool isConsistent() const { return Consistent; }
/// getLevels - Returns the number of common loops surrounding the
/// source and destination of the dependence.
unsigned getLevels() const { return Levels; }
/// getDirection - Returns the direction associated with a particular
/// level.
unsigned getDirection(unsigned Level) const;
/// getDistance - Returns the distance (or NULL) associated with a
/// particular level.
const SCEV *getDistance(unsigned Level) const;
/// isPeelFirst - Returns true if peeling the first iteration from
/// this loop will break this dependence.
bool isPeelFirst(unsigned Level) const;
/// isPeelLast - Returns true if peeling the last iteration from
/// this loop will break this dependence.
bool isPeelLast(unsigned Level) const;
/// isSplitable - Returns true if splitting the loop will break
/// the dependence.
bool isSplitable(unsigned Level) const;
/// isScalar - Returns true if a particular level is scalar; that is,
/// if no subscript in the source or destination mention the induction
/// variable associated with the loop at this level.
bool isScalar(unsigned Level) const;
private:
unsigned short Levels;
bool LoopIndependent;
bool Consistent; // Init to true, then refine.
DVEntry *DV;
friend class DependenceAnalysis;
};
/// DependenceAnalysis - This class is the main dependence-analysis driver.
///
class DependenceAnalysis : public FunctionPass {
void operator=(const DependenceAnalysis &); // do not implement
DependenceAnalysis(const DependenceAnalysis &); // do not implement
public:
/// depends - Tests for a dependence between the Src and Dst instructions.
/// Returns NULL if no dependence; otherwise, returns a Dependence (or a
/// FullDependence) with as much information as can be gleaned.
/// The flag PossiblyLoopIndependent should be set by the caller
/// if it appears that control flow can reach from Src to Dst
/// without traversing a loop back edge.
Dependence *depends(const Instruction *Src,
const Instruction *Dst,
bool PossiblyLoopIndependent);
/// getSplitIteration - Give a dependence that's splitable at some
/// particular level, return the iteration that should be used to split
/// the loop.
///
/// Generally, the dependence analyzer will be used to build
/// a dependence graph for a function (basically a map from instructions
/// to dependences). Looking for cycles in the graph shows us loops
/// that cannot be trivially vectorized/parallelized.
///
/// We can try to improve the situation by examining all the dependences
/// that make up the cycle, looking for ones we can break.
/// Sometimes, peeling the first or last iteration of a loop will break
/// dependences, and there are flags for those possibilities.
/// Sometimes, splitting a loop at some other iteration will do the trick,
/// and we've got a flag for that case. Rather than waste the space to
/// record the exact iteration (since we rarely know), we provide
/// a method that calculates the iteration. It's a drag that it must work
/// from scratch, but wonderful in that it's possible.
///
/// Here's an example:
///
/// for (i = 0; i < 10; i++)
/// A[i] = ...
/// ... = A[11 - i]
///
/// There's a loop-carried flow dependence from the store to the load,
/// found by the weak-crossing SIV test. The dependence will have a flag,
/// indicating that the dependence can be broken by splitting the loop.
/// Calling getSplitIteration will return 5.
/// Splitting the loop breaks the dependence, like so:
///
/// for (i = 0; i <= 5; i++)
/// A[i] = ...
/// ... = A[11 - i]
/// for (i = 6; i < 10; i++)
/// A[i] = ...
/// ... = A[11 - i]
///
/// breaks the dependence and allows us to vectorize/parallelize
/// both loops.
const SCEV *getSplitIteration(const Dependence *Dep, unsigned Level);
private:
AliasAnalysis *AA;
ScalarEvolution *SE;
LoopInfo *LI;
Function *F;
/// Subscript - This private struct represents a pair of subscripts from
/// a pair of potentially multi-dimensional array references. We use a
/// vector of them to guide subscript partitioning.
struct Subscript {
const SCEV *Src;
const SCEV *Dst;
enum ClassificationKind { ZIV, SIV, RDIV, MIV, NonLinear } Classification;
SmallBitVector Loops;
SmallBitVector GroupLoops;
SmallBitVector Group;
};
struct CoefficientInfo {
const SCEV *Coeff;
const SCEV *PosPart;
const SCEV *NegPart;
const SCEV *Iterations;
};
struct BoundInfo {
const SCEV *Iterations;
const SCEV *Upper[8];
const SCEV *Lower[8];
unsigned char Direction;
unsigned char DirSet;
};
/// Constraint - This private class represents a constraint, as defined
/// in the paper
///
/// Practical Dependence Testing
/// Goff, Kennedy, Tseng
/// PLDI 1991
///
/// There are 5 kinds of constraint, in a hierarchy.
/// 1) Any - indicates no constraint, any dependence is possible.
/// 2) Line - A line ax + by = c, where a, b, and c are parameters,
/// representing the dependence equation.
/// 3) Distance - The value d of the dependence distance;
/// 4) Point - A point <x, y> representing the dependence from
/// iteration x to iteration y.
/// 5) Empty - No dependence is possible.
class Constraint {
private:
enum ConstraintKind { Empty, Point, Distance, Line, Any } Kind;
ScalarEvolution *SE;
const SCEV *A;
const SCEV *B;
const SCEV *C;
const Loop *AssociatedLoop;
public:
/// isEmpty - Return true if the constraint is of kind Empty.
bool isEmpty() const { return Kind == Empty; }
/// isPoint - Return true if the constraint is of kind Point.
bool isPoint() const { return Kind == Point; }
/// isDistance - Return true if the constraint is of kind Distance.
bool isDistance() const { return Kind == Distance; }
/// isLine - Return true if the constraint is of kind Line.
/// Since Distance's can also be represented as Lines, we also return
/// true if the constraint is of kind Distance.
bool isLine() const { return Kind == Line || Kind == Distance; }
/// isAny - Return true if the constraint is of kind Any;
bool isAny() const { return Kind == Any; }
/// getX - If constraint is a point <X, Y>, returns X.
/// Otherwise assert.
const SCEV *getX() const;
/// getY - If constraint is a point <X, Y>, returns Y.
/// Otherwise assert.
const SCEV *getY() const;
/// getA - If constraint is a line AX + BY = C, returns A.
/// Otherwise assert.
const SCEV *getA() const;
/// getB - If constraint is a line AX + BY = C, returns B.
/// Otherwise assert.
const SCEV *getB() const;
/// getC - If constraint is a line AX + BY = C, returns C.
/// Otherwise assert.
const SCEV *getC() const;
/// getD - If constraint is a distance, returns D.
/// Otherwise assert.
const SCEV *getD() const;
/// getAssociatedLoop - Returns the loop associated with this constraint.
const Loop *getAssociatedLoop() const;
/// setPoint - Change a constraint to Point.
void setPoint(const SCEV *X, const SCEV *Y, const Loop *CurrentLoop);
/// setLine - Change a constraint to Line.
void setLine(const SCEV *A, const SCEV *B,
const SCEV *C, const Loop *CurrentLoop);
/// setDistance - Change a constraint to Distance.
void setDistance(const SCEV *D, const Loop *CurrentLoop);
/// setEmpty - Change a constraint to Empty.
void setEmpty();
/// setAny - Change a constraint to Any.
void setAny(ScalarEvolution *SE);
/// dump - For debugging purposes. Dumps the constraint
/// out to OS.
void dump(raw_ostream &OS) const;
};
/// establishNestingLevels - Examines the loop nesting of the Src and Dst
/// instructions and establishes their shared loops. Sets the variables
/// CommonLevels, SrcLevels, and MaxLevels.
/// The source and destination instructions needn't be contained in the same
/// loop. The routine establishNestingLevels finds the level of most deeply
/// nested loop that contains them both, CommonLevels. An instruction that's
/// not contained in a loop is at level = 0. MaxLevels is equal to the level
/// of the source plus the level of the destination, minus CommonLevels.
/// This lets us allocate vectors MaxLevels in length, with room for every
/// distinct loop referenced in both the source and destination subscripts.
/// The variable SrcLevels is the nesting depth of the source instruction.
/// It's used to help calculate distinct loops referenced by the destination.
/// Here's the map from loops to levels:
/// 0 - unused
/// 1 - outermost common loop
/// ... - other common loops
/// CommonLevels - innermost common loop
/// ... - loops containing Src but not Dst
/// SrcLevels - innermost loop containing Src but not Dst
/// ... - loops containing Dst but not Src
/// MaxLevels - innermost loop containing Dst but not Src
/// Consider the follow code fragment:
/// for (a = ...) {
/// for (b = ...) {
/// for (c = ...) {
/// for (d = ...) {
/// A[] = ...;
/// }
/// }
/// for (e = ...) {
/// for (f = ...) {
/// for (g = ...) {
/// ... = A[];
/// }
/// }
/// }
/// }
/// }
/// If we're looking at the possibility of a dependence between the store
/// to A (the Src) and the load from A (the Dst), we'll note that they
/// have 2 loops in common, so CommonLevels will equal 2 and the direction
/// vector for Result will have 2 entries. SrcLevels = 4 and MaxLevels = 7.
/// A map from loop names to level indices would look like
/// a - 1
/// b - 2 = CommonLevels
/// c - 3
/// d - 4 = SrcLevels
/// e - 5
/// f - 6
/// g - 7 = MaxLevels
void establishNestingLevels(const Instruction *Src,
const Instruction *Dst);
unsigned CommonLevels, SrcLevels, MaxLevels;
/// mapSrcLoop - Given one of the loops containing the source, return
/// its level index in our numbering scheme.
unsigned mapSrcLoop(const Loop *SrcLoop) const;
/// mapDstLoop - Given one of the loops containing the destination,
/// return its level index in our numbering scheme.
unsigned mapDstLoop(const Loop *DstLoop) const;
/// isLoopInvariant - Returns true if Expression is loop invariant
/// in LoopNest.
bool isLoopInvariant(const SCEV *Expression, const Loop *LoopNest) const;
/// removeMatchingExtensions - Examines a subscript pair.
/// If the source and destination are identically sign (or zero)
/// extended, it strips off the extension in an effort to
/// simplify the actual analysis.
void removeMatchingExtensions(Subscript *Pair);
/// collectCommonLoops - Finds the set of loops from the LoopNest that
/// have a level <= CommonLevels and are referred to by the SCEV Expression.
void collectCommonLoops(const SCEV *Expression,
const Loop *LoopNest,
SmallBitVector &Loops) const;
/// checkSrcSubscript - Examines the SCEV Src, returning true iff it's
/// linear. Collect the set of loops mentioned by Src.
bool checkSrcSubscript(const SCEV *Src,
const Loop *LoopNest,
SmallBitVector &Loops);
/// checkDstSubscript - Examines the SCEV Dst, returning true iff it's
/// linear. Collect the set of loops mentioned by Dst.
bool checkDstSubscript(const SCEV *Dst,
const Loop *LoopNest,
SmallBitVector &Loops);
/// isKnownPredicate - Compare X and Y using the predicate Pred.
/// Basically a wrapper for SCEV::isKnownPredicate,
/// but tries harder, especially in the presence of sign and zero
/// extensions and symbolics.
bool isKnownPredicate(ICmpInst::Predicate Pred,
const SCEV *X,
const SCEV *Y) const;
/// collectUpperBound - All subscripts are the same type (on my machine,
/// an i64). The loop bound may be a smaller type. collectUpperBound
/// find the bound, if available, and zero extends it to the Type T.
/// (I zero extend since the bound should always be >= 0.)
/// If no upper bound is available, return NULL.
const SCEV *collectUpperBound(const Loop *l, Type *T) const;
/// collectConstantUpperBound - Calls collectUpperBound(), then
/// attempts to cast it to SCEVConstant. If the cast fails,
/// returns NULL.
const SCEVConstant *collectConstantUpperBound(const Loop *l, Type *T) const;
/// classifyPair - Examines the subscript pair (the Src and Dst SCEVs)
/// and classifies it as either ZIV, SIV, RDIV, MIV, or Nonlinear.
/// Collects the associated loops in a set.
Subscript::ClassificationKind classifyPair(const SCEV *Src,
const Loop *SrcLoopNest,
const SCEV *Dst,
const Loop *DstLoopNest,
SmallBitVector &Loops);
/// testZIV - Tests the ZIV subscript pair (Src and Dst) for dependence.
/// Returns true if any possible dependence is disproved.
/// If there might be a dependence, returns false.
/// If the dependence isn't proven to exist,
/// marks the Result as inconsistent.
bool testZIV(const SCEV *Src,
const SCEV *Dst,
FullDependence &Result) const;
/// testSIV - Tests the SIV subscript pair (Src and Dst) for dependence.
/// Things of the form [c1 + a1*i] and [c2 + a2*j], where
/// i and j are induction variables, c1 and c2 are loop invariant,
/// and a1 and a2 are constant.
/// Returns true if any possible dependence is disproved.
/// If there might be a dependence, returns false.
/// Sets appropriate direction vector entry and, when possible,
/// the distance vector entry.
/// If the dependence isn't proven to exist,
/// marks the Result as inconsistent.
bool testSIV(const SCEV *Src,
const SCEV *Dst,
unsigned &Level,
FullDependence &Result,
Constraint &NewConstraint,
const SCEV *&SplitIter) const;
/// testRDIV - Tests the RDIV subscript pair (Src and Dst) for dependence.
/// Things of the form [c1 + a1*i] and [c2 + a2*j]
/// where i and j are induction variables, c1 and c2 are loop invariant,
/// and a1 and a2 are constant.
/// With minor algebra, this test can also be used for things like
/// [c1 + a1*i + a2*j][c2].
/// Returns true if any possible dependence is disproved.
/// If there might be a dependence, returns false.
/// Marks the Result as inconsistent.
bool testRDIV(const SCEV *Src,
const SCEV *Dst,
FullDependence &Result) const;
/// testMIV - Tests the MIV subscript pair (Src and Dst) for dependence.
/// Returns true if dependence disproved.
/// Can sometimes refine direction vectors.
bool testMIV(const SCEV *Src,
const SCEV *Dst,
const SmallBitVector &Loops,
FullDependence &Result) const;
/// strongSIVtest - Tests the strong SIV subscript pair (Src and Dst)
/// for dependence.
/// Things of the form [c1 + a*i] and [c2 + a*i],
/// where i is an induction variable, c1 and c2 are loop invariant,
/// and a is a constant
/// Returns true if any possible dependence is disproved.
/// If there might be a dependence, returns false.
/// Sets appropriate direction and distance.
bool strongSIVtest(const SCEV *Coeff,
const SCEV *SrcConst,
const SCEV *DstConst,
const Loop *CurrentLoop,
unsigned Level,
FullDependence &Result,
Constraint &NewConstraint) const;
/// weakCrossingSIVtest - Tests the weak-crossing SIV subscript pair
/// (Src and Dst) for dependence.
/// Things of the form [c1 + a*i] and [c2 - a*i],
/// where i is an induction variable, c1 and c2 are loop invariant,
/// and a is a constant.
/// Returns true if any possible dependence is disproved.
/// If there might be a dependence, returns false.
/// Sets appropriate direction entry.
/// Set consistent to false.
/// Marks the dependence as splitable.
bool weakCrossingSIVtest(const SCEV *SrcCoeff,
const SCEV *SrcConst,
const SCEV *DstConst,
const Loop *CurrentLoop,
unsigned Level,
FullDependence &Result,
Constraint &NewConstraint,
const SCEV *&SplitIter) const;
/// ExactSIVtest - Tests the SIV subscript pair
/// (Src and Dst) for dependence.
/// Things of the form [c1 + a1*i] and [c2 + a2*i],
/// where i is an induction variable, c1 and c2 are loop invariant,
/// and a1 and a2 are constant.
/// Returns true if any possible dependence is disproved.
/// If there might be a dependence, returns false.
/// Sets appropriate direction entry.
/// Set consistent to false.
bool exactSIVtest(const SCEV *SrcCoeff,
const SCEV *DstCoeff,
const SCEV *SrcConst,
const SCEV *DstConst,
const Loop *CurrentLoop,
unsigned Level,
FullDependence &Result,
Constraint &NewConstraint) const;
/// weakZeroSrcSIVtest - Tests the weak-zero SIV subscript pair
/// (Src and Dst) for dependence.
/// Things of the form [c1] and [c2 + a*i],
/// where i is an induction variable, c1 and c2 are loop invariant,
/// and a is a constant. See also weakZeroDstSIVtest.
/// Returns true if any possible dependence is disproved.
/// If there might be a dependence, returns false.
/// Sets appropriate direction entry.
/// Set consistent to false.
/// If loop peeling will break the dependence, mark appropriately.
bool weakZeroSrcSIVtest(const SCEV *DstCoeff,
const SCEV *SrcConst,
const SCEV *DstConst,
const Loop *CurrentLoop,
unsigned Level,
FullDependence &Result,
Constraint &NewConstraint) const;
/// weakZeroDstSIVtest - Tests the weak-zero SIV subscript pair
/// (Src and Dst) for dependence.
/// Things of the form [c1 + a*i] and [c2],
/// where i is an induction variable, c1 and c2 are loop invariant,
/// and a is a constant. See also weakZeroSrcSIVtest.
/// Returns true if any possible dependence is disproved.
/// If there might be a dependence, returns false.
/// Sets appropriate direction entry.
/// Set consistent to false.
/// If loop peeling will break the dependence, mark appropriately.
bool weakZeroDstSIVtest(const SCEV *SrcCoeff,
const SCEV *SrcConst,
const SCEV *DstConst,
const Loop *CurrentLoop,
unsigned Level,
FullDependence &Result,
Constraint &NewConstraint) const;
/// exactRDIVtest - Tests the RDIV subscript pair for dependence.
/// Things of the form [c1 + a*i] and [c2 + b*j],
/// where i and j are induction variable, c1 and c2 are loop invariant,
/// and a and b are constants.
/// Returns true if any possible dependence is disproved.
/// Marks the result as inconsistent.
/// Works in some cases that symbolicRDIVtest doesn't,
/// and vice versa.
bool exactRDIVtest(const SCEV *SrcCoeff,
const SCEV *DstCoeff,
const SCEV *SrcConst,
const SCEV *DstConst,
const Loop *SrcLoop,
const Loop *DstLoop,
FullDependence &Result) const;
/// symbolicRDIVtest - Tests the RDIV subscript pair for dependence.
/// Things of the form [c1 + a*i] and [c2 + b*j],
/// where i and j are induction variable, c1 and c2 are loop invariant,
/// and a and b are constants.
/// Returns true if any possible dependence is disproved.
/// Marks the result as inconsistent.
/// Works in some cases that exactRDIVtest doesn't,
/// and vice versa. Can also be used as a backup for
/// ordinary SIV tests.
bool symbolicRDIVtest(const SCEV *SrcCoeff,
const SCEV *DstCoeff,
const SCEV *SrcConst,
const SCEV *DstConst,
const Loop *SrcLoop,
const Loop *DstLoop) const;
/// gcdMIVtest - Tests an MIV subscript pair for dependence.
/// Returns true if any possible dependence is disproved.
/// Marks the result as inconsistent.
/// Can sometimes disprove the equal direction for 1 or more loops.
// Can handle some symbolics that even the SIV tests don't get,
/// so we use it as a backup for everything.
bool gcdMIVtest(const SCEV *Src,
const SCEV *Dst,
FullDependence &Result) const;
/// banerjeeMIVtest - Tests an MIV subscript pair for dependence.
/// Returns true if any possible dependence is disproved.
/// Marks the result as inconsistent.
/// Computes directions.
bool banerjeeMIVtest(const SCEV *Src,
const SCEV *Dst,
const SmallBitVector &Loops,
FullDependence &Result) const;
/// collectCoefficientInfo - Walks through the subscript,
/// collecting each coefficient, the associated loop bounds,
/// and recording its positive and negative parts for later use.
CoefficientInfo *collectCoeffInfo(const SCEV *Subscript,
bool SrcFlag,
const SCEV *&Constant) const;
/// getPositivePart - X^+ = max(X, 0).
///
const SCEV *getPositivePart(const SCEV *X) const;
/// getNegativePart - X^- = min(X, 0).
///
const SCEV *getNegativePart(const SCEV *X) const;
/// getLowerBound - Looks through all the bounds info and
/// computes the lower bound given the current direction settings
/// at each level.
const SCEV *getLowerBound(BoundInfo *Bound) const;
/// getUpperBound - Looks through all the bounds info and
/// computes the upper bound given the current direction settings
/// at each level.
const SCEV *getUpperBound(BoundInfo *Bound) const;
/// exploreDirections - Hierarchically expands the direction vector
/// search space, combining the directions of discovered dependences
/// in the DirSet field of Bound. Returns the number of distinct
/// dependences discovered. If the dependence is disproved,
/// it will return 0.
unsigned exploreDirections(unsigned Level,
CoefficientInfo *A,
CoefficientInfo *B,
BoundInfo *Bound,
const SmallBitVector &Loops,
unsigned &DepthExpanded,
const SCEV *Delta) const;
/// testBounds - Returns true iff the current bounds are plausible.
///
bool testBounds(unsigned char DirKind,
unsigned Level,
BoundInfo *Bound,
const SCEV *Delta) const;
/// findBoundsALL - Computes the upper and lower bounds for level K
/// using the * direction. Records them in Bound.
void findBoundsALL(CoefficientInfo *A,
CoefficientInfo *B,
BoundInfo *Bound,
unsigned K) const;
/// findBoundsLT - Computes the upper and lower bounds for level K
/// using the < direction. Records them in Bound.
void findBoundsLT(CoefficientInfo *A,
CoefficientInfo *B,
BoundInfo *Bound,
unsigned K) const;
/// findBoundsGT - Computes the upper and lower bounds for level K
/// using the > direction. Records them in Bound.
void findBoundsGT(CoefficientInfo *A,
CoefficientInfo *B,
BoundInfo *Bound,
unsigned K) const;
/// findBoundsEQ - Computes the upper and lower bounds for level K
/// using the = direction. Records them in Bound.
void findBoundsEQ(CoefficientInfo *A,
CoefficientInfo *B,
BoundInfo *Bound,
unsigned K) const;
/// intersectConstraints - Updates X with the intersection
/// of the Constraints X and Y. Returns true if X has changed.
bool intersectConstraints(Constraint *X,
const Constraint *Y);
/// propagate - Review the constraints, looking for opportunities
/// to simplify a subscript pair (Src and Dst).
/// Return true if some simplification occurs.
/// If the simplification isn't exact (that is, if it is conservative
/// in terms of dependence), set consistent to false.
bool propagate(const SCEV *&Src,
const SCEV *&Dst,
SmallBitVector &Loops,
SmallVector<Constraint, 4> &Constraints,
bool &Consistent);
/// propagateDistance - Attempt to propagate a distance
/// constraint into a subscript pair (Src and Dst).
/// Return true if some simplification occurs.
/// If the simplification isn't exact (that is, if it is conservative
/// in terms of dependence), set consistent to false.
bool propagateDistance(const SCEV *&Src,
const SCEV *&Dst,
Constraint &CurConstraint,
bool &Consistent);
/// propagatePoint - Attempt to propagate a point
/// constraint into a subscript pair (Src and Dst).
/// Return true if some simplification occurs.
bool propagatePoint(const SCEV *&Src,
const SCEV *&Dst,
Constraint &CurConstraint);
/// propagateLine - Attempt to propagate a line
/// constraint into a subscript pair (Src and Dst).
/// Return true if some simplification occurs.
/// If the simplification isn't exact (that is, if it is conservative
/// in terms of dependence), set consistent to false.
bool propagateLine(const SCEV *&Src,
const SCEV *&Dst,
Constraint &CurConstraint,
bool &Consistent);
/// findCoefficient - Given a linear SCEV,
/// return the coefficient corresponding to specified loop.
/// If there isn't one, return the SCEV constant 0.
/// For example, given a*i + b*j + c*k, returning the coefficient
/// corresponding to the j loop would yield b.
const SCEV *findCoefficient(const SCEV *Expr,
const Loop *TargetLoop) const;
/// zeroCoefficient - Given a linear SCEV,
/// return the SCEV given by zeroing out the coefficient
/// corresponding to the specified loop.
/// For example, given a*i + b*j + c*k, zeroing the coefficient
/// corresponding to the j loop would yield a*i + c*k.
const SCEV *zeroCoefficient(const SCEV *Expr,
const Loop *TargetLoop) const;
/// addToCoefficient - Given a linear SCEV Expr,
/// return the SCEV given by adding some Value to the
/// coefficient corresponding to the specified TargetLoop.
/// For example, given a*i + b*j + c*k, adding 1 to the coefficient
/// corresponding to the j loop would yield a*i + (b+1)*j + c*k.
const SCEV *addToCoefficient(const SCEV *Expr,
const Loop *TargetLoop,
const SCEV *Value) const;
/// updateDirection - Update direction vector entry
/// based on the current constraint.
void updateDirection(Dependence::DVEntry &Level,
const Constraint &CurConstraint) const;
public:
static char ID; // Class identification, replacement for typeinfo
DependenceAnalysis() : FunctionPass(ID) {
initializeDependenceAnalysisPass(*PassRegistry::getPassRegistry());
}
bool runOnFunction(Function &F);
void releaseMemory();
void getAnalysisUsage(AnalysisUsage &) const;
void print(raw_ostream &, const Module * = 0) const;
}; // class DependenceAnalysis
/// createDependenceAnalysisPass - This creates an instance of the
/// DependenceAnalysis pass.
FunctionPass *createDependenceAnalysisPass();
} // namespace llvm
#endif

View File

@ -346,7 +346,7 @@ class DominatorTreeBase : public DominatorBase<NodeT> {
DomTreeNodeBase<NodeT> *getRootNode() { return RootNode; }
const DomTreeNodeBase<NodeT> *getRootNode() const { return RootNode; }
/// properlyDominates - Returns true iff this dominates N and this != N.
/// properlyDominates - Returns true iff A dominates B and A != B.
/// Note that this is not a constant time operation!
///
bool properlyDominates(const DomTreeNodeBase<NodeT> *A,

View File

@ -28,7 +28,7 @@ class IVUsers;
class ScalarEvolution;
class SCEV;
class IVUsers;
class TargetData;
class DataLayout;
/// IVStrideUse - Keep track of one use of a strided induction variable.
/// The Expr member keeps track of the expression, User is the actual user
@ -123,7 +123,7 @@ class IVUsers : public LoopPass {
LoopInfo *LI;
DominatorTree *DT;
ScalarEvolution *SE;
TargetData *TD;
DataLayout *TD;
SmallPtrSet<Instruction*,16> Processed;
/// IVUses - A list of all tracked IV uses of induction variable expressions

View File

@ -26,7 +26,7 @@
namespace llvm {
class CallSite;
class TargetData;
class DataLayout;
namespace InlineConstants {
// Various magic constants used to adjust heuristics.
@ -36,6 +36,9 @@ namespace llvm {
const int LastCallToStaticBonus = -15000;
const int ColdccPenalty = 2000;
const int NoreturnPenalty = 10000;
/// Do not inline functions which allocate this many bytes on the stack
/// when the caller is recursive.
const unsigned TotalAllocaSizeRecursiveCaller = 1024;
}
/// \brief Represents the cost of inlining a function.
@ -101,13 +104,13 @@ namespace llvm {
/// InlineCostAnalyzer - Cost analyzer used by inliner.
class InlineCostAnalyzer {
// TargetData if available, or null.
const TargetData *TD;
// DataLayout if available, or null.
const DataLayout *TD;
public:
InlineCostAnalyzer(): TD(0) {}
void setTargetData(const TargetData *TData) { TD = TData; }
void setDataLayout(const DataLayout *TData) { TD = TData; }
/// \brief Get an InlineCost object representing the cost of inlining this
/// callsite.

View File

@ -24,7 +24,7 @@ namespace llvm {
class ArrayRef;
class DominatorTree;
class Instruction;
class TargetData;
class DataLayout;
class TargetLibraryInfo;
class Type;
class Value;
@ -32,122 +32,122 @@ namespace llvm {
/// SimplifyAddInst - Given operands for an Add, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyAddInst(Value *LHS, Value *RHS, bool isNSW, bool isNUW,
const TargetData *TD = 0,
const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifySubInst - Given operands for a Sub, see if we can
/// fold the result. If not, this returns null.
Value *SimplifySubInst(Value *LHS, Value *RHS, bool isNSW, bool isNUW,
const TargetData *TD = 0,
const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyMulInst - Given operands for a Mul, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyMulInst(Value *LHS, Value *RHS, const TargetData *TD = 0,
Value *SimplifyMulInst(Value *LHS, Value *RHS, const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifySDivInst - Given operands for an SDiv, see if we can
/// fold the result. If not, this returns null.
Value *SimplifySDivInst(Value *LHS, Value *RHS, const TargetData *TD = 0,
Value *SimplifySDivInst(Value *LHS, Value *RHS, const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyUDivInst - Given operands for a UDiv, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyUDivInst(Value *LHS, Value *RHS, const TargetData *TD = 0,
Value *SimplifyUDivInst(Value *LHS, Value *RHS, const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyFDivInst - Given operands for an FDiv, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyFDivInst(Value *LHS, Value *RHS, const TargetData *TD = 0,
Value *SimplifyFDivInst(Value *LHS, Value *RHS, const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifySRemInst - Given operands for an SRem, see if we can
/// fold the result. If not, this returns null.
Value *SimplifySRemInst(Value *LHS, Value *RHS, const TargetData *TD = 0,
Value *SimplifySRemInst(Value *LHS, Value *RHS, const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyURemInst - Given operands for a URem, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyURemInst(Value *LHS, Value *RHS, const TargetData *TD = 0,
Value *SimplifyURemInst(Value *LHS, Value *RHS, const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyFRemInst - Given operands for an FRem, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyFRemInst(Value *LHS, Value *RHS, const TargetData *TD = 0,
Value *SimplifyFRemInst(Value *LHS, Value *RHS, const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyShlInst - Given operands for a Shl, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyShlInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW,
const TargetData *TD = 0,
const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyLShrInst - Given operands for a LShr, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyLShrInst(Value *Op0, Value *Op1, bool isExact,
const TargetData *TD = 0,
const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyAShrInst - Given operands for a AShr, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyAShrInst(Value *Op0, Value *Op1, bool isExact,
const TargetData *TD = 0,
const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyAndInst - Given operands for an And, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyAndInst(Value *LHS, Value *RHS, const TargetData *TD = 0,
Value *SimplifyAndInst(Value *LHS, Value *RHS, const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyOrInst - Given operands for an Or, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyOrInst(Value *LHS, Value *RHS, const TargetData *TD = 0,
Value *SimplifyOrInst(Value *LHS, Value *RHS, const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyXorInst - Given operands for a Xor, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyXorInst(Value *LHS, Value *RHS, const TargetData *TD = 0,
Value *SimplifyXorInst(Value *LHS, Value *RHS, const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyICmpInst - Given operands for an ICmpInst, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
const TargetData *TD = 0,
const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyFCmpInst - Given operands for an FCmpInst, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
const TargetData *TD = 0,
const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifySelectInst - Given operands for a SelectInst, see if we can fold
/// the result. If not, this returns null.
Value *SimplifySelectInst(Value *Cond, Value *TrueVal, Value *FalseVal,
const TargetData *TD = 0,
const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyGEPInst - Given operands for an GetElementPtrInst, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyGEPInst(ArrayRef<Value *> Ops, const TargetData *TD = 0,
Value *SimplifyGEPInst(ArrayRef<Value *> Ops, const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
@ -155,13 +155,13 @@ namespace llvm {
/// can fold the result. If not, this returns null.
Value *SimplifyInsertValueInst(Value *Agg, Value *Val,
ArrayRef<unsigned> Idxs,
const TargetData *TD = 0,
const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyTruncInst - Given operands for an TruncInst, see if we can fold
/// the result. If not, this returns null.
Value *SimplifyTruncInst(Value *Op, Type *Ty, const TargetData *TD = 0,
Value *SimplifyTruncInst(Value *Op, Type *Ty, const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
@ -171,20 +171,20 @@ namespace llvm {
/// SimplifyCmpInst - Given operands for a CmpInst, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
const TargetData *TD = 0,
const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyBinOp - Given operands for a BinaryOperator, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS,
const TargetData *TD = 0,
const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyInstruction - See if we can compute a simplified version of this
/// instruction. If not, this returns null.
Value *SimplifyInstruction(Instruction *I, const TargetData *TD = 0,
Value *SimplifyInstruction(Instruction *I, const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
@ -198,7 +198,7 @@ namespace llvm {
///
/// The function returns true if any simplifications were performed.
bool replaceAndRecursivelySimplify(Instruction *I, Value *SimpleV,
const TargetData *TD = 0,
const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
@ -209,7 +209,7 @@ namespace llvm {
/// of the users impacted. It returns true if any simplifications were
/// performed.
bool recursivelySimplifyInstruction(Instruction *I,
const TargetData *TD = 0,
const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
} // end namespace llvm

View File

@ -33,8 +33,8 @@ namespace llvm {
//
// IntervalPartition - This class builds and holds an "interval partition" for
// a function. This partition divides the control flow graph into a set of
// maximal intervals, as defined with the properties above. Intuitively, a
// BasicBlock is a (possibly nonexistent) loop with a "tail" of non looping
// maximal intervals, as defined with the properties above. Intuitively, an
// interval is a (possibly nonexistent) loop with a "tail" of non looping
// nodes following it.
//
class IntervalPartition : public FunctionPass {

View File

@ -19,18 +19,18 @@
namespace llvm {
class Constant;
class TargetData;
class DataLayout;
class TargetLibraryInfo;
class Value;
/// LazyValueInfo - This pass computes, caches, and vends lazy value constraint
/// information.
class LazyValueInfo : public FunctionPass {
class TargetData *TD;
class DataLayout *TD;
class TargetLibraryInfo *TLI;
void *PImpl;
LazyValueInfo(const LazyValueInfo&); // DO NOT IMPLEMENT.
void operator=(const LazyValueInfo&); // DO NOT IMPLEMENT.
LazyValueInfo(const LazyValueInfo&) LLVM_DELETED_FUNCTION;
void operator=(const LazyValueInfo&) LLVM_DELETED_FUNCTION;
public:
static char ID;
LazyValueInfo() : FunctionPass(ID), PImpl(0) {

View File

@ -19,7 +19,7 @@
namespace llvm {
class AliasAnalysis;
class TargetData;
class DataLayout;
class MDNode;
/// isSafeToLoadUnconditionally - Return true if we know that executing a load
@ -27,7 +27,7 @@ class MDNode;
/// specified pointer, we do a quick local scan of the basic block containing
/// ScanFrom, to determine if the address is already accessed.
bool isSafeToLoadUnconditionally(Value *V, Instruction *ScanFrom,
unsigned Align, const TargetData *TD = 0);
unsigned Align, const DataLayout *TD = 0);
/// FindAvailableLoadedValue - Scan the ScanBB block backwards (starting at
/// the instruction before ScanFrom) checking to see if we have the value at

View File

@ -1,124 +0,0 @@
//===- llvm/Analysis/LoopDependenceAnalysis.h --------------- -*- C++ -*---===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// LoopDependenceAnalysis is an LLVM pass that analyses dependences in memory
// accesses in loops.
//
// Please note that this is work in progress and the interface is subject to
// change.
//
// TODO: adapt as interface progresses
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_LOOP_DEPENDENCE_ANALYSIS_H
#define LLVM_ANALYSIS_LOOP_DEPENDENCE_ANALYSIS_H
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Analysis/LoopPass.h"
#include "llvm/Support/Allocator.h"
namespace llvm {
class AliasAnalysis;
class AnalysisUsage;
class ScalarEvolution;
class SCEV;
class Value;
class raw_ostream;
class LoopDependenceAnalysis : public LoopPass {
AliasAnalysis *AA;
ScalarEvolution *SE;
/// L - The loop we are currently analysing.
Loop *L;
/// TODO: doc
enum DependenceResult { Independent = 0, Dependent = 1, Unknown = 2 };
/// TODO: doc
struct Subscript {
/// TODO: Add distance, direction, breaking conditions, ...
};
/// DependencePair - Represents a data dependence relation between to memory
/// reference instructions.
struct DependencePair : public FastFoldingSetNode {
Value *A;
Value *B;
DependenceResult Result;
SmallVector<Subscript, 4> Subscripts;
DependencePair(const FoldingSetNodeID &ID, Value *a, Value *b) :
FastFoldingSetNode(ID), A(a), B(b), Result(Unknown), Subscripts() {}
};
/// findOrInsertDependencePair - Return true if a DependencePair for the
/// given Values already exists, false if a new DependencePair had to be
/// created. The third argument is set to the pair found or created.
bool findOrInsertDependencePair(Value*, Value*, DependencePair*&);
/// getLoops - Collect all loops of the loop nest L in which
/// a given SCEV is variant.
void getLoops(const SCEV*, DenseSet<const Loop*>*) const;
/// isLoopInvariant - True if a given SCEV is invariant in all loops of the
/// loop nest starting at the innermost loop L.
bool isLoopInvariant(const SCEV*) const;
/// isAffine - An SCEV is affine with respect to the loop nest starting at
/// the innermost loop L if it is of the form A+B*X where A, B are invariant
/// in the loop nest and X is a induction variable in the loop nest.
bool isAffine(const SCEV*) const;
/// TODO: doc
bool isZIVPair(const SCEV*, const SCEV*) const;
bool isSIVPair(const SCEV*, const SCEV*) const;
DependenceResult analyseZIV(const SCEV*, const SCEV*, Subscript*) const;
DependenceResult analyseSIV(const SCEV*, const SCEV*, Subscript*) const;
DependenceResult analyseMIV(const SCEV*, const SCEV*, Subscript*) const;
DependenceResult analyseSubscript(const SCEV*, const SCEV*, Subscript*) const;
DependenceResult analysePair(DependencePair*) const;
public:
static char ID; // Class identification, replacement for typeinfo
LoopDependenceAnalysis() : LoopPass(ID) {
initializeLoopDependenceAnalysisPass(*PassRegistry::getPassRegistry());
}
/// isDependencePair - Check whether two values can possibly give rise to
/// a data dependence: that is the case if both are instructions accessing
/// memory and at least one of those accesses is a write.
bool isDependencePair(const Value*, const Value*) const;
/// depends - Return a boolean indicating if there is a data dependence
/// between two instructions.
bool depends(Value*, Value*);
bool runOnLoop(Loop*, LPPassManager&);
virtual void releaseMemory();
virtual void getAnalysisUsage(AnalysisUsage&) const;
void print(raw_ostream&, const Module* = 0) const;
private:
FoldingSet<DependencePair> Pairs;
BumpPtrAllocator PairAllocator;
}; // class LoopDependenceAnalysis
// createLoopDependenceAnalysisPass - This creates an instance of the
// LoopDependenceAnalysis pass.
//
LoopPass *createLoopDependenceAnalysisPass();
} // namespace llvm
#endif /* LLVM_ANALYSIS_LOOP_DEPENDENCE_ANALYSIS_H */

View File

@ -72,10 +72,9 @@ class LoopBase {
// Blocks - The list of blocks in this loop. First entry is the header node.
std::vector<BlockT*> Blocks;
// DO NOT IMPLEMENT
LoopBase(const LoopBase<BlockT, LoopT> &);
// DO NOT IMPLEMENT
const LoopBase<BlockT, LoopT>&operator=(const LoopBase<BlockT, LoopT> &);
LoopBase(const LoopBase<BlockT, LoopT> &) LLVM_DELETED_FUNCTION;
const LoopBase<BlockT, LoopT>&
operator=(const LoopBase<BlockT, LoopT> &) LLVM_DELETED_FUNCTION;
public:
/// Loop ctor - This creates an empty loop.
LoopBase() : ParentLoop(0) {}
@ -416,8 +415,8 @@ class LoopInfoBase {
friend class LoopBase<BlockT, LoopT>;
friend class LoopInfo;
void operator=(const LoopInfoBase &); // do not implement
LoopInfoBase(const LoopInfo &); // do not implement
void operator=(const LoopInfoBase &) LLVM_DELETED_FUNCTION;
LoopInfoBase(const LoopInfo &) LLVM_DELETED_FUNCTION;
public:
LoopInfoBase() { }
~LoopInfoBase() { releaseMemory(); }
@ -550,8 +549,8 @@ class LoopInfo : public FunctionPass {
LoopInfoBase<BasicBlock, Loop> LI;
friend class LoopBase<BasicBlock, Loop>;
void operator=(const LoopInfo &); // do not implement
LoopInfo(const LoopInfo &); // do not implement
void operator=(const LoopInfo &) LLVM_DELETED_FUNCTION;
LoopInfo(const LoopInfo &) LLVM_DELETED_FUNCTION;
public:
static char ID; // Pass identification, replacement for typeid

View File

@ -145,7 +145,6 @@ BlockT *LoopBase<BlockT, LoopT>::getLoopPredecessor() const {
// Loop over the predecessors of the header node...
BlockT *Header = getHeader();
typedef GraphTraits<BlockT*> BlockTraits;
typedef GraphTraits<Inverse<BlockT*> > InvBlockTraits;
for (typename InvBlockTraits::ChildIteratorType PI =
InvBlockTraits::child_begin(Header),

View File

@ -27,7 +27,8 @@
namespace llvm {
class CallInst;
class PointerType;
class TargetData;
class DataLayout;
class TargetLibraryInfo;
class Type;
class Value;
@ -35,27 +36,33 @@ class Value;
/// \brief Tests if a value is a call or invoke to a library function that
/// allocates or reallocates memory (either malloc, calloc, realloc, or strdup
/// like).
bool isAllocationFn(const Value *V, bool LookThroughBitCast = false);
bool isAllocationFn(const Value *V, const TargetLibraryInfo *TLI,
bool LookThroughBitCast = false);
/// \brief Tests if a value is a call or invoke to a function that returns a
/// NoAlias pointer (including malloc/calloc/realloc/strdup-like functions).
bool isNoAliasFn(const Value *V, bool LookThroughBitCast = false);
bool isNoAliasFn(const Value *V, const TargetLibraryInfo *TLI,
bool LookThroughBitCast = false);
/// \brief Tests if a value is a call or invoke to a library function that
/// allocates uninitialized memory (such as malloc).
bool isMallocLikeFn(const Value *V, bool LookThroughBitCast = false);
bool isMallocLikeFn(const Value *V, const TargetLibraryInfo *TLI,
bool LookThroughBitCast = false);
/// \brief Tests if a value is a call or invoke to a library function that
/// allocates zero-filled memory (such as calloc).
bool isCallocLikeFn(const Value *V, bool LookThroughBitCast = false);
bool isCallocLikeFn(const Value *V, const TargetLibraryInfo *TLI,
bool LookThroughBitCast = false);
/// \brief Tests if a value is a call or invoke to a library function that
/// allocates memory (either malloc, calloc, or strdup like).
bool isAllocLikeFn(const Value *V, bool LookThroughBitCast = false);
bool isAllocLikeFn(const Value *V, const TargetLibraryInfo *TLI,
bool LookThroughBitCast = false);
/// \brief Tests if a value is a call or invoke to a library function that
/// reallocates memory (such as realloc).
bool isReallocLikeFn(const Value *V, bool LookThroughBitCast = false);
bool isReallocLikeFn(const Value *V, const TargetLibraryInfo *TLI,
bool LookThroughBitCast = false);
//===----------------------------------------------------------------------===//
@ -65,36 +72,39 @@ bool isReallocLikeFn(const Value *V, bool LookThroughBitCast = false);
/// extractMallocCall - Returns the corresponding CallInst if the instruction
/// is a malloc call. Since CallInst::CreateMalloc() only creates calls, we
/// ignore InvokeInst here.
const CallInst *extractMallocCall(const Value *I);
static inline CallInst *extractMallocCall(Value *I) {
return const_cast<CallInst*>(extractMallocCall((const Value*)I));
const CallInst *extractMallocCall(const Value *I, const TargetLibraryInfo *TLI);
static inline CallInst *extractMallocCall(Value *I,
const TargetLibraryInfo *TLI) {
return const_cast<CallInst*>(extractMallocCall((const Value*)I, TLI));
}
/// isArrayMalloc - Returns the corresponding CallInst if the instruction
/// is a call to malloc whose array size can be determined and the array size
/// is not constant 1. Otherwise, return NULL.
const CallInst *isArrayMalloc(const Value *I, const TargetData *TD);
const CallInst *isArrayMalloc(const Value *I, const DataLayout *TD,
const TargetLibraryInfo *TLI);
/// getMallocType - Returns the PointerType resulting from the malloc call.
/// The PointerType depends on the number of bitcast uses of the malloc call:
/// 0: PointerType is the malloc calls' return type.
/// 1: PointerType is the bitcast's result type.
/// >1: Unique PointerType cannot be determined, return NULL.
PointerType *getMallocType(const CallInst *CI);
PointerType *getMallocType(const CallInst *CI, const TargetLibraryInfo *TLI);
/// getMallocAllocatedType - Returns the Type allocated by malloc call.
/// The Type depends on the number of bitcast uses of the malloc call:
/// 0: PointerType is the malloc calls' return type.
/// 1: PointerType is the bitcast's result type.
/// >1: Unique PointerType cannot be determined, return NULL.
Type *getMallocAllocatedType(const CallInst *CI);
Type *getMallocAllocatedType(const CallInst *CI, const TargetLibraryInfo *TLI);
/// getMallocArraySize - Returns the array size of a malloc call. If the
/// argument passed to malloc is a multiple of the size of the malloced type,
/// then return that multiple. For non-array mallocs, the multiple is
/// constant 1. Otherwise, return NULL for mallocs whose array size cannot be
/// determined.
Value *getMallocArraySize(CallInst *CI, const TargetData *TD,
Value *getMallocArraySize(CallInst *CI, const DataLayout *TD,
const TargetLibraryInfo *TLI,
bool LookThroughSExt = false);
@ -104,9 +114,10 @@ Value *getMallocArraySize(CallInst *CI, const TargetData *TD,
/// extractCallocCall - Returns the corresponding CallInst if the instruction
/// is a calloc call.
const CallInst *extractCallocCall(const Value *I);
static inline CallInst *extractCallocCall(Value *I) {
return const_cast<CallInst*>(extractCallocCall((const Value*)I));
const CallInst *extractCallocCall(const Value *I, const TargetLibraryInfo *TLI);
static inline CallInst *extractCallocCall(Value *I,
const TargetLibraryInfo *TLI) {
return const_cast<CallInst*>(extractCallocCall((const Value*)I, TLI));
}
@ -115,10 +126,10 @@ static inline CallInst *extractCallocCall(Value *I) {
//
/// isFreeCall - Returns non-null if the value is a call to the builtin free()
const CallInst *isFreeCall(const Value *I);
const CallInst *isFreeCall(const Value *I, const TargetLibraryInfo *TLI);
static inline CallInst *isFreeCall(Value *I) {
return const_cast<CallInst*>(isFreeCall((const Value*)I));
static inline CallInst *isFreeCall(Value *I, const TargetLibraryInfo *TLI) {
return const_cast<CallInst*>(isFreeCall((const Value*)I, TLI));
}
@ -130,8 +141,8 @@ static inline CallInst *isFreeCall(Value *I) {
/// object size in Size if successful, and false otherwise.
/// If RoundToAlign is true, then Size is rounded up to the aligment of allocas,
/// byval arguments, and global variables.
bool getObjectSize(const Value *Ptr, uint64_t &Size, const TargetData *TD,
bool RoundToAlign = false);
bool getObjectSize(const Value *Ptr, uint64_t &Size, const DataLayout *TD,
const TargetLibraryInfo *TLI, bool RoundToAlign = false);
@ -142,10 +153,12 @@ typedef std::pair<APInt, APInt> SizeOffsetType;
class ObjectSizeOffsetVisitor
: public InstVisitor<ObjectSizeOffsetVisitor, SizeOffsetType> {
const TargetData *TD;
const DataLayout *TD;
const TargetLibraryInfo *TLI;
bool RoundToAlign;
unsigned IntTyBits;
APInt Zero;
SmallPtrSet<Instruction *, 8> SeenInsts;
APInt align(APInt Size, uint64_t Align);
@ -154,8 +167,8 @@ class ObjectSizeOffsetVisitor
}
public:
ObjectSizeOffsetVisitor(const TargetData *TD, LLVMContext &Context,
bool RoundToAlign = false);
ObjectSizeOffsetVisitor(const DataLayout *TD, const TargetLibraryInfo *TLI,
LLVMContext &Context, bool RoundToAlign = false);
SizeOffsetType compute(Value *V);
@ -200,10 +213,10 @@ class ObjectSizeOffsetEvaluator
typedef DenseMap<const Value*, WeakEvalType> CacheMapTy;
typedef SmallPtrSet<const Value*, 8> PtrSetTy;
const TargetData *TD;
const DataLayout *TD;
const TargetLibraryInfo *TLI;
LLVMContext &Context;
BuilderTy Builder;
ObjectSizeOffsetVisitor Visitor;
IntegerType *IntTy;
Value *Zero;
CacheMapTy CacheMap;
@ -215,7 +228,8 @@ class ObjectSizeOffsetEvaluator
SizeOffsetEvalType compute_(Value *V);
public:
ObjectSizeOffsetEvaluator(const TargetData *TD, LLVMContext &Context);
ObjectSizeOffsetEvaluator(const DataLayout *TD, const TargetLibraryInfo *TLI,
LLVMContext &Context);
SizeOffsetEvalType compute(Value *V);
bool knownSize(SizeOffsetEvalType SizeOffset) {

View File

@ -29,7 +29,7 @@ namespace llvm {
class Instruction;
class CallSite;
class AliasAnalysis;
class TargetData;
class DataLayout;
class MemoryDependenceAnalysis;
class PredIteratorCache;
class DominatorTree;
@ -323,7 +323,7 @@ namespace llvm {
/// Current AA implementation, just a cache.
AliasAnalysis *AA;
TargetData *TD;
DataLayout *TD;
DominatorTree *DT;
OwningPtr<PredIteratorCache> PredCache;
public:
@ -412,7 +412,7 @@ namespace llvm {
int64_t MemLocOffs,
unsigned MemLocSize,
const LoadInst *LI,
const TargetData &TD);
const DataLayout &TD);
private:
MemDepResult getCallSiteDependencyFrom(CallSite C, bool isReadOnlyCall,

View File

@ -19,7 +19,7 @@
namespace llvm {
class DominatorTree;
class TargetData;
class DataLayout;
class TargetLibraryInfo;
/// PHITransAddr - An address value which tracks and handles phi translation.
@ -37,7 +37,7 @@ class PHITransAddr {
Value *Addr;
/// TD - The target data we are playing with if known, otherwise null.
const TargetData *TD;
const DataLayout *TD;
/// TLI - The target library info if known, otherwise null.
const TargetLibraryInfo *TLI;
@ -45,7 +45,7 @@ class PHITransAddr {
/// InstInputs - The inputs for our symbolic address.
SmallVector<Instruction*, 4> InstInputs;
public:
PHITransAddr(Value *addr, const TargetData *td) : Addr(addr), TD(td), TLI(0) {
PHITransAddr(Value *addr, const DataLayout *td) : Addr(addr), TD(td), TLI(0) {
// If the address is an instruction, the whole thing is considered an input.
if (Instruction *I = dyn_cast<Instruction>(Addr))
InstInputs.push_back(I);

View File

@ -101,6 +101,14 @@ namespace llvm {
ModulePass *createProfileLoaderPass();
extern char &ProfileLoaderPassID;
//===--------------------------------------------------------------------===//
//
// createProfileMetadataLoaderPass - This pass loads information from a
// profile dump file and sets branch weight metadata.
//
ModulePass *createProfileMetadataLoaderPass();
extern char &ProfileMetadataLoaderPassID;
//===--------------------------------------------------------------------===//
//
// createNoProfileInfoPass - This pass implements the default "no profile".
@ -172,11 +180,20 @@ namespace llvm {
//===--------------------------------------------------------------------===//
//
// createLoopDependenceAnalysisPass - This creates an instance of the
// LoopDependenceAnalysis pass.
// createDependenceAnalysisPass - This creates an instance of the
// DependenceAnalysis pass.
//
LoopPass *createLoopDependenceAnalysisPass();
FunctionPass *createDependenceAnalysisPass();
//===--------------------------------------------------------------------===//
//
// createCostModelAnalysisPass - This creates an instance of the
// CostModelAnalysis pass.
//
FunctionPass *createCostModelAnalysisPass();
//===--------------------------------------------------------------------===//
//
// Minor pass prototypes, allowing us to expose them through bugpoint and
// analyze.
FunctionPass *createInstCountPass();

View File

@ -0,0 +1,139 @@
//===- ProfileDataLoader.h - Load & convert profile info ----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// The ProfileDataLoader class is used to load profiling data from a dump file.
// The ProfileDataT<FType, BType> class is used to store the mapping of this
// data to control flow edges.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_PROFILEDATALOADER_H
#define LLVM_ANALYSIS_PROFILEDATALOADER_H
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include <string>
namespace llvm {
class ModulePass;
class Function;
class BasicBlock;
// Helper for dumping edges to dbgs().
raw_ostream& operator<<(raw_ostream &O, std::pair<const BasicBlock *,
const BasicBlock *> E);
/// \brief The ProfileDataT<FType, BType> class is used to store the mapping of
/// profiling data to control flow edges.
///
/// An edge is defined by its source and sink basic blocks.
template<class FType, class BType>
class ProfileDataT {
public:
// The profiling information defines an Edge by its source and sink basic
// blocks.
typedef std::pair<const BType*, const BType*> Edge;
private:
typedef DenseMap<Edge, unsigned> EdgeWeights;
/// \brief Count the number of times a transition between two blocks is
/// executed.
///
/// As a special case, we also hold an edge from the null BasicBlock to the
/// entry block to indicate how many times the function was entered.
DenseMap<const FType*, EdgeWeights> EdgeInformation;
public:
/// getFunction() - Returns the Function for an Edge.
static const FType *getFunction(Edge e) {
// e.first may be NULL
assert(((!e.first) || (e.first->getParent() == e.second->getParent()))
&& "A ProfileData::Edge can not be between two functions");
assert(e.second && "A ProfileData::Edge must have a real sink");
return e.second->getParent();
}
/// getEdge() - Creates an Edge between two BasicBlocks.
static Edge getEdge(const BType *Src, const BType *Dest) {
return Edge(Src, Dest);
}
/// getEdgeWeight - Return the number of times that a given edge was
/// executed.
unsigned getEdgeWeight(Edge e) const {
const FType *f = getFunction(e);
assert((EdgeInformation.find(f) != EdgeInformation.end())
&& "No profiling information for function");
EdgeWeights weights = EdgeInformation.find(f)->second;
assert((weights.find(e) != weights.end())
&& "No profiling information for edge");
return weights.find(e)->second;
}
/// addEdgeWeight - Add 'weight' to the already stored execution count for
/// this edge.
void addEdgeWeight(Edge e, unsigned weight) {
EdgeInformation[getFunction(e)][e] += weight;
}
};
typedef ProfileDataT<Function, BasicBlock> ProfileData;
//typedef ProfileDataT<MachineFunction, MachineBasicBlock> MachineProfileData;
/// The ProfileDataLoader class is used to load raw profiling data from the
/// dump file.
class ProfileDataLoader {
private:
/// The name of the file where the raw profiling data is stored.
const std::string &Filename;
/// A vector of the command line arguments used when the target program was
/// run to generate profiling data. One entry per program run.
SmallVector<std::string, 1> CommandLines;
/// The raw values for how many times each edge was traversed, values from
/// multiple program runs are accumulated.
SmallVector<unsigned, 32> EdgeCounts;
public:
/// ProfileDataLoader ctor - Read the specified profiling data file, exiting
/// the program if the file is invalid or broken.
ProfileDataLoader(const char *ToolName, const std::string &Filename);
/// A special value used to represent the weight of an edge which has not
/// been counted yet.
static const unsigned Uncounted;
/// getNumExecutions - Return the number of times the target program was run
/// to generate this profiling data.
unsigned getNumExecutions() const { return CommandLines.size(); }
/// getExecution - Return the command line parameters used to generate the
/// i'th set of profiling data.
const std::string &getExecution(unsigned i) const { return CommandLines[i]; }
const std::string &getFileName() const { return Filename; }
/// getRawEdgeCounts - Return the raw profiling data, this is just a list of
/// numbers with no mappings to edges.
ArrayRef<unsigned> getRawEdgeCounts() const { return EdgeCounts; }
};
/// createProfileMetadataLoaderPass - This function returns a Pass that loads
/// the profiling information for the module from the specified filename.
ModulePass *createProfileMetadataLoaderPass(const std::string &Filename);
} // End llvm namespace
#endif

View File

@ -0,0 +1,39 @@
/*===-- ProfileDataTypes.h - Profiling info shared constants --------------===*\
|*
|* The LLVM Compiler Infrastructure
|*
|* This file is distributed under the University of Illinois Open Source
|* License. See LICENSE.TXT for details.
|*
|*===----------------------------------------------------------------------===*|
|*
|* This file defines constants shared by the various different profiling
|* runtime libraries and the LLVM C++ profile metadata loader. It must be a
|* C header because, at present, the profiling runtimes are written in C.
|*
\*===----------------------------------------------------------------------===*/
#ifndef LLVM_ANALYSIS_PROFILEDATATYPES_H
#define LLVM_ANALYSIS_PROFILEDATATYPES_H
/* Included by libprofile. */
#if defined(__cplusplus)
extern "C" {
#endif
/* TODO: Strip out unused entries once ProfileInfo etc has been removed. */
enum ProfilingType {
ArgumentInfo = 1, /* The command line argument block */
FunctionInfo = 2, /* Function profiling information */
BlockInfo = 3, /* Block profiling information */
EdgeInfo = 4, /* Edge profiling information */
PathInfo = 5, /* Path profiling information */
BBTraceInfo = 6, /* Basic block trace information */
OptEdgeInfo = 7 /* Edge profiling information, optimal version */
};
#if defined(__cplusplus)
}
#endif
#endif /* LLVM_ANALYSIS_PROFILEDATATYPES_H */

View File

@ -27,15 +27,7 @@ enum ProfilingStorageType {
ProfilingHash = 2
};
enum ProfilingType {
ArgumentInfo = 1, /* The command line argument block */
FunctionInfo = 2, /* Function profiling information */
BlockInfo = 3, /* Block profiling information */
EdgeInfo = 4, /* Edge profiling information */
PathInfo = 5, /* Path profiling information */
BBTraceInfo = 6, /* Basic block trace information */
OptEdgeInfo = 7 /* Edge profiling information, optimal version */
};
#include "llvm/Analysis/ProfileDataTypes.h"
/*
* The header for tables that map path numbers to path counters.

View File

@ -54,10 +54,8 @@ 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 &);
RegionNode(const RegionNode &) LLVM_DELETED_FUNCTION;
const RegionNode &operator=(const RegionNode &) LLVM_DELETED_FUNCTION;
protected:
/// This is the entry basic block that starts this region node. If this is a
@ -203,10 +201,8 @@ inline Region* RegionNode::getNodeAs<Region>() const {
/// 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 &);
Region(const Region &) LLVM_DELETED_FUNCTION;
const Region &operator=(const Region &) LLVM_DELETED_FUNCTION;
// Information necessary to manage this Region.
RegionInfo* RI;
@ -473,27 +469,6 @@ class Region : public RegionNode {
const_iterator end() const { return children.end(); }
//@}
/// @name BasicBlock Node Iterators
///
/// These iterators iterate over all BasicBlock RegionNodes that are
/// contained in this Region. The iterator also iterates over BasicBlock
/// RegionNodes 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_node_iterator;
typedef df_iterator<const RegionNode*, SmallPtrSet<const RegionNode*, 8>,
false, GraphTraits<FlatIt<const RegionNode*> > >
const_block_node_iterator;
block_node_iterator block_node_begin();
block_node_iterator block_node_end();
const_block_node_iterator block_node_begin() const;
const_block_node_iterator block_node_end() const;
//@}
/// @name BasicBlock Iterators
///
/// These iterators iterate over all BasicBlocks that are contained in this
@ -586,10 +561,8 @@ class RegionInfo : public FunctionPass {
typedef DenseMap<BasicBlock*, Region*> BBtoRegionMap;
typedef SmallPtrSet<Region*, 4> RegionSet;
// DO NOT IMPLEMENT
RegionInfo(const RegionInfo &);
// DO NOT IMPLEMENT
const RegionInfo &operator=(const RegionInfo &);
RegionInfo(const RegionInfo &) LLVM_DELETED_FUNCTION;
const RegionInfo &operator=(const RegionInfo &) LLVM_DELETED_FUNCTION;
DominatorTree *DT;
PostDominatorTree *PDT;

View File

@ -40,7 +40,7 @@ namespace llvm {
class DominatorTree;
class Type;
class ScalarEvolution;
class TargetData;
class DataLayout;
class TargetLibraryInfo;
class LLVMContext;
class Loop;
@ -70,8 +70,8 @@ namespace llvm {
unsigned short SubclassData;
private:
SCEV(const SCEV &); // DO NOT IMPLEMENT
void operator=(const SCEV &); // DO NOT IMPLEMENT
SCEV(const SCEV &) LLVM_DELETED_FUNCTION;
void operator=(const SCEV &) LLVM_DELETED_FUNCTION;
public:
/// NoWrapFlags are bitfield indices into SubclassData.
@ -162,7 +162,6 @@ namespace llvm {
SCEVCouldNotCompute();
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const SCEVCouldNotCompute *S) { return true; }
static bool classof(const SCEV *S);
};
@ -227,7 +226,7 @@ namespace llvm {
/// TD - The target data information for the target we are targeting.
///
TargetData *TD;
DataLayout *TD;
/// TLI - The target library information for the target we are targeting.
///
@ -874,6 +873,7 @@ namespace llvm {
virtual void releaseMemory();
virtual void getAnalysisUsage(AnalysisUsage &AU) const;
virtual void print(raw_ostream &OS, const Module* = 0) const;
virtual void verifyAnalysis() const;
private:
FoldingSet<SCEV> UniqueSCEVs;

View File

@ -46,7 +46,6 @@ namespace llvm {
Type *getType() const { return V->getType(); }
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const SCEVConstant *S) { return true; }
static inline bool classof(const SCEV *S) {
return S->getSCEVType() == scConstant;
}
@ -68,7 +67,6 @@ namespace llvm {
Type *getType() const { return Ty; }
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const SCEVCastExpr *S) { return true; }
static inline bool classof(const SCEV *S) {
return S->getSCEVType() == scTruncate ||
S->getSCEVType() == scZeroExtend ||
@ -88,7 +86,6 @@ namespace llvm {
public:
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const SCEVTruncateExpr *S) { return true; }
static inline bool classof(const SCEV *S) {
return S->getSCEVType() == scTruncate;
}
@ -106,7 +103,6 @@ namespace llvm {
public:
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const SCEVZeroExtendExpr *S) { return true; }
static inline bool classof(const SCEV *S) {
return S->getSCEVType() == scZeroExtend;
}
@ -124,7 +120,6 @@ namespace llvm {
public:
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const SCEVSignExtendExpr *S) { return true; }
static inline bool classof(const SCEV *S) {
return S->getSCEVType() == scSignExtend;
}
@ -166,7 +161,6 @@ namespace llvm {
}
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const SCEVNAryExpr *S) { return true; }
static inline bool classof(const SCEV *S) {
return S->getSCEVType() == scAddExpr ||
S->getSCEVType() == scMulExpr ||
@ -188,7 +182,6 @@ namespace llvm {
public:
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const SCEVCommutativeExpr *S) { return true; }
static inline bool classof(const SCEV *S) {
return S->getSCEVType() == scAddExpr ||
S->getSCEVType() == scMulExpr ||
@ -223,7 +216,6 @@ namespace llvm {
}
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const SCEVAddExpr *S) { return true; }
static inline bool classof(const SCEV *S) {
return S->getSCEVType() == scAddExpr;
}
@ -242,7 +234,6 @@ namespace llvm {
public:
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const SCEVMulExpr *S) { return true; }
static inline bool classof(const SCEV *S) {
return S->getSCEVType() == scMulExpr;
}
@ -274,7 +265,6 @@ namespace llvm {
}
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const SCEVUDivExpr *S) { return true; }
static inline bool classof(const SCEV *S) {
return S->getSCEVType() == scUDivExpr;
}
@ -358,7 +348,6 @@ namespace llvm {
}
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const SCEVAddRecExpr *S) { return true; }
static inline bool classof(const SCEV *S) {
return S->getSCEVType() == scAddRecExpr;
}
@ -380,7 +369,6 @@ namespace llvm {
public:
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const SCEVSMaxExpr *S) { return true; }
static inline bool classof(const SCEV *S) {
return S->getSCEVType() == scSMaxExpr;
}
@ -402,7 +390,6 @@ namespace llvm {
public:
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const SCEVUMaxExpr *S) { return true; }
static inline bool classof(const SCEV *S) {
return S->getSCEVType() == scUMaxExpr;
}
@ -449,7 +436,6 @@ namespace llvm {
Type *getType() const { return getValPtr()->getType(); }
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const SCEVUnknown *S) { return true; }
static inline bool classof(const SCEV *S) {
return S->getSCEVType() == scUnknown;
}

View File

@ -130,9 +130,9 @@ class SparseSolver {
/// PHI nodes retriggered.
typedef std::pair<BasicBlock*,BasicBlock*> Edge;
std::set<Edge> KnownFeasibleEdges;
SparseSolver(const SparseSolver&); // DO NOT IMPLEMENT
void operator=(const SparseSolver&); // DO NOT IMPLEMENT
SparseSolver(const SparseSolver&) LLVM_DELETED_FUNCTION;
void operator=(const SparseSolver&) LLVM_DELETED_FUNCTION;
public:
explicit SparseSolver(AbstractLatticeFunction *Lattice)
: LatticeFunc(Lattice) {}

View File

@ -22,7 +22,7 @@ namespace llvm {
class Value;
class Instruction;
class APInt;
class TargetData;
class DataLayout;
class StringRef;
class MDNode;
@ -37,27 +37,27 @@ namespace llvm {
/// same width as the vector element, and the bit is set only if it is true
/// for all of the elements in the vector.
void ComputeMaskedBits(Value *V, APInt &KnownZero, APInt &KnownOne,
const TargetData *TD = 0, unsigned Depth = 0);
const DataLayout *TD = 0, unsigned Depth = 0);
void computeMaskedBitsLoad(const MDNode &Ranges, APInt &KnownZero);
/// ComputeSignBit - Determine whether the sign bit is known to be zero or
/// one. Convenience wrapper around ComputeMaskedBits.
void ComputeSignBit(Value *V, bool &KnownZero, bool &KnownOne,
const TargetData *TD = 0, unsigned Depth = 0);
const DataLayout *TD = 0, unsigned Depth = 0);
/// isPowerOfTwo - Return true if the given value is known to have exactly one
/// bit set when defined. For vectors return true if every element is known to
/// be a power of two when defined. Supports values with integer or pointer
/// type and vectors of integers. If 'OrZero' is set then returns true if the
/// given value is either a power of two or zero.
bool isPowerOfTwo(Value *V, const TargetData *TD = 0, bool OrZero = false,
bool isPowerOfTwo(Value *V, const DataLayout *TD = 0, bool OrZero = false,
unsigned Depth = 0);
/// isKnownNonZero - Return true if the given value is known to be non-zero
/// when defined. For vectors return true if every element is known to be
/// non-zero when defined. Supports values with integer or pointer type and
/// vectors of integers.
bool isKnownNonZero(Value *V, const TargetData *TD = 0, unsigned Depth = 0);
bool isKnownNonZero(Value *V, const DataLayout *TD = 0, unsigned Depth = 0);
/// MaskedValueIsZero - Return true if 'V & Mask' is known to be zero. We use
/// this predicate to simplify operations downstream. Mask is known to be
@ -69,7 +69,7 @@ namespace llvm {
/// same width as the vector element, and the bit is set only if it is true
/// for all of the elements in the vector.
bool MaskedValueIsZero(Value *V, const APInt &Mask,
const TargetData *TD = 0, unsigned Depth = 0);
const DataLayout *TD = 0, unsigned Depth = 0);
/// ComputeNumSignBits - Return the number of times the sign bit of the
@ -80,7 +80,7 @@ namespace llvm {
///
/// 'Op' must have a scalar integer type.
///
unsigned ComputeNumSignBits(Value *Op, const TargetData *TD = 0,
unsigned ComputeNumSignBits(Value *Op, const DataLayout *TD = 0,
unsigned Depth = 0);
/// ComputeMultiple - This function computes the integer multiple of Base that
@ -118,10 +118,10 @@ namespace llvm {
/// it can be expressed as a base pointer plus a constant offset. Return the
/// base and offset to the caller.
Value *GetPointerBaseWithConstantOffset(Value *Ptr, int64_t &Offset,
const TargetData &TD);
const DataLayout &TD);
static inline const Value *
GetPointerBaseWithConstantOffset(const Value *Ptr, int64_t &Offset,
const TargetData &TD) {
const DataLayout &TD) {
return GetPointerBaseWithConstantOffset(const_cast<Value*>(Ptr), Offset,TD);
}
@ -143,10 +143,10 @@ namespace llvm {
/// being addressed. Note that the returned value has pointer type if the
/// specified value does. If the MaxLookup value is non-zero, it limits the
/// number of instructions to be stripped off.
Value *GetUnderlyingObject(Value *V, const TargetData *TD = 0,
Value *GetUnderlyingObject(Value *V, const DataLayout *TD = 0,
unsigned MaxLookup = 6);
static inline const Value *
GetUnderlyingObject(const Value *V, const TargetData *TD = 0,
GetUnderlyingObject(const Value *V, const DataLayout *TD = 0,
unsigned MaxLookup = 6) {
return GetUnderlyingObject(const_cast<Value *>(V), TD, MaxLookup);
}
@ -156,7 +156,7 @@ namespace llvm {
/// multiple objects.
void GetUnderlyingObjects(Value *V,
SmallVectorImpl<Value *> &Objects,
const TargetData *TD = 0,
const DataLayout *TD = 0,
unsigned MaxLookup = 6);
/// onlyUsedByLifetimeMarkers - Return true if the only users of this pointer
@ -182,7 +182,7 @@ namespace llvm {
/// However, this method can return true for instructions that read memory;
/// for such instructions, moving them may change the resulting value.
bool isSafeToSpeculativelyExecute(const Value *V,
const TargetData *TD = 0);
const DataLayout *TD = 0);
} // end namespace llvm

View File

@ -68,8 +68,8 @@ class Argument : public Value, public ilist_node<Argument> {
/// attribute on it in its containing function.
bool hasNoCaptureAttr() const;
/// hasSRetAttr - Return true if this argument has the sret attribute on it in
/// its containing function.
/// hasStructRetAttr - Return true if this argument has the sret attribute on
/// it in its containing function.
bool hasStructRetAttr() const;
/// addAttr - Add a Attribute to an argument
@ -81,7 +81,6 @@ class Argument : public Value, public ilist_node<Argument> {
/// classof - Methods for support type inquiry through isa, cast, and
/// dyn_cast:
///
static inline bool classof(const Argument *) { return true; }
static inline bool classof(const Value *V) {
return V->getValueID() == ArgumentVal;
}

View File

@ -21,268 +21,280 @@
#include <string>
namespace llvm {
class AttrBuilder;
class AttributesImpl;
class LLVMContext;
class Type;
namespace Attribute {
/// We use this proxy POD type to allow constructing Attributes constants
/// using initializer lists. Do not use this class directly.
struct AttrConst {
uint64_t v;
AttrConst operator | (const AttrConst Attrs) const {
AttrConst Res = {v | Attrs.v};
return Res;
}
AttrConst operator ~ () const {
AttrConst Res = {~v};
return Res;
}
};
} // namespace Attribute
/// Attributes - A bitset of attributes.
class Attributes {
public:
Attributes() : Bits(0) { }
explicit Attributes(uint64_t Val) : Bits(Val) { }
/*implicit*/ Attributes(Attribute::AttrConst Val) : Bits(Val.v) { }
// This is a "safe bool() operator".
operator const void *() const { return Bits ? this : 0; }
bool isEmptyOrSingleton() const { return (Bits & (Bits - 1)) == 0; }
bool operator == (const Attributes &Attrs) const {
return Bits == Attrs.Bits;
}
bool operator != (const Attributes &Attrs) const {
return Bits != Attrs.Bits;
}
Attributes operator | (const Attributes &Attrs) const {
return Attributes(Bits | Attrs.Bits);
}
Attributes operator & (const Attributes &Attrs) const {
return Attributes(Bits & Attrs.Bits);
}
Attributes operator ^ (const Attributes &Attrs) const {
return Attributes(Bits ^ Attrs.Bits);
}
Attributes &operator |= (const Attributes &Attrs) {
Bits |= Attrs.Bits;
public:
/// Function parameters and results can have attributes to indicate how they
/// should be treated by optimizations and code generation. This enumeration
/// lists the attributes that can be associated with parameters, function
/// results or the function itself.
///
/// Note that uwtable is about the ABI or the user mandating an entry in the
/// unwind table. The nounwind attribute is about an exception passing by the
/// function.
///
/// In a theoretical system that uses tables for profiling and sjlj for
/// exceptions, they would be fully independent. In a normal system that uses
/// tables for both, the semantics are:
///
/// nil = Needs an entry because an exception might pass by.
/// nounwind = No need for an entry
/// uwtable = Needs an entry because the ABI says so and because
/// an exception might pass by.
/// uwtable + nounwind = Needs an entry because the ABI says so.
enum AttrVal {
// IR-Level Attributes
None, ///< No attributes have been set
AddressSafety, ///< Address safety checking is on.
Alignment, ///< Alignment of parameter (5 bits)
///< stored as log2 of alignment with +1 bias
///< 0 means unaligned different from align 1
AlwaysInline, ///< inline=always
ByVal, ///< Pass structure by value
InlineHint, ///< Source said inlining was desirable
InReg, ///< Force argument to be passed in register
MinSize, ///< Function must be optimized for size first
Naked, ///< Naked function
Nest, ///< Nested function static chain
NoAlias, ///< Considered to not alias after call
NoCapture, ///< Function creates no aliases of pointer
NoImplicitFloat, ///< Disable implicit floating point insts
NoInline, ///< inline=never
NonLazyBind, ///< Function is called early and/or
///< often, so lazy binding isn't worthwhile
NoRedZone, ///< Disable redzone
NoReturn, ///< Mark the function as not returning
NoUnwind, ///< Function doesn't unwind stack
OptimizeForSize, ///< opt_size
ReadNone, ///< Function does not access memory
ReadOnly, ///< Function only reads from memory
ReturnsTwice, ///< Function can return twice
SExt, ///< Sign extended before/after call
StackAlignment, ///< Alignment of stack for function (3 bits)
///< stored as log2 of alignment with +1 bias 0
///< means unaligned (different from
///< alignstack={1))
StackProtect, ///< Stack protection.
StackProtectReq, ///< Stack protection required.
StructRet, ///< Hidden pointer to structure to return
UWTable, ///< Function must be in a unwind table
ZExt ///< Zero extended before/after call
};
private:
AttributesImpl *Attrs;
Attributes(AttributesImpl *A) : Attrs(A) {}
public:
Attributes() : Attrs(0) {}
Attributes(const Attributes &A) : Attrs(A.Attrs) {}
Attributes &operator=(const Attributes &A) {
Attrs = A.Attrs;
return *this;
}
Attributes &operator &= (const Attributes &Attrs) {
Bits &= Attrs.Bits;
return *this;
/// get - Return a uniquified Attributes object. This takes the uniquified
/// value from the Builder and wraps it in the Attributes class.
static Attributes get(LLVMContext &Context, ArrayRef<AttrVal> Vals);
static Attributes get(LLVMContext &Context, AttrBuilder &B);
/// @brief Return true if the attribute is present.
bool hasAttribute(AttrVal Val) const;
/// @brief Return true if attributes exist
bool hasAttributes() const;
/// @brief Return true if the attributes are a non-null intersection.
bool hasAttributes(const Attributes &A) const;
/// @brief Returns the alignment field of an attribute as a byte alignment
/// value.
unsigned getAlignment() const;
/// @brief Returns the stack alignment field of an attribute as a byte
/// alignment value.
unsigned getStackAlignment() const;
/// @brief Parameter attributes that do not apply to vararg call arguments.
bool hasIncompatibleWithVarArgsAttrs() const {
return hasAttribute(Attributes::StructRet);
}
Attributes operator ~ () const { return Attributes(~Bits); }
uint64_t Raw() const { return Bits; }
private:
// Currently, we need less than 64 bits.
/// @brief Attributes that only apply to function parameters.
bool hasParameterOnlyAttrs() const {
return hasAttribute(Attributes::ByVal) ||
hasAttribute(Attributes::Nest) ||
hasAttribute(Attributes::StructRet) ||
hasAttribute(Attributes::NoCapture);
}
/// @brief Attributes that may be applied to the function itself. These cannot
/// be used on return values or function parameters.
bool hasFunctionOnlyAttrs() const {
return hasAttribute(Attributes::NoReturn) ||
hasAttribute(Attributes::NoUnwind) ||
hasAttribute(Attributes::ReadNone) ||
hasAttribute(Attributes::ReadOnly) ||
hasAttribute(Attributes::NoInline) ||
hasAttribute(Attributes::AlwaysInline) ||
hasAttribute(Attributes::OptimizeForSize) ||
hasAttribute(Attributes::StackProtect) ||
hasAttribute(Attributes::StackProtectReq) ||
hasAttribute(Attributes::NoRedZone) ||
hasAttribute(Attributes::NoImplicitFloat) ||
hasAttribute(Attributes::Naked) ||
hasAttribute(Attributes::InlineHint) ||
hasAttribute(Attributes::StackAlignment) ||
hasAttribute(Attributes::UWTable) ||
hasAttribute(Attributes::NonLazyBind) ||
hasAttribute(Attributes::ReturnsTwice) ||
hasAttribute(Attributes::AddressSafety) ||
hasAttribute(Attributes::MinSize);
}
bool operator==(const Attributes &A) const {
return Attrs == A.Attrs;
}
bool operator!=(const Attributes &A) const {
return Attrs != A.Attrs;
}
uint64_t Raw() const;
/// @brief Which attributes cannot be applied to a type.
static Attributes typeIncompatible(Type *Ty);
/// encodeLLVMAttributesForBitcode - This returns an integer containing an
/// encoding of all the LLVM attributes found in the given attribute bitset.
/// Any change to this encoding is a breaking change to bitcode compatibility.
static uint64_t encodeLLVMAttributesForBitcode(Attributes Attrs);
/// decodeLLVMAttributesForBitcode - This returns an attribute bitset
/// containing the LLVM attributes that have been decoded from the given
/// integer. This function must stay in sync with
/// 'encodeLLVMAttributesForBitcode'.
static Attributes decodeLLVMAttributesForBitcode(LLVMContext &C,
uint64_t EncodedAttrs);
/// getAsString - The set of Attributes set in Attributes is converted to a
/// string of equivalent mnemonics. This is, presumably, for writing out the
/// mnemonics for the assembly writer.
/// @brief Convert attribute bits to text
std::string getAsString() const;
};
//===----------------------------------------------------------------------===//
/// AttrBuilder - This class is used in conjunction with the Attributes::get
/// method to create an Attributes object. The object itself is uniquified. The
/// Builder's value, however, is not. So this can be used as a quick way to test
/// for equality, presence of attributes, etc.
class AttrBuilder {
uint64_t Bits;
public:
AttrBuilder() : Bits(0) {}
explicit AttrBuilder(uint64_t B) : Bits(B) {}
AttrBuilder(const Attributes &A) : Bits(A.Raw()) {}
AttrBuilder(const AttrBuilder &B) : Bits(B.Bits) {}
void clear() { Bits = 0; }
/// addAttribute - Add an attribute to the builder.
AttrBuilder &addAttribute(Attributes::AttrVal Val);
/// removeAttribute - Remove an attribute from the builder.
AttrBuilder &removeAttribute(Attributes::AttrVal Val);
/// addAttribute - Add the attributes from A to the builder.
AttrBuilder &addAttributes(const Attributes &A);
/// removeAttribute - Remove the attributes from A from the builder.
AttrBuilder &removeAttributes(const Attributes &A);
/// hasAttribute - Return true if the builder has the specified attribute.
bool hasAttribute(Attributes::AttrVal A) const;
/// hasAttributes - Return true if the builder has IR-level attributes.
bool hasAttributes() const;
/// hasAttributes - Return true if the builder has any attribute that's in the
/// specified attribute.
bool hasAttributes(const Attributes &A) const;
/// hasAlignmentAttr - Return true if the builder has an alignment attribute.
bool hasAlignmentAttr() const;
/// getAlignment - Retrieve the alignment attribute, if it exists.
uint64_t getAlignment() const;
/// getStackAlignment - Retrieve the stack alignment attribute, if it exists.
uint64_t getStackAlignment() const;
/// addAlignmentAttr - This turns an int alignment (which must be a power of
/// 2) into the form used internally in Attributes.
AttrBuilder &addAlignmentAttr(unsigned Align);
/// addStackAlignmentAttr - This turns an int stack alignment (which must be a
/// power of 2) into the form used internally in Attributes.
AttrBuilder &addStackAlignmentAttr(unsigned Align);
/// addRawValue - Add the raw value to the internal representation.
/// N.B. This should be used ONLY for decoding LLVM bitcode!
AttrBuilder &addRawValue(uint64_t Val);
/// @brief Remove attributes that are used on functions only.
void removeFunctionOnlyAttrs() {
removeAttribute(Attributes::NoReturn)
.removeAttribute(Attributes::NoUnwind)
.removeAttribute(Attributes::ReadNone)
.removeAttribute(Attributes::ReadOnly)
.removeAttribute(Attributes::NoInline)
.removeAttribute(Attributes::AlwaysInline)
.removeAttribute(Attributes::OptimizeForSize)
.removeAttribute(Attributes::StackProtect)
.removeAttribute(Attributes::StackProtectReq)
.removeAttribute(Attributes::NoRedZone)
.removeAttribute(Attributes::NoImplicitFloat)
.removeAttribute(Attributes::Naked)
.removeAttribute(Attributes::InlineHint)
.removeAttribute(Attributes::StackAlignment)
.removeAttribute(Attributes::UWTable)
.removeAttribute(Attributes::NonLazyBind)
.removeAttribute(Attributes::ReturnsTwice)
.removeAttribute(Attributes::AddressSafety)
.removeAttribute(Attributes::MinSize);
}
uint64_t Raw() const { return Bits; }
bool operator==(const AttrBuilder &B) {
return Bits == B.Bits;
}
bool operator!=(const AttrBuilder &B) {
return Bits != B.Bits;
}
};
namespace Attribute {
//===----------------------------------------------------------------------===//
// AttributeWithIndex
//===----------------------------------------------------------------------===//
/// Function parameters and results can have attributes to indicate how they
/// should be treated by optimizations and code generation. This enumeration
/// lists the attributes that can be associated with parameters, function
/// results or the function itself.
/// @brief Function attributes.
// We declare AttrConst objects that will be used throughout the code
// and also raw uint64_t objects with _i suffix to be used below for other
// constant declarations. This is done to avoid static CTORs and at the same
// time to keep type-safety of Attributes.
#define DECLARE_LLVM_ATTRIBUTE(name, value) \
const uint64_t name##_i = value; \
const AttrConst name = {value};
DECLARE_LLVM_ATTRIBUTE(None,0) ///< No attributes have been set
DECLARE_LLVM_ATTRIBUTE(ZExt,1<<0) ///< Zero extended before/after call
DECLARE_LLVM_ATTRIBUTE(SExt,1<<1) ///< Sign extended before/after call
DECLARE_LLVM_ATTRIBUTE(NoReturn,1<<2) ///< Mark the function as not returning
DECLARE_LLVM_ATTRIBUTE(InReg,1<<3) ///< Force argument to be passed in register
DECLARE_LLVM_ATTRIBUTE(StructRet,1<<4) ///< Hidden pointer to structure to return
DECLARE_LLVM_ATTRIBUTE(NoUnwind,1<<5) ///< Function doesn't unwind stack
DECLARE_LLVM_ATTRIBUTE(NoAlias,1<<6) ///< Considered to not alias after call
DECLARE_LLVM_ATTRIBUTE(ByVal,1<<7) ///< Pass structure by value
DECLARE_LLVM_ATTRIBUTE(Nest,1<<8) ///< Nested function static chain
DECLARE_LLVM_ATTRIBUTE(ReadNone,1<<9) ///< Function does not access memory
DECLARE_LLVM_ATTRIBUTE(ReadOnly,1<<10) ///< Function only reads from memory
DECLARE_LLVM_ATTRIBUTE(NoInline,1<<11) ///< inline=never
DECLARE_LLVM_ATTRIBUTE(AlwaysInline,1<<12) ///< inline=always
DECLARE_LLVM_ATTRIBUTE(OptimizeForSize,1<<13) ///< opt_size
DECLARE_LLVM_ATTRIBUTE(StackProtect,1<<14) ///< Stack protection.
DECLARE_LLVM_ATTRIBUTE(StackProtectReq,1<<15) ///< Stack protection required.
DECLARE_LLVM_ATTRIBUTE(Alignment,31<<16) ///< Alignment of parameter (5 bits)
// stored as log2 of alignment with +1 bias
// 0 means unaligned different from align 1
DECLARE_LLVM_ATTRIBUTE(NoCapture,1<<21) ///< Function creates no aliases of pointer
DECLARE_LLVM_ATTRIBUTE(NoRedZone,1<<22) /// disable redzone
DECLARE_LLVM_ATTRIBUTE(NoImplicitFloat,1<<23) /// disable implicit floating point
/// instructions.
DECLARE_LLVM_ATTRIBUTE(Naked,1<<24) ///< Naked function
DECLARE_LLVM_ATTRIBUTE(InlineHint,1<<25) ///< source said inlining was
///desirable
DECLARE_LLVM_ATTRIBUTE(StackAlignment,7<<26) ///< Alignment of stack for
///function (3 bits) stored as log2
///of alignment with +1 bias
///0 means unaligned (different from
///alignstack= {1))
DECLARE_LLVM_ATTRIBUTE(ReturnsTwice,1<<29) ///< Function can return twice
DECLARE_LLVM_ATTRIBUTE(UWTable,1<<30) ///< Function must be in a unwind
///table
DECLARE_LLVM_ATTRIBUTE(NonLazyBind,1U<<31) ///< Function is called early and/or
/// often, so lazy binding isn't
/// worthwhile.
DECLARE_LLVM_ATTRIBUTE(AddressSafety,1ULL<<32) ///< Address safety checking is on.
DECLARE_LLVM_ATTRIBUTE(IANSDialect,1ULL<<33) ///< Inline asm non-standard dialect.
/// When not set, ATT dialect assumed.
/// When set implies the Intel dialect.
#undef DECLARE_LLVM_ATTRIBUTE
/// Note that uwtable is about the ABI or the user mandating an entry in the
/// unwind table. The nounwind attribute is about an exception passing by the
/// function.
/// In a theoretical system that uses tables for profiling and sjlj for
/// exceptions, they would be fully independent. In a normal system that
/// uses tables for both, the semantics are:
/// nil = Needs an entry because an exception might pass by.
/// nounwind = No need for an entry
/// uwtable = Needs an entry because the ABI says so and because
/// an exception might pass by.
/// uwtable + nounwind = Needs an entry because the ABI says so.
/// @brief Attributes that only apply to function parameters.
const AttrConst ParameterOnly = {ByVal_i | Nest_i |
StructRet_i | NoCapture_i};
/// @brief Attributes that may be applied to the function itself. These cannot
/// be used on return values or function parameters.
const AttrConst FunctionOnly = {NoReturn_i | NoUnwind_i | ReadNone_i |
ReadOnly_i | NoInline_i | AlwaysInline_i | OptimizeForSize_i |
StackProtect_i | StackProtectReq_i | NoRedZone_i | NoImplicitFloat_i |
Naked_i | InlineHint_i | StackAlignment_i |
UWTable_i | NonLazyBind_i | ReturnsTwice_i | AddressSafety_i |
IANSDialect_i};
/// @brief Parameter attributes that do not apply to vararg call arguments.
const AttrConst VarArgsIncompatible = {StructRet_i};
/// @brief Attributes that are mutually incompatible.
const AttrConst MutuallyIncompatible[5] = {
{ByVal_i | Nest_i | StructRet_i},
{ByVal_i | Nest_i | InReg_i },
{ZExt_i | SExt_i},
{ReadNone_i | ReadOnly_i},
{NoInline_i | AlwaysInline_i}
};
/// @brief Which attributes cannot be applied to a type.
Attributes typeIncompatible(Type *Ty);
/// This turns an int alignment (a power of 2, normally) into the
/// form used internally in Attributes.
inline Attributes constructAlignmentFromInt(unsigned i) {
// Default alignment, allow the target to define how to align it.
if (i == 0)
return None;
assert(isPowerOf2_32(i) && "Alignment must be a power of two.");
assert(i <= 0x40000000 && "Alignment too large.");
return Attributes((Log2_32(i)+1) << 16);
}
/// This returns the alignment field of an attribute as a byte alignment value.
inline unsigned getAlignmentFromAttrs(Attributes A) {
Attributes Align = A & Attribute::Alignment;
if (!Align)
return 0;
return 1U << ((Align.Raw() >> 16) - 1);
}
/// This turns an int stack alignment (which must be a power of 2) into
/// the form used internally in Attributes.
inline Attributes constructStackAlignmentFromInt(unsigned i) {
// Default alignment, allow the target to define how to align it.
if (i == 0)
return None;
assert(isPowerOf2_32(i) && "Alignment must be a power of two.");
assert(i <= 0x100 && "Alignment too large.");
return Attributes((Log2_32(i)+1) << 26);
}
/// This returns the stack alignment field of an attribute as a byte alignment
/// value.
inline unsigned getStackAlignmentFromAttrs(Attributes A) {
Attributes StackAlign = A & Attribute::StackAlignment;
if (!StackAlign)
return 0;
return 1U << ((StackAlign.Raw() >> 26) - 1);
}
/// This returns an integer containing an encoding of all the
/// LLVM attributes found in the given attribute bitset. Any
/// change to this encoding is a breaking change to bitcode
/// compatibility.
inline uint64_t encodeLLVMAttributesForBitcode(Attributes Attrs) {
// FIXME: It doesn't make sense to store the alignment information as an
// expanded out value, we should store it as a log2 value. However, we can't
// just change that here without breaking bitcode compatibility. If this ever
// becomes a problem in practice, we should introduce new tag numbers in the
// bitcode file and have those tags use a more efficiently encoded alignment
// field.
// Store the alignment in the bitcode as a 16-bit raw value instead of a
// 5-bit log2 encoded value. Shift the bits above the alignment up by
// 11 bits.
uint64_t EncodedAttrs = Attrs.Raw() & 0xffff;
if (Attrs & Attribute::Alignment)
EncodedAttrs |= (1ull << 16) <<
(((Attrs & Attribute::Alignment).Raw()-1) >> 16);
EncodedAttrs |= (Attrs.Raw() & (0xfffull << 21)) << 11;
return EncodedAttrs;
}
/// This returns an attribute bitset containing the LLVM attributes
/// that have been decoded from the given integer. This function
/// must stay in sync with 'encodeLLVMAttributesForBitcode'.
inline Attributes decodeLLVMAttributesForBitcode(uint64_t EncodedAttrs) {
// The alignment is stored as a 16-bit raw value from bits 31--16.
// We shift the bits above 31 down by 11 bits.
unsigned Alignment = (EncodedAttrs & (0xffffull << 16)) >> 16;
assert((!Alignment || isPowerOf2_32(Alignment)) &&
"Alignment must be a power of two.");
Attributes Attrs(EncodedAttrs & 0xffff);
if (Alignment)
Attrs |= Attribute::constructAlignmentFromInt(Alignment);
Attrs |= Attributes((EncodedAttrs & (0xfffull << 32)) >> 11);
return Attrs;
}
/// The set of Attributes set in Attributes is converted to a
/// string of equivalent mnemonics. This is, presumably, for writing out
/// the mnemonics for the assembly writer.
/// @brief Convert attribute bits to text
std::string getAsString(Attributes Attrs);
} // end namespace Attribute
/// This is just a pair of values to associate a set of attributes
/// with an index.
/// AttributeWithIndex - This is just a pair of values to associate a set of
/// attributes with an index.
struct AttributeWithIndex {
Attributes Attrs; ///< The attributes that are set, or'd together.
unsigned Index; ///< Index of the parameter for which the attributes apply.
///< Index 0 is used for return value attributes.
///< Index ~0U is used for function attributes.
Attributes Attrs; ///< The attributes that are set, or'd together.
unsigned Index; ///< Index of the parameter for which the attributes apply.
///< Index 0 is used for return value attributes.
///< Index ~0U is used for function attributes.
static AttributeWithIndex get(LLVMContext &C, unsigned Idx,
ArrayRef<Attributes::AttrVal> Attrs) {
return get(Idx, Attributes::get(C, Attrs));
}
static AttributeWithIndex get(unsigned Idx, Attributes Attrs) {
AttributeWithIndex P;
P.Index = Idx;
@ -300,31 +312,42 @@ class AttributeListImpl;
/// AttrListPtr - This class manages the ref count for the opaque
/// AttributeListImpl object and provides accessors for it.
class AttrListPtr {
/// AttrList - The attributes that we are managing. This can be null
/// to represent the empty attributes list.
public:
enum AttrIndex {
ReturnIndex = 0U,
FunctionIndex = ~0U
};
private:
/// @brief The attributes that we are managing. This can be null to represent
/// the empty attributes list.
AttributeListImpl *AttrList;
/// @brief The attributes for the specified index are returned. Attributes
/// for the result are denoted with Idx = 0.
Attributes getAttributes(unsigned Idx) const;
explicit AttrListPtr(AttributeListImpl *LI) : AttrList(LI) {}
public:
AttrListPtr() : AttrList(0) {}
AttrListPtr(const AttrListPtr &P);
AttrListPtr(const AttrListPtr &P) : AttrList(P.AttrList) {}
const AttrListPtr &operator=(const AttrListPtr &RHS);
~AttrListPtr();
//===--------------------------------------------------------------------===//
// Attribute List Construction and Mutation
//===--------------------------------------------------------------------===//
/// get - Return a Attributes list with the specified parameters in it.
static AttrListPtr get(ArrayRef<AttributeWithIndex> Attrs);
static AttrListPtr get(LLVMContext &C, ArrayRef<AttributeWithIndex> Attrs);
/// addAttr - Add the specified attribute at the specified index to this
/// attribute list. Since attribute lists are immutable, this
/// returns the new list.
AttrListPtr addAttr(unsigned Idx, Attributes Attrs) const;
AttrListPtr addAttr(LLVMContext &C, unsigned Idx, Attributes Attrs) const;
/// removeAttr - Remove the specified attribute at the specified index from
/// this attribute list. Since attribute lists are immutable, this
/// returns the new list.
AttrListPtr removeAttr(unsigned Idx, Attributes Attrs) const;
AttrListPtr removeAttr(LLVMContext &C, unsigned Idx, Attributes Attrs) const;
//===--------------------------------------------------------------------===//
// Attribute List Accessors
@ -332,36 +355,38 @@ class AttrListPtr {
/// getParamAttributes - The attributes for the specified index are
/// returned.
Attributes getParamAttributes(unsigned Idx) const {
assert (Idx && Idx != ~0U && "Invalid parameter index!");
return getAttributes(Idx);
}
/// getRetAttributes - The attributes for the ret value are
/// returned.
Attributes getRetAttributes() const {
return getAttributes(0);
return getAttributes(ReturnIndex);
}
/// getFnAttributes - The function attributes are returned.
Attributes getFnAttributes() const {
return getAttributes(~0U);
return getAttributes(FunctionIndex);
}
/// paramHasAttr - Return true if the specified parameter index has the
/// specified attribute set.
bool paramHasAttr(unsigned Idx, Attributes Attr) const {
return getAttributes(Idx) & Attr;
return getAttributes(Idx).hasAttributes(Attr);
}
/// getParamAlignment - Return the alignment for the specified function
/// parameter.
unsigned getParamAlignment(unsigned Idx) const {
return Attribute::getAlignmentFromAttrs(getAttributes(Idx));
return getAttributes(Idx).getAlignment();
}
/// hasAttrSomewhere - Return true if the specified attribute is set for at
/// least one parameter or for the return value.
bool hasAttrSomewhere(Attributes Attr) const;
bool hasAttrSomewhere(Attributes::AttrVal Attr) const;
unsigned getNumAttrs() const;
Attributes &getAttributesAtIndex(unsigned i) const;
/// operator==/!= - Provide equality predicates.
bool operator==(const AttrListPtr &RHS) const
@ -369,8 +394,6 @@ class AttrListPtr {
bool operator!=(const AttrListPtr &RHS) const
{ return AttrList != RHS.AttrList; }
void dump() const;
//===--------------------------------------------------------------------===//
// Attribute List Introspection
//===--------------------------------------------------------------------===//
@ -400,13 +423,7 @@ class AttrListPtr {
/// holds a index number plus a set of attributes.
const AttributeWithIndex &getSlot(unsigned Slot) const;
private:
explicit AttrListPtr(AttributeListImpl *L);
/// getAttributes - The attributes for the specified index are
/// returned. Attributes for the result are denoted with Idx = 0.
Attributes getAttributes(unsigned Idx) const;
void dump() const;
};
} // End llvm namespace

View File

@ -79,8 +79,8 @@ class BasicBlock : public Value, // Basic blocks are data objects also
void setParent(Function *parent);
friend class SymbolTableListTraits<BasicBlock, Function>;
BasicBlock(const BasicBlock &); // Do not implement
void operator=(const BasicBlock &); // Do not implement
BasicBlock(const BasicBlock &) LLVM_DELETED_FUNCTION;
void operator=(const BasicBlock &) LLVM_DELETED_FUNCTION;
/// BasicBlock ctor - If the function parameter is specified, the basic block
/// is automatically inserted at either the end of the function (if
@ -213,7 +213,6 @@ class BasicBlock : public Value, // Basic blocks are data objects also
ValueSymbolTable *getValueSymbolTable();
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const BasicBlock *) { return true; }
static inline bool classof(const Value *V) {
return V->getValueID() == Value::BasicBlockVal;
}

View File

@ -415,8 +415,8 @@ class Archive {
/// name will be truncated at 15 characters. If \p Compress is specified,
/// all archive members will be compressed before being written. If
/// \p PrintSymTab is true, the symbol table will be printed to std::cout.
/// @returns true if an error occurred, \p error set to error message
/// @returns false if the writing succeeded.
/// @returns true if an error occurred, \p error set to error message;
/// returns false if the writing succeeded.
/// @brief Write (possibly modified) archive contents to disk
bool writeToDisk(
bool CreateSymbolTable=false, ///< Create Symbol table
@ -480,8 +480,8 @@ class Archive {
/// Writes one ArchiveMember to an ofstream. If an error occurs, returns
/// false, otherwise true. If an error occurs and error is non-null then
/// it will be set to an error message.
/// @returns false Writing member succeeded
/// @returns true Writing member failed, \p error set to error message
/// @returns false if writing member succeeded,
/// returns true if writing member failed, \p error set to error message.
bool writeMember(
const ArchiveMember& member, ///< The member to be written
std::ofstream& ARFile, ///< The file to write member onto
@ -527,9 +527,9 @@ class Archive {
/// @name Hidden
/// @{
private:
Archive(); ///< Do not implement
Archive(const Archive&); ///< Do not implement
Archive& operator=(const Archive&); ///< Do not implement
Archive() LLVM_DELETED_FUNCTION;
Archive(const Archive&) LLVM_DELETED_FUNCTION;
Archive& operator=(const Archive&) LLVM_DELETED_FUNCTION;
/// @}
};

View File

@ -47,9 +47,9 @@ class BitstreamReader {
/// block/record name information in the BlockInfo block. Only llvm-bcanalyzer
/// uses this.
bool IgnoreBlockInfoNames;
BitstreamReader(const BitstreamReader&); // DO NOT IMPLEMENT
void operator=(const BitstreamReader&); // DO NOT IMPLEMENT
BitstreamReader(const BitstreamReader&) LLVM_DELETED_FUNCTION;
void operator=(const BitstreamReader&) LLVM_DELETED_FUNCTION;
public:
BitstreamReader() : IgnoreBlockInfoNames(true) {
}
@ -409,7 +409,7 @@ class BitstreamCursor {
}
/// EnterSubBlock - Having read the ENTER_SUBBLOCK abbrevid, enter
/// the block, and return true if the block is valid.
/// the block, and return true if the block has an error.
bool EnterSubBlock(unsigned BlockID, unsigned *NumWordsP = 0) {
// Save the current block's state on BlockScope.
BlockScope.push_back(Block(CurCodeSize));

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