create new branch and first commit
This commit is contained in:
parent
9c1a6a1622
commit
eadf46b4f3
|
@ -1,6 +1,42 @@
|
||||||
$(HOSTLIBS)-$(CONFIG_PAX_RAP) += rap_plugin.so
|
GCC_PLUGINS_DIR := $(shell $(CC) -print-file-name=plugin)
|
||||||
always := $($(HOSTLIBS)-y)
|
|
||||||
|
|
||||||
rap_plugin-objs := $(patsubst $(srctree)/$(src)/%.c,%.o,$(wildcard $(srctree)/$(src)/*.c))
|
ifeq ($(PLUGINCC),$(HOSTCC))
|
||||||
|
HOSTLIBS := hostlibs
|
||||||
|
HOST_EXTRACFLAGS += -I$(GCC_PLUGINS_DIR)/include -I$(src)
|
||||||
|
HOST_EXTRACFLAGS += -std=gnu99 -ggdb -fvisibility=hidden
|
||||||
|
HOST_EXTRACFLAGS += -Wall -W
|
||||||
|
export HOST_EXTRACFLAGS
|
||||||
|
else
|
||||||
|
HOSTLIBS := hostcxxlibs
|
||||||
|
HOST_EXTRACXXFLAGS += -I$(GCC_PLUGINS_DIR)/include -I$(src)
|
||||||
|
HOST_EXTRACXXFLAGS += -std=gnu++98 -ggdb -fvisibility=hidden
|
||||||
|
HOST_EXTRACXXFLAGS += -fno-rtti -fno-exceptions -fasynchronous-unwind-tables
|
||||||
|
HOST_EXTRACXXFLAGS += -Wall -W
|
||||||
|
HOST_EXTRACXXFLAGS += -Wno-unused-parameter -Wno-narrowing -Wno-unused-variable
|
||||||
|
export HOST_EXTRACXXFLAGS
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifneq ($(CFLAGS_KCOV), $(SANCOV_PLUGIN))
|
||||||
|
GCC_PLUGIN := $(filter-out $(SANCOV_PLUGIN), $(GCC_PLUGIN))
|
||||||
|
endif
|
||||||
|
|
||||||
|
export HOSTLIBS
|
||||||
|
|
||||||
|
$(HOSTLIBS)-y := $(foreach p,$(GCC_PLUGIN),$(if $(findstring /,$(p)),,$(p)))
|
||||||
|
always := $($(HOSTLIBS)-y)
|
||||||
|
$(foreach p,$($(HOSTLIBS)-y:%.so=%),$(eval $(p)-objs := $(p).o))
|
||||||
|
|
||||||
|
$(obj)/randomize_layout_plugin.o: $(objtree)/$(obj)/randomize_layout_seed.h
|
||||||
|
|
||||||
|
quiet_cmd_create_randomize_layout_seed = GENSEED $@
|
||||||
|
cmd_create_randomize_layout_seed = \
|
||||||
|
$(CONFIG_SHELL) $(srctree)/$(src)/gen-random-seed.sh $@ $(objtree)/include/generated/randomize_layout_hash.h
|
||||||
|
$(objtree)/$(obj)/randomize_layout_seed.h: FORCE
|
||||||
|
$(call if_changed,create_randomize_layout_seed)
|
||||||
|
|
||||||
|
targets += randomize_layout_seed.h randomize_layout_hash.h
|
||||||
|
|
||||||
|
subdir-y := $(GCC_PLUGIN_SUBDIR)
|
||||||
|
subdir- += $(GCC_PLUGIN_SUBDIR)
|
||||||
|
|
||||||
clean-files += *.so
|
clean-files += *.so
|
||||||
|
|
|
@ -0,0 +1,491 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2011-2017 by the PaX Team <pageexec@freemail.hu>
|
||||||
|
* Licensed under the GPL v2
|
||||||
|
*
|
||||||
|
* Note: the choice of the license means that the compilation process is
|
||||||
|
* NOT 'eligible' as defined by gcc's library exception to the GPL v3,
|
||||||
|
* but for the kernel it doesn't matter since it doesn't link against
|
||||||
|
* any of the gcc libraries
|
||||||
|
*
|
||||||
|
* gcc plugin to implement various sparse (source code checker) features
|
||||||
|
*
|
||||||
|
* TODO:
|
||||||
|
* - define separate __iomem, __percpu and __rcu address spaces (lots of code to patch)
|
||||||
|
*
|
||||||
|
* BUGS:
|
||||||
|
* - none known
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "gcc-common.h"
|
||||||
|
|
||||||
|
extern void c_register_addr_space (const char *str, addr_space_t as);
|
||||||
|
extern enum machine_mode default_addr_space_pointer_mode (addr_space_t);
|
||||||
|
extern enum machine_mode default_addr_space_address_mode (addr_space_t);
|
||||||
|
extern bool default_addr_space_valid_pointer_mode(enum machine_mode mode, addr_space_t as);
|
||||||
|
extern bool default_addr_space_legitimate_address_p(enum machine_mode mode, rtx mem, bool strict, addr_space_t as);
|
||||||
|
extern rtx default_addr_space_legitimize_address(rtx x, rtx oldx, enum machine_mode mode, addr_space_t as);
|
||||||
|
|
||||||
|
__visible int plugin_is_GPL_compatible;
|
||||||
|
|
||||||
|
static struct plugin_info checker_plugin_info = {
|
||||||
|
.version = "201602181345",
|
||||||
|
.help = "user\tturn on user/kernel address space checking\n"
|
||||||
|
"context\tturn on locking context checking\n"
|
||||||
|
};
|
||||||
|
|
||||||
|
#define ADDR_SPACE_KERNEL 0
|
||||||
|
#define ADDR_SPACE_FORCE_KERNEL 1
|
||||||
|
#define ADDR_SPACE_USER 2
|
||||||
|
#define ADDR_SPACE_FORCE_USER 3
|
||||||
|
#define ADDR_SPACE_IOMEM 0
|
||||||
|
#define ADDR_SPACE_FORCE_IOMEM 0
|
||||||
|
#define ADDR_SPACE_PERCPU 0
|
||||||
|
#define ADDR_SPACE_FORCE_PERCPU 0
|
||||||
|
#define ADDR_SPACE_RCU 0
|
||||||
|
#define ADDR_SPACE_FORCE_RCU 0
|
||||||
|
|
||||||
|
static enum machine_mode checker_addr_space_pointer_mode(addr_space_t addrspace)
|
||||||
|
{
|
||||||
|
return default_addr_space_pointer_mode(ADDR_SPACE_GENERIC);
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum machine_mode checker_addr_space_address_mode(addr_space_t addrspace)
|
||||||
|
{
|
||||||
|
return default_addr_space_address_mode(ADDR_SPACE_GENERIC);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool checker_addr_space_valid_pointer_mode(enum machine_mode mode, addr_space_t as)
|
||||||
|
{
|
||||||
|
return default_addr_space_valid_pointer_mode(mode, as);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool checker_addr_space_legitimate_address_p(enum machine_mode mode, rtx mem, bool strict, addr_space_t as)
|
||||||
|
{
|
||||||
|
return default_addr_space_legitimate_address_p(mode, mem, strict, ADDR_SPACE_GENERIC);
|
||||||
|
}
|
||||||
|
|
||||||
|
static rtx checker_addr_space_legitimize_address(rtx x, rtx oldx, enum machine_mode mode, addr_space_t as)
|
||||||
|
{
|
||||||
|
return default_addr_space_legitimize_address(x, oldx, mode, as);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool checker_addr_space_subset_p(addr_space_t subset, addr_space_t superset)
|
||||||
|
{
|
||||||
|
if (subset == ADDR_SPACE_FORCE_KERNEL && superset == ADDR_SPACE_KERNEL)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (subset == ADDR_SPACE_FORCE_USER && superset == ADDR_SPACE_USER)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (subset == ADDR_SPACE_FORCE_IOMEM && superset == ADDR_SPACE_IOMEM)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (subset == ADDR_SPACE_KERNEL && superset == ADDR_SPACE_FORCE_USER)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (subset == ADDR_SPACE_KERNEL && superset == ADDR_SPACE_FORCE_IOMEM)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (subset == ADDR_SPACE_USER && superset == ADDR_SPACE_FORCE_KERNEL)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (subset == ADDR_SPACE_IOMEM && superset == ADDR_SPACE_FORCE_KERNEL)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return subset == superset;
|
||||||
|
}
|
||||||
|
|
||||||
|
static rtx checker_addr_space_convert(rtx op, tree from_type, tree to_type)
|
||||||
|
{
|
||||||
|
// addr_space_t from_as = TYPE_ADDR_SPACE(TREE_TYPE(from_type));
|
||||||
|
// addr_space_t to_as = TYPE_ADDR_SPACE(TREE_TYPE(to_type));
|
||||||
|
|
||||||
|
return op;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void register_checker_address_spaces(void *event_data, void *data)
|
||||||
|
{
|
||||||
|
c_register_addr_space("__kernel", ADDR_SPACE_KERNEL);
|
||||||
|
c_register_addr_space("__force_kernel", ADDR_SPACE_FORCE_KERNEL);
|
||||||
|
c_register_addr_space("__user", ADDR_SPACE_USER);
|
||||||
|
c_register_addr_space("__force_user", ADDR_SPACE_FORCE_USER);
|
||||||
|
// c_register_addr_space("__iomem", ADDR_SPACE_IOMEM);
|
||||||
|
// c_register_addr_space("__force_iomem", ADDR_SPACE_FORCE_IOMEM);
|
||||||
|
// c_register_addr_space("__percpu", ADDR_SPACE_PERCPU);
|
||||||
|
// c_register_addr_space("__force_percpu", ADDR_SPACE_FORCE_PERCPU);
|
||||||
|
// c_register_addr_space("__rcu", ADDR_SPACE_RCU);
|
||||||
|
// c_register_addr_space("__force_rcu", ADDR_SPACE_FORCE_RCU);
|
||||||
|
|
||||||
|
targetm.addr_space.pointer_mode = checker_addr_space_pointer_mode;
|
||||||
|
targetm.addr_space.address_mode = checker_addr_space_address_mode;
|
||||||
|
targetm.addr_space.valid_pointer_mode = checker_addr_space_valid_pointer_mode;
|
||||||
|
targetm.addr_space.legitimate_address_p = checker_addr_space_legitimate_address_p;
|
||||||
|
// targetm.addr_space.legitimize_address = checker_addr_space_legitimize_address;
|
||||||
|
targetm.addr_space.subset_p = checker_addr_space_subset_p;
|
||||||
|
targetm.addr_space.convert = checker_addr_space_convert;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool split_context_attribute(tree args, tree *lock, tree *in, tree *out)
|
||||||
|
{
|
||||||
|
*in = TREE_VALUE(args);
|
||||||
|
|
||||||
|
if (TREE_CODE(*in) != INTEGER_CST) {
|
||||||
|
*lock = *in;
|
||||||
|
args = TREE_CHAIN(args);
|
||||||
|
*in = TREE_VALUE(args);
|
||||||
|
} else
|
||||||
|
*lock = NULL_TREE;
|
||||||
|
|
||||||
|
args = TREE_CHAIN(args);
|
||||||
|
if (*lock && !args)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
*out = TREE_VALUE(args);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static tree handle_context_attribute(tree *node, tree name, tree args, int flags, bool *no_add_attrs)
|
||||||
|
{
|
||||||
|
*no_add_attrs = true;
|
||||||
|
tree lock, in, out;
|
||||||
|
|
||||||
|
if (TREE_CODE(*node) != FUNCTION_DECL) {
|
||||||
|
error("%qE attribute applies to functions only (%qD)", name, *node);
|
||||||
|
return NULL_TREE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!split_context_attribute(args, &lock, &in, &out)) {
|
||||||
|
error("%qE attribute needs two integers after the lock expression", name);
|
||||||
|
return NULL_TREE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TREE_CODE(in) != INTEGER_CST) {
|
||||||
|
error("the 'in' argument of the %qE attribute must be an integer (%qE)", name, in);
|
||||||
|
return NULL_TREE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TREE_CODE(out) != INTEGER_CST) {
|
||||||
|
error("the 'out' argument of the %qE attribute must be an integer (%qE)", name, out);
|
||||||
|
return NULL_TREE;
|
||||||
|
}
|
||||||
|
|
||||||
|
*no_add_attrs = false;
|
||||||
|
return NULL_TREE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct attribute_spec context_attr = {
|
||||||
|
.name = "context",
|
||||||
|
.min_length = 2,
|
||||||
|
.max_length = 3,
|
||||||
|
.decl_required = true,
|
||||||
|
.type_required = false,
|
||||||
|
.function_type_required = false,
|
||||||
|
.handler = handle_context_attribute,
|
||||||
|
#if BUILDING_GCC_VERSION >= 4007
|
||||||
|
.affects_type_identity = true
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
static void register_attributes(void *event_data, void *data)
|
||||||
|
{
|
||||||
|
register_attribute(&context_attr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char context_function[] = "__context__";
|
||||||
|
static GTY(()) tree context_function_decl;
|
||||||
|
|
||||||
|
static const char context_error[] = "__context_error__";
|
||||||
|
static GTY(()) tree context_error_decl;
|
||||||
|
|
||||||
|
static void context_start_unit(void __unused *gcc_data, void __unused *user_data)
|
||||||
|
{
|
||||||
|
tree fntype, attr;
|
||||||
|
|
||||||
|
// void __context__(void *, int);
|
||||||
|
fntype = build_function_type_list(void_type_node, ptr_type_node, integer_type_node, NULL_TREE);
|
||||||
|
context_function_decl = build_fn_decl(context_function, fntype);
|
||||||
|
|
||||||
|
TREE_PUBLIC(context_function_decl) = 1;
|
||||||
|
TREE_USED(context_function_decl) = 1;
|
||||||
|
DECL_EXTERNAL(context_function_decl) = 1;
|
||||||
|
DECL_ARTIFICIAL(context_function_decl) = 1;
|
||||||
|
DECL_PRESERVE_P(context_function_decl) = 1;
|
||||||
|
// TREE_NOTHROW(context_function_decl) = 1;
|
||||||
|
// DECL_UNINLINABLE(context_function_decl) = 1;
|
||||||
|
DECL_ASSEMBLER_NAME(context_function_decl); // for LTO
|
||||||
|
lang_hooks.decls.pushdecl(context_function_decl);
|
||||||
|
|
||||||
|
// void __context_error__(const void *, int) __attribute__((error("context error")));
|
||||||
|
fntype = build_function_type_list(void_type_node, const_ptr_type_node, integer_type_node, NULL_TREE);
|
||||||
|
context_error_decl = build_fn_decl(context_error, fntype);
|
||||||
|
|
||||||
|
TREE_PUBLIC(context_error_decl) = 1;
|
||||||
|
TREE_USED(context_error_decl) = 1;
|
||||||
|
DECL_EXTERNAL(context_error_decl) = 1;
|
||||||
|
DECL_ARTIFICIAL(context_error_decl) = 1;
|
||||||
|
DECL_PRESERVE_P(context_error_decl) = 1;
|
||||||
|
// TREE_NOTHROW(context_error_decl) = 1;
|
||||||
|
// DECL_UNINLINABLE(context_error_decl) = 1;
|
||||||
|
TREE_THIS_VOLATILE(context_error_decl) = 1;
|
||||||
|
DECL_ASSEMBLER_NAME(context_error_decl);
|
||||||
|
|
||||||
|
attr = tree_cons(NULL, build_const_char_string(14, "context error"), NULL);
|
||||||
|
attr = tree_cons(get_identifier("error"), attr, NULL);
|
||||||
|
decl_attributes(&context_error_decl, attr, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool context_gate(void)
|
||||||
|
{
|
||||||
|
tree context_attr;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
context_attr = lookup_attribute("context", DECL_ATTRIBUTES(current_function_decl));
|
||||||
|
return context_attr != NULL_TREE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static basic_block verify_context_before(gimple_stmt_iterator *gsi, tree context, tree inout, tree error)
|
||||||
|
{
|
||||||
|
gimple stmt;
|
||||||
|
basic_block cond_bb, join_bb, true_bb;
|
||||||
|
edge e;
|
||||||
|
location_t loc;
|
||||||
|
const char *file;
|
||||||
|
int line;
|
||||||
|
size_t len;
|
||||||
|
tree filename;
|
||||||
|
|
||||||
|
stmt = gsi_stmt(*gsi);
|
||||||
|
if (gimple_has_location(stmt)) {
|
||||||
|
loc = gimple_location(stmt);
|
||||||
|
file = gimple_filename(stmt);
|
||||||
|
line = gimple_lineno(stmt);
|
||||||
|
} else {
|
||||||
|
loc = DECL_SOURCE_LOCATION(current_function_decl);
|
||||||
|
file = DECL_SOURCE_FILE(current_function_decl);
|
||||||
|
line = DECL_SOURCE_LINE(current_function_decl);
|
||||||
|
}
|
||||||
|
gcc_assert(file);
|
||||||
|
|
||||||
|
// if (context != count) __context_error__(__FILE__, __LINE__);
|
||||||
|
stmt = gimple_build_cond(NE_EXPR, context, inout, NULL_TREE, NULL_TREE);
|
||||||
|
gimple_set_location(stmt, loc);
|
||||||
|
gsi_insert_before(gsi, stmt, GSI_NEW_STMT);
|
||||||
|
|
||||||
|
cond_bb = gsi_bb(*gsi);
|
||||||
|
gcc_assert(!gsi_end_p(*gsi));
|
||||||
|
gcc_assert(stmt == gsi_stmt(*gsi));
|
||||||
|
|
||||||
|
e = split_block(cond_bb, gsi_stmt(*gsi));
|
||||||
|
cond_bb = e->src;
|
||||||
|
join_bb = e->dest;
|
||||||
|
e->flags = EDGE_FALSE_VALUE;
|
||||||
|
e->probability = REG_BR_PROB_BASE;
|
||||||
|
|
||||||
|
true_bb = create_empty_bb(EXIT_BLOCK_PTR_FOR_FN(cfun)->prev_bb);
|
||||||
|
make_edge(cond_bb, true_bb, EDGE_TRUE_VALUE);
|
||||||
|
make_edge(true_bb, join_bb, EDGE_FALLTHRU);
|
||||||
|
|
||||||
|
set_immediate_dominator(CDI_DOMINATORS, true_bb, cond_bb);
|
||||||
|
set_immediate_dominator(CDI_DOMINATORS, join_bb, cond_bb);
|
||||||
|
|
||||||
|
gcc_assert(cond_bb->loop_father == join_bb->loop_father);
|
||||||
|
add_bb_to_loop(true_bb, cond_bb->loop_father);
|
||||||
|
|
||||||
|
// insert call to builtin_trap or __context_error__
|
||||||
|
*gsi = gsi_start_bb(true_bb);
|
||||||
|
|
||||||
|
// stmt = gimple_build_call(builtin_decl_implicit(BUILT_IN_TRAP), 0);
|
||||||
|
len = strlen(file) + 1;
|
||||||
|
filename = build_const_char_string(len, file);
|
||||||
|
filename = build1(ADDR_EXPR, const_ptr_type_node, filename);
|
||||||
|
stmt = gimple_build_call(error, 2, filename, build_int_cst(NULL_TREE, line));
|
||||||
|
gimple_set_location(stmt, loc);
|
||||||
|
gsi_insert_after(gsi, stmt, GSI_CONTINUE_LINKING);
|
||||||
|
|
||||||
|
*gsi = gsi_start_nondebug_bb(join_bb);
|
||||||
|
return join_bb;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void update_context(gimple_stmt_iterator *gsi, tree context, int diff)
|
||||||
|
{
|
||||||
|
gimple assign;
|
||||||
|
tree op;
|
||||||
|
|
||||||
|
op = fold_build2_loc(UNKNOWN_LOCATION, PLUS_EXPR, integer_type_node, context, build_int_cst(integer_type_node, diff));
|
||||||
|
assign = gimple_build_assign(context, op);
|
||||||
|
gsi_insert_after(gsi, assign, GSI_NEW_STMT);
|
||||||
|
update_stmt(assign);
|
||||||
|
}
|
||||||
|
|
||||||
|
static basic_block track_context(basic_block bb, tree context)
|
||||||
|
{
|
||||||
|
gimple_stmt_iterator gsi;
|
||||||
|
gimple assign;
|
||||||
|
|
||||||
|
// adjust context according to the context information on any call stmt
|
||||||
|
for (gsi = gsi_start_bb(bb); !gsi_end_p(gsi); gsi_next(&gsi)) {
|
||||||
|
gimple stmt = gsi_stmt(gsi);
|
||||||
|
tree fndecl, context_attr;
|
||||||
|
tree lock, in, out;
|
||||||
|
int incount, outcount;
|
||||||
|
|
||||||
|
if (!is_gimple_call(stmt))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
fndecl = gimple_call_fndecl(stmt);
|
||||||
|
if (!fndecl)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (fndecl == context_function_decl) {
|
||||||
|
unsigned int num_ops = gimple_num_ops(stmt);
|
||||||
|
int diff = tree_to_shwi(gimple_op(stmt, num_ops - 1));
|
||||||
|
|
||||||
|
gcc_assert(diff);
|
||||||
|
update_context(&gsi, context, diff);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
context_attr = lookup_attribute("context", DECL_ATTRIBUTES(fndecl));
|
||||||
|
if (!context_attr)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
gcc_assert(split_context_attribute(TREE_VALUE(context_attr), &lock, &in, &out));
|
||||||
|
incount = tree_to_shwi(in);
|
||||||
|
outcount = tree_to_shwi(out);
|
||||||
|
bb = verify_context_before(&gsi, context, in, context_error_decl);
|
||||||
|
update_context(&gsi, context, outcount - incount);
|
||||||
|
}
|
||||||
|
|
||||||
|
return bb;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool bb_any_loop(basic_block bb)
|
||||||
|
{
|
||||||
|
return bb_loop_depth(bb) || (bb->flags & BB_IRREDUCIBLE_LOOP);
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned int context_execute(void)
|
||||||
|
{
|
||||||
|
basic_block bb;
|
||||||
|
gimple assign;
|
||||||
|
gimple_stmt_iterator gsi;
|
||||||
|
tree context_attr, context;
|
||||||
|
tree lock, in, out;
|
||||||
|
|
||||||
|
loop_optimizer_init(LOOPS_NORMAL | LOOPS_HAVE_RECORDED_EXITS);
|
||||||
|
gcc_assert(current_loops);
|
||||||
|
|
||||||
|
calculate_dominance_info(CDI_DOMINATORS);
|
||||||
|
calculate_dominance_info(CDI_POST_DOMINATORS);
|
||||||
|
|
||||||
|
context_attr = lookup_attribute("context", DECL_ATTRIBUTES(current_function_decl));
|
||||||
|
if (context_attr) {
|
||||||
|
gcc_assert(split_context_attribute(TREE_VALUE(context_attr), &lock, &in, &out));
|
||||||
|
} else {
|
||||||
|
in = out = integer_zero_node;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1. create local context variable
|
||||||
|
context = create_tmp_var(integer_type_node, "context");
|
||||||
|
add_referenced_var(context);
|
||||||
|
mark_sym_for_renaming(context);
|
||||||
|
|
||||||
|
// 2. initialize local context variable
|
||||||
|
gcc_assert(single_succ_p(ENTRY_BLOCK_PTR_FOR_FN(cfun)));
|
||||||
|
bb = single_succ(ENTRY_BLOCK_PTR_FOR_FN(cfun));
|
||||||
|
if (!single_pred_p(bb)) {
|
||||||
|
gcc_assert(bb_any_loop(bb));
|
||||||
|
split_edge(single_succ_edge(ENTRY_BLOCK_PTR_FOR_FN(cfun)));
|
||||||
|
bb = single_succ(ENTRY_BLOCK_PTR_FOR_FN(cfun));
|
||||||
|
}
|
||||||
|
gsi = gsi_start_bb(bb);
|
||||||
|
assign = gimple_build_assign(context, in);
|
||||||
|
gsi_insert_before(&gsi, assign, GSI_NEW_STMT);
|
||||||
|
update_stmt(assign);
|
||||||
|
|
||||||
|
// 3. instrument each BB to track the local context variable
|
||||||
|
FOR_EACH_BB_FN(bb, cfun) {
|
||||||
|
bb = track_context(bb, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. verify the local context variable against the expected state
|
||||||
|
if (EDGE_COUNT(EXIT_BLOCK_PTR_FOR_FN(cfun)->preds)) {
|
||||||
|
gcc_assert(single_pred_p(EXIT_BLOCK_PTR_FOR_FN(cfun)));
|
||||||
|
gsi = gsi_last_nondebug_bb(single_pred(EXIT_BLOCK_PTR_FOR_FN(cfun)));
|
||||||
|
verify_context_before(&gsi, context, out, context_error_decl);
|
||||||
|
}
|
||||||
|
|
||||||
|
free_dominance_info(CDI_DOMINATORS);
|
||||||
|
free_dominance_info(CDI_POST_DOMINATORS);
|
||||||
|
loop_optimizer_finalize();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define PASS_NAME context
|
||||||
|
#define PROPERTIES_REQUIRED PROP_gimple_leh | PROP_cfg
|
||||||
|
//#define TODO_FLAGS_START TODO_verify_ssa | TODO_verify_flow | TODO_verify_stmts
|
||||||
|
#define TODO_FLAGS_FINISH TODO_verify_ssa | TODO_verify_stmts | TODO_dump_func | TODO_verify_flow | TODO_update_ssa
|
||||||
|
#include "gcc-generate-gimple-pass.h"
|
||||||
|
|
||||||
|
__visible int plugin_init(struct plugin_name_args *plugin_info, struct plugin_gcc_version *version)
|
||||||
|
{
|
||||||
|
const char * const plugin_name = plugin_info->base_name;
|
||||||
|
const int argc = plugin_info->argc;
|
||||||
|
const struct plugin_argument * const argv = plugin_info->argv;
|
||||||
|
int i;
|
||||||
|
bool enable_user, enable_context;
|
||||||
|
|
||||||
|
static const struct ggc_root_tab gt_ggc_r_gt_checker[] = {
|
||||||
|
{
|
||||||
|
.base = &context_function_decl,
|
||||||
|
.nelt = 1,
|
||||||
|
.stride = sizeof(context_function_decl),
|
||||||
|
.cb = >_ggc_mx_tree_node,
|
||||||
|
.pchw = >_pch_nx_tree_node
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.base = &context_error_decl,
|
||||||
|
.nelt = 1,
|
||||||
|
.stride = sizeof(context_error_decl),
|
||||||
|
.cb = >_ggc_mx_tree_node,
|
||||||
|
.pchw = >_pch_nx_tree_node
|
||||||
|
},
|
||||||
|
LAST_GGC_ROOT_TAB
|
||||||
|
};
|
||||||
|
|
||||||
|
// PASS_INFO(context, "ssa", 1, PASS_POS_INSERT_AFTER);
|
||||||
|
PASS_INFO(context, "phiprop", 1, PASS_POS_INSERT_AFTER);
|
||||||
|
|
||||||
|
if (!plugin_default_version_check(version, &gcc_version)) {
|
||||||
|
error_gcc_version(version);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
register_callback(plugin_name, PLUGIN_INFO, NULL, &checker_plugin_info);
|
||||||
|
|
||||||
|
enable_user = false;
|
||||||
|
enable_context = false;
|
||||||
|
for (i = 0; i < argc; ++i) {
|
||||||
|
if (!strcmp(argv[i].key, "user")) {
|
||||||
|
enable_user = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!strcmp(argv[i].key, "context")) {
|
||||||
|
enable_context = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
error(G_("unknown option '-fplugin-arg-%s-%s'"), plugin_name, argv[i].key);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (enable_user)
|
||||||
|
register_callback(plugin_name, PLUGIN_PRAGMAS, register_checker_address_spaces, NULL);
|
||||||
|
if (enable_context) {
|
||||||
|
register_callback(plugin_name, PLUGIN_ATTRIBUTES, register_attributes, NULL);
|
||||||
|
register_callback(plugin_name, PLUGIN_START_UNIT, context_start_unit, NULL);
|
||||||
|
register_callback(plugin_name, PLUGIN_REGISTER_GGC_ROOTS, NULL, (void *)>_ggc_r_gt_checker);
|
||||||
|
register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &context_pass_info);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,158 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2012-2017 by PaX Team <pageexec@freemail.hu>
|
||||||
|
* Licensed under the GPL v2
|
||||||
|
*
|
||||||
|
* Note: the choice of the license means that the compilation process is
|
||||||
|
* NOT 'eligible' as defined by gcc's library exception to the GPL v3,
|
||||||
|
* but for the kernel it doesn't matter since it doesn't link against
|
||||||
|
* any of the gcc libraries
|
||||||
|
*
|
||||||
|
* gcc plugin to colorize diagnostic output
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "gcc-common.h"
|
||||||
|
|
||||||
|
__visible int plugin_is_GPL_compatible;
|
||||||
|
|
||||||
|
static struct plugin_info colorize_plugin_info = {
|
||||||
|
.version = "201602181345",
|
||||||
|
.help = "color=[never|always|auto]\tdetermine when to colorize\n",
|
||||||
|
};
|
||||||
|
|
||||||
|
#define GREEN "\033[32m\033[K"
|
||||||
|
#define LIGHTGREEN "\033[1;32m\033[K"
|
||||||
|
#define YELLOW "\033[33m\033[K"
|
||||||
|
#define LIGHTYELLOW "\033[1;33m\033[K"
|
||||||
|
#define RED "\033[31m\033[K"
|
||||||
|
#define LIGHTRED "\033[1;31m\033[K"
|
||||||
|
#define BLUE "\033[34m\033[K"
|
||||||
|
#define LIGHTBLUE "\033[1;34m\033[K"
|
||||||
|
#define BRIGHT "\033[1;m\033[K"
|
||||||
|
#define NORMAL "\033[m\033[K"
|
||||||
|
|
||||||
|
static diagnostic_starter_fn old_starter;
|
||||||
|
static diagnostic_finalizer_fn old_finalizer;
|
||||||
|
|
||||||
|
static void start_colorize(diagnostic_context *context, diagnostic_info *diagnostic)
|
||||||
|
{
|
||||||
|
const char *color;
|
||||||
|
char *newprefix;
|
||||||
|
|
||||||
|
switch (diagnostic->kind) {
|
||||||
|
case DK_NOTE:
|
||||||
|
color = LIGHTBLUE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DK_PEDWARN:
|
||||||
|
case DK_WARNING:
|
||||||
|
color = LIGHTYELLOW;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DK_ERROR:
|
||||||
|
case DK_FATAL:
|
||||||
|
case DK_ICE:
|
||||||
|
case DK_PERMERROR:
|
||||||
|
case DK_SORRY:
|
||||||
|
color = LIGHTRED;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
color = NORMAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
old_starter(context, diagnostic);
|
||||||
|
if (-1 == asprintf(&newprefix, "%s%s" NORMAL, color, context->printer->prefix))
|
||||||
|
return;
|
||||||
|
pp_destroy_prefix(context->printer);
|
||||||
|
pp_set_prefix(context->printer, newprefix);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void finalize_colorize(diagnostic_context *context, diagnostic_info *diagnostic)
|
||||||
|
{
|
||||||
|
old_finalizer(context, diagnostic);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void colorize_arm(void)
|
||||||
|
{
|
||||||
|
old_starter = diagnostic_starter(global_dc);
|
||||||
|
old_finalizer = diagnostic_finalizer(global_dc);
|
||||||
|
|
||||||
|
diagnostic_starter(global_dc) = start_colorize;
|
||||||
|
diagnostic_finalizer(global_dc) = finalize_colorize;
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned int colorize_rearm_execute(void)
|
||||||
|
{
|
||||||
|
if (diagnostic_starter(global_dc) == start_colorize)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
colorize_arm();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define PASS_NAME colorize_rearm
|
||||||
|
#define NO_GATE
|
||||||
|
#include "gcc-generate-simple_ipa-pass.h"
|
||||||
|
|
||||||
|
static void colorize_start_unit(void *gcc_data __unused, void *user_data __unused)
|
||||||
|
{
|
||||||
|
colorize_arm();
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool should_colorize(void)
|
||||||
|
{
|
||||||
|
#if BUILDING_GCC_VERSION >= 4009
|
||||||
|
return false;
|
||||||
|
#else
|
||||||
|
char const *t = getenv("TERM");
|
||||||
|
|
||||||
|
return t && strcmp(t, "dumb") && isatty(STDERR_FILENO);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
__visible int plugin_init(struct plugin_name_args *plugin_info, struct plugin_gcc_version *version)
|
||||||
|
{
|
||||||
|
const char * const plugin_name = plugin_info->base_name;
|
||||||
|
const int argc = plugin_info->argc;
|
||||||
|
const struct plugin_argument * const argv = plugin_info->argv;
|
||||||
|
int i;
|
||||||
|
bool colorize;
|
||||||
|
|
||||||
|
PASS_INFO(colorize_rearm, "*free_lang_data", 1, PASS_POS_INSERT_AFTER);
|
||||||
|
|
||||||
|
if (!plugin_default_version_check(version, &gcc_version)) {
|
||||||
|
error_gcc_version(version);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
register_callback(plugin_name, PLUGIN_INFO, NULL, &colorize_plugin_info);
|
||||||
|
|
||||||
|
colorize = getenv("GCC_COLORS") ? should_colorize() : false;
|
||||||
|
|
||||||
|
for (i = 0; i < argc; ++i) {
|
||||||
|
if (!strcmp(argv[i].key, "color")) {
|
||||||
|
if (!argv[i].value) {
|
||||||
|
error(G_("no value supplied for option '-fplugin-arg-%s-%s'"), plugin_name, argv[i].key);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!strcmp(argv[i].value, "always"))
|
||||||
|
colorize = true;
|
||||||
|
else if (!strcmp(argv[i].value, "never"))
|
||||||
|
colorize = false;
|
||||||
|
else if (!strcmp(argv[i].value, "auto"))
|
||||||
|
colorize = should_colorize();
|
||||||
|
else
|
||||||
|
error(G_("invalid option argument '-fplugin-arg-%s-%s=%s'"), plugin_name, argv[i].key, argv[i].value);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
error(G_("unknown option '-fplugin-arg-%s-%s'"), plugin_name, argv[i].key);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (colorize) {
|
||||||
|
// TODO: parse GCC_COLORS as used by gcc 4.9+
|
||||||
|
register_callback(plugin_name, PLUGIN_START_UNIT, &colorize_start_unit, NULL);
|
||||||
|
register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &colorize_rearm_pass_info);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,577 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2011 by Emese Revfy <re.emese@gmail.com>
|
||||||
|
* Copyright 2011-2017 by PaX Team <pageexec@freemail.hu>
|
||||||
|
* Licensed under the GPL v2, or (at your option) v3
|
||||||
|
*
|
||||||
|
* This gcc plugin constifies all structures which contain only function pointers or are explicitly marked for constification.
|
||||||
|
*
|
||||||
|
* Homepage:
|
||||||
|
* http://www.grsecurity.net/~ephox/const_plugin/
|
||||||
|
*
|
||||||
|
* Usage:
|
||||||
|
* $ gcc -I`gcc -print-file-name=plugin`/include -fPIC -shared -O2 -o constify_plugin.so constify_plugin.c
|
||||||
|
* $ gcc -fplugin=constify_plugin.so test.c -O2
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "gcc-common.h"
|
||||||
|
|
||||||
|
// unused C type flag in all versions 4.5-6
|
||||||
|
#define TYPE_CONSTIFY_VISITED(TYPE) TYPE_LANG_FLAG_4(TYPE)
|
||||||
|
|
||||||
|
__visible int plugin_is_GPL_compatible;
|
||||||
|
|
||||||
|
static bool enabled = true;
|
||||||
|
|
||||||
|
static struct plugin_info const_plugin_info = {
|
||||||
|
.version = "201607241840",
|
||||||
|
.help = "disable\tturn off constification\n",
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct {
|
||||||
|
const char *name;
|
||||||
|
const char *asm_op;
|
||||||
|
} const_sections[] = {
|
||||||
|
{".init.rodata", "\t.section\t.init.rodata,\"a\""},
|
||||||
|
{".ref.rodata", "\t.section\t.ref.rodata,\"a\""},
|
||||||
|
{".devinit.rodata", "\t.section\t.devinit.rodata,\"a\""},
|
||||||
|
{".devexit.rodata", "\t.section\t.devexit.rodata,\"a\""},
|
||||||
|
{".cpuinit.rodata", "\t.section\t.cpuinit.rodata,\"a\""},
|
||||||
|
{".cpuexit.rodata", "\t.section\t.cpuexit.rodata,\"a\""},
|
||||||
|
{".meminit.rodata", "\t.section\t.meminit.rodata,\"a\""},
|
||||||
|
{".memexit.rodata", "\t.section\t.memexit.rodata,\"a\""},
|
||||||
|
{".data..read_only", "\t.section\t.data..read_only,\"a\""},
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
bool has_fptr_field;
|
||||||
|
bool has_writable_field;
|
||||||
|
bool has_do_const_field;
|
||||||
|
bool has_no_const_field;
|
||||||
|
} constify_info;
|
||||||
|
|
||||||
|
static const_tree get_field_type(const_tree field)
|
||||||
|
{
|
||||||
|
return strip_array_types(TREE_TYPE(field));
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool is_fptr(const_tree field)
|
||||||
|
{
|
||||||
|
const_tree ptr = get_field_type(field);
|
||||||
|
|
||||||
|
if (TREE_CODE(ptr) != POINTER_TYPE)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return TREE_CODE(TREE_TYPE(ptr)) == FUNCTION_TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* determine whether the given structure type meets the requirements for automatic constification,
|
||||||
|
* including the constification attributes on nested structure types
|
||||||
|
*/
|
||||||
|
static void constifiable(const_tree node, constify_info *cinfo)
|
||||||
|
{
|
||||||
|
const_tree field;
|
||||||
|
|
||||||
|
gcc_assert(TREE_CODE(node) == RECORD_TYPE || TREE_CODE(node) == UNION_TYPE);
|
||||||
|
|
||||||
|
// e.g., pointer to structure fields while still constructing the structure type
|
||||||
|
if (TYPE_FIELDS(node) == NULL_TREE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (field = TYPE_FIELDS(node); field; field = TREE_CHAIN(field)) {
|
||||||
|
const_tree type = get_field_type(field);
|
||||||
|
enum tree_code code = TREE_CODE(type);
|
||||||
|
|
||||||
|
if (node == type)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (is_fptr(field))
|
||||||
|
cinfo->has_fptr_field = true;
|
||||||
|
else if (code == RECORD_TYPE || code == UNION_TYPE) {
|
||||||
|
if (lookup_attribute("do_const", TYPE_ATTRIBUTES(type)))
|
||||||
|
cinfo->has_do_const_field = true;
|
||||||
|
else if (lookup_attribute("no_const", TYPE_ATTRIBUTES(type)))
|
||||||
|
cinfo->has_no_const_field = true;
|
||||||
|
else
|
||||||
|
constifiable(type, cinfo);
|
||||||
|
} else if (!TREE_READONLY(field))
|
||||||
|
cinfo->has_writable_field = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool constified(const_tree node)
|
||||||
|
{
|
||||||
|
constify_info cinfo = {
|
||||||
|
.has_fptr_field = false,
|
||||||
|
.has_writable_field = false,
|
||||||
|
.has_do_const_field = false,
|
||||||
|
.has_no_const_field = false
|
||||||
|
};
|
||||||
|
|
||||||
|
gcc_assert(TREE_CODE(node) == RECORD_TYPE || TREE_CODE(node) == UNION_TYPE);
|
||||||
|
|
||||||
|
if (lookup_attribute("no_const", TYPE_ATTRIBUTES(node))) {
|
||||||
|
// gcc_assert(!TYPE_READONLY(node));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lookup_attribute("do_const", TYPE_ATTRIBUTES(node))) {
|
||||||
|
gcc_assert(TYPE_READONLY(node));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
constifiable(node, &cinfo);
|
||||||
|
if ((!cinfo.has_fptr_field || cinfo.has_writable_field || cinfo.has_no_const_field) && !cinfo.has_do_const_field)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return TYPE_READONLY(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void deconstify_tree(tree node);
|
||||||
|
|
||||||
|
static void deconstify_type(tree type)
|
||||||
|
{
|
||||||
|
tree field;
|
||||||
|
|
||||||
|
gcc_assert(TREE_CODE(type) == RECORD_TYPE || TREE_CODE(type) == UNION_TYPE);
|
||||||
|
|
||||||
|
for (field = TYPE_FIELDS(type); field; field = TREE_CHAIN(field)) {
|
||||||
|
const_tree fieldtype = get_field_type(field);
|
||||||
|
|
||||||
|
// special case handling of simple ptr-to-same-array-type members
|
||||||
|
if (TREE_CODE(TREE_TYPE(field)) == POINTER_TYPE) {
|
||||||
|
tree ptrtype = TREE_TYPE(TREE_TYPE(field));
|
||||||
|
|
||||||
|
if (TREE_TYPE(TREE_TYPE(field)) == type)
|
||||||
|
continue;
|
||||||
|
if (TREE_CODE(ptrtype) != RECORD_TYPE && TREE_CODE(ptrtype) != UNION_TYPE)
|
||||||
|
continue;
|
||||||
|
if (!constified(ptrtype))
|
||||||
|
continue;
|
||||||
|
if (TYPE_MAIN_VARIANT(ptrtype) == TYPE_MAIN_VARIANT(type))
|
||||||
|
TREE_TYPE(field) = build_pointer_type(build_qualified_type(type, TYPE_QUALS(ptrtype) & ~TYPE_QUAL_CONST));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (TREE_CODE(fieldtype) != RECORD_TYPE && TREE_CODE(fieldtype) != UNION_TYPE)
|
||||||
|
continue;
|
||||||
|
if (!constified(fieldtype))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
deconstify_tree(field);
|
||||||
|
TREE_READONLY(field) = 0;
|
||||||
|
}
|
||||||
|
TYPE_READONLY(type) = 0;
|
||||||
|
C_TYPE_FIELDS_READONLY(type) = 0;
|
||||||
|
if (lookup_attribute("do_const", TYPE_ATTRIBUTES(type))) {
|
||||||
|
TYPE_ATTRIBUTES(type) = copy_list(TYPE_ATTRIBUTES(type));
|
||||||
|
TYPE_ATTRIBUTES(type) = remove_attribute("do_const", TYPE_ATTRIBUTES(type));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void deconstify_tree(tree node)
|
||||||
|
{
|
||||||
|
tree old_type, new_type, field;
|
||||||
|
|
||||||
|
old_type = TREE_TYPE(node);
|
||||||
|
while (TREE_CODE(old_type) == ARRAY_TYPE && TREE_CODE(TREE_TYPE(old_type)) != ARRAY_TYPE) {
|
||||||
|
node = TREE_TYPE(node) = copy_node(old_type);
|
||||||
|
old_type = TREE_TYPE(old_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
gcc_assert(TREE_CODE(old_type) == RECORD_TYPE || TREE_CODE(old_type) == UNION_TYPE);
|
||||||
|
gcc_assert(TYPE_READONLY(old_type) && (TYPE_QUALS(old_type) & TYPE_QUAL_CONST));
|
||||||
|
|
||||||
|
new_type = build_qualified_type(old_type, TYPE_QUALS(old_type) & ~TYPE_QUAL_CONST);
|
||||||
|
TYPE_FIELDS(new_type) = copy_list(TYPE_FIELDS(new_type));
|
||||||
|
for (field = TYPE_FIELDS(new_type); field; field = TREE_CHAIN(field))
|
||||||
|
DECL_FIELD_CONTEXT(field) = new_type;
|
||||||
|
|
||||||
|
deconstify_type(new_type);
|
||||||
|
|
||||||
|
TREE_TYPE(node) = new_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
static tree handle_no_const_attribute(tree *node, tree name, tree args __unused, int flags __unused, bool *no_add_attrs)
|
||||||
|
{
|
||||||
|
tree type;
|
||||||
|
constify_info cinfo = {
|
||||||
|
.has_fptr_field = false,
|
||||||
|
.has_writable_field = false,
|
||||||
|
.has_do_const_field = false,
|
||||||
|
.has_no_const_field = false
|
||||||
|
};
|
||||||
|
|
||||||
|
*no_add_attrs = true;
|
||||||
|
if (TREE_CODE(*node) == FUNCTION_DECL) {
|
||||||
|
error("%qE attribute does not apply to functions (%qF)", name, *node);
|
||||||
|
return NULL_TREE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TREE_CODE(*node) == PARM_DECL) {
|
||||||
|
error("%qE attribute does not apply to function parameters (%qD)", name, *node);
|
||||||
|
return NULL_TREE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TREE_CODE(*node) == VAR_DECL) {
|
||||||
|
error("%qE attribute does not apply to variables (%qD)", name, *node);
|
||||||
|
return NULL_TREE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TYPE_P(*node)) {
|
||||||
|
type = *node;
|
||||||
|
} else {
|
||||||
|
if (TREE_CODE(*node) != TYPE_DECL) {
|
||||||
|
error("%qE attribute does not apply to %qD (%qT)", name, *node, TREE_TYPE(*node));
|
||||||
|
return NULL_TREE;
|
||||||
|
}
|
||||||
|
type = TREE_TYPE(*node);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TREE_CODE(type) != RECORD_TYPE && TREE_CODE(type) != UNION_TYPE) {
|
||||||
|
error("%qE attribute used on %qT applies to struct and union types only", name, type);
|
||||||
|
return NULL_TREE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lookup_attribute(IDENTIFIER_POINTER(name), TYPE_ATTRIBUTES(type))) {
|
||||||
|
error("%qE attribute is already applied to the type %qT", name, type);
|
||||||
|
return NULL_TREE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TYPE_P(*node)) {
|
||||||
|
if (lookup_attribute("do_const", TYPE_ATTRIBUTES(type)))
|
||||||
|
error("%qE attribute used on type %qT is incompatible with 'do_const'", name, type);
|
||||||
|
else
|
||||||
|
*no_add_attrs = false;
|
||||||
|
return NULL_TREE;
|
||||||
|
}
|
||||||
|
|
||||||
|
constifiable(type, &cinfo);
|
||||||
|
if ((cinfo.has_fptr_field && !cinfo.has_writable_field && !cinfo.has_no_const_field) || lookup_attribute("do_const", TYPE_ATTRIBUTES(type))) {
|
||||||
|
if (enabled) {
|
||||||
|
if TYPE_P(*node)
|
||||||
|
deconstify_type(*node);
|
||||||
|
else
|
||||||
|
deconstify_tree(*node);
|
||||||
|
}
|
||||||
|
if (TYPE_P(*node))
|
||||||
|
TYPE_CONSTIFY_VISITED(*node) = 1;
|
||||||
|
else
|
||||||
|
TYPE_CONSTIFY_VISITED(TREE_TYPE(*node)) = 1;
|
||||||
|
return NULL_TREE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (enabled && TYPE_FIELDS(type))
|
||||||
|
error("%qE attribute used on type %qT that is not constified", name, type);
|
||||||
|
return NULL_TREE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void constify_type(tree type)
|
||||||
|
{
|
||||||
|
gcc_assert(type == TYPE_MAIN_VARIANT(type));
|
||||||
|
TYPE_READONLY(type) = 1;
|
||||||
|
C_TYPE_FIELDS_READONLY(type) = 1;
|
||||||
|
TYPE_CONSTIFY_VISITED(type) = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static tree handle_do_const_attribute(tree *node, tree name, tree args __unused, int flags __unused, bool *no_add_attrs)
|
||||||
|
{
|
||||||
|
*no_add_attrs = true;
|
||||||
|
if (!TYPE_P(*node)) {
|
||||||
|
error("%qE attribute applies to types only (%qD)", name, *node);
|
||||||
|
return NULL_TREE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TREE_CODE(*node) != RECORD_TYPE && TREE_CODE(*node) != UNION_TYPE) {
|
||||||
|
error("%qE attribute used on %qT applies to struct and union types only", name, *node);
|
||||||
|
return NULL_TREE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lookup_attribute(IDENTIFIER_POINTER(name), TYPE_ATTRIBUTES(*node))) {
|
||||||
|
error("%qE attribute used on %qT is already applied to the type", name, *node);
|
||||||
|
return NULL_TREE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lookup_attribute("no_const", TYPE_ATTRIBUTES(*node))) {
|
||||||
|
error("%qE attribute used on %qT is incompatible with 'no_const'", name, *node);
|
||||||
|
return NULL_TREE;
|
||||||
|
}
|
||||||
|
|
||||||
|
*no_add_attrs = false;
|
||||||
|
return NULL_TREE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct attribute_spec no_const_attr = {
|
||||||
|
.name = "no_const",
|
||||||
|
.min_length = 0,
|
||||||
|
.max_length = 0,
|
||||||
|
.decl_required = false,
|
||||||
|
.type_required = false,
|
||||||
|
.function_type_required = false,
|
||||||
|
.handler = handle_no_const_attribute,
|
||||||
|
#if BUILDING_GCC_VERSION >= 4007
|
||||||
|
.affects_type_identity = true
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct attribute_spec do_const_attr = {
|
||||||
|
.name = "do_const",
|
||||||
|
.min_length = 0,
|
||||||
|
.max_length = 0,
|
||||||
|
.decl_required = false,
|
||||||
|
.type_required = false,
|
||||||
|
.function_type_required = false,
|
||||||
|
.handler = handle_do_const_attribute,
|
||||||
|
#if BUILDING_GCC_VERSION >= 4007
|
||||||
|
.affects_type_identity = true
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
static void register_attributes(void *event_data, void *data)
|
||||||
|
{
|
||||||
|
register_attribute(&no_const_attr);
|
||||||
|
register_attribute(&do_const_attr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void finish_type(void *event_data, void *data __unused)
|
||||||
|
{
|
||||||
|
tree type = (tree)event_data;
|
||||||
|
constify_info cinfo = {
|
||||||
|
.has_fptr_field = false,
|
||||||
|
.has_writable_field = false,
|
||||||
|
.has_do_const_field = false,
|
||||||
|
.has_no_const_field = false
|
||||||
|
};
|
||||||
|
|
||||||
|
if (type == NULL_TREE || type == error_mark_node)
|
||||||
|
return;
|
||||||
|
|
||||||
|
#if BUILDING_GCC_VERSION >= 5000
|
||||||
|
if (TREE_CODE(type) == ENUMERAL_TYPE)
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (TYPE_FIELDS(type) == NULL_TREE || TYPE_CONSTIFY_VISITED(type))
|
||||||
|
return;
|
||||||
|
|
||||||
|
constifiable(type, &cinfo);
|
||||||
|
|
||||||
|
if (lookup_attribute("no_const", TYPE_ATTRIBUTES(type))) {
|
||||||
|
if ((cinfo.has_fptr_field && !cinfo.has_writable_field && !cinfo.has_no_const_field) || cinfo.has_do_const_field) {
|
||||||
|
deconstify_type(type);
|
||||||
|
TYPE_CONSTIFY_VISITED(type) = 1;
|
||||||
|
} else
|
||||||
|
error("'no_const' attribute used on type %qT that is not constified", type);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lookup_attribute("do_const", TYPE_ATTRIBUTES(type))) {
|
||||||
|
if (!cinfo.has_writable_field && !cinfo.has_no_const_field) {
|
||||||
|
error("'do_const' attribute used on type %qT that is%sconstified", type, cinfo.has_fptr_field ? " " : " not ");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
constify_type(type);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cinfo.has_fptr_field && !cinfo.has_writable_field && !cinfo.has_no_const_field) {
|
||||||
|
if (lookup_attribute("do_const", TYPE_ATTRIBUTES(type))) {
|
||||||
|
error("'do_const' attribute used on type %qT that is constified", type);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
constify_type(type);
|
||||||
|
// TYPE_ATTRIBUTES(type) = copy_list(TYPE_ATTRIBUTES(type));
|
||||||
|
// TYPE_ATTRIBUTES(type) = tree_cons(get_identifier("do_const"), NULL_TREE, TYPE_ATTRIBUTES(type));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
deconstify_type(type);
|
||||||
|
TYPE_CONSTIFY_VISITED(type) = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool is_constified_var(varpool_node_ptr node)
|
||||||
|
{
|
||||||
|
tree var = NODE_DECL(node);
|
||||||
|
tree type = TREE_TYPE(var);
|
||||||
|
|
||||||
|
if (node->alias)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (DECL_EXTERNAL(var))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// XXX handle more complex nesting of arrays/structs
|
||||||
|
if (TREE_CODE(type) == ARRAY_TYPE)
|
||||||
|
type = TREE_TYPE(type);
|
||||||
|
|
||||||
|
if (TREE_CODE(type) != RECORD_TYPE && TREE_CODE(type) != UNION_TYPE)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!TYPE_READONLY(type) || !C_TYPE_FIELDS_READONLY(type))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!TYPE_CONSTIFY_VISITED(type))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void check_section_mismatch(varpool_node_ptr node)
|
||||||
|
{
|
||||||
|
tree var, section;
|
||||||
|
size_t i;
|
||||||
|
const char *name;
|
||||||
|
|
||||||
|
var = NODE_DECL(node);
|
||||||
|
name = get_decl_section_name(var);
|
||||||
|
section = lookup_attribute("section", DECL_ATTRIBUTES(var));
|
||||||
|
if (!section) {
|
||||||
|
if (name) {
|
||||||
|
fprintf(stderr, "DECL_SECTION [%s] ", name);
|
||||||
|
dump_varpool_node(stderr, node);
|
||||||
|
gcc_unreachable();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
} else
|
||||||
|
gcc_assert(name);
|
||||||
|
|
||||||
|
//fprintf(stderr, "SECTIONAME: [%s] ", get_decl_section_name(var));
|
||||||
|
//debug_tree(var);
|
||||||
|
|
||||||
|
gcc_assert(!TREE_CHAIN(section));
|
||||||
|
gcc_assert(TREE_VALUE(section));
|
||||||
|
|
||||||
|
section = TREE_VALUE(TREE_VALUE(section));
|
||||||
|
gcc_assert(!strcmp(TREE_STRING_POINTER(section), name));
|
||||||
|
//debug_tree(section);
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(const_sections); i++)
|
||||||
|
if (!strcmp(const_sections[i].name, name))
|
||||||
|
return;
|
||||||
|
|
||||||
|
error_at(DECL_SOURCE_LOCATION(var), "constified variable %qD placed into writable section %E", var, section);
|
||||||
|
}
|
||||||
|
|
||||||
|
// this works around a gcc bug/feature where uninitialized globals
|
||||||
|
// are moved into the .bss section regardless of any constification
|
||||||
|
// see gcc/varasm.c:bss_initializer_p()
|
||||||
|
static void fix_initializer(varpool_node_ptr node)
|
||||||
|
{
|
||||||
|
tree var = NODE_DECL(node);
|
||||||
|
tree type = TREE_TYPE(var);
|
||||||
|
|
||||||
|
if (DECL_INITIAL(var))
|
||||||
|
return;
|
||||||
|
|
||||||
|
DECL_INITIAL(var) = build_constructor(type, NULL);
|
||||||
|
// inform(DECL_SOURCE_LOCATION(var), "constified variable %qE moved into .rodata", var);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void check_global_variables(void *event_data __unused, void *data __unused)
|
||||||
|
{
|
||||||
|
varpool_node_ptr node;
|
||||||
|
|
||||||
|
FOR_EACH_VARIABLE(node) {
|
||||||
|
if (!is_constified_var(node))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
check_section_mismatch(node);
|
||||||
|
fix_initializer(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned int check_local_variables_execute(void)
|
||||||
|
{
|
||||||
|
unsigned int ret = 0;
|
||||||
|
tree var;
|
||||||
|
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
FOR_EACH_LOCAL_DECL(cfun, i, var) {
|
||||||
|
tree type = TREE_TYPE(var);
|
||||||
|
|
||||||
|
gcc_assert(DECL_P(var));
|
||||||
|
if (is_global_var(var))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (TREE_CODE(type) != RECORD_TYPE && TREE_CODE(type) != UNION_TYPE)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!TYPE_READONLY(type) || !C_TYPE_FIELDS_READONLY(type))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!TYPE_CONSTIFY_VISITED(type))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
error_at(DECL_SOURCE_LOCATION(var), "constified variable %qE cannot be local", var);
|
||||||
|
ret = 1;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define PASS_NAME check_local_variables
|
||||||
|
#define NO_GATE
|
||||||
|
#include "gcc-generate-gimple-pass.h"
|
||||||
|
|
||||||
|
static unsigned int (*old_section_type_flags)(tree decl, const char *name, int reloc);
|
||||||
|
|
||||||
|
static unsigned int constify_section_type_flags(tree decl, const char *name, int reloc)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(const_sections); i++)
|
||||||
|
if (!strcmp(const_sections[i].name, name))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return old_section_type_flags(decl, name, reloc);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void constify_start_unit(void *gcc_data __unused, void *user_data __unused)
|
||||||
|
{
|
||||||
|
// size_t i;
|
||||||
|
|
||||||
|
// for (i = 0; i < ARRAY_SIZE(const_sections); i++)
|
||||||
|
// const_sections[i].section = get_unnamed_section(0, output_section_asm_op, const_sections[i].asm_op);
|
||||||
|
// const_sections[i].section = get_section(const_sections[i].name, 0, NULL);
|
||||||
|
|
||||||
|
old_section_type_flags = targetm.section_type_flags;
|
||||||
|
targetm.section_type_flags = constify_section_type_flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
__visible int plugin_init(struct plugin_name_args *plugin_info, struct plugin_gcc_version *version)
|
||||||
|
{
|
||||||
|
const char * const plugin_name = plugin_info->base_name;
|
||||||
|
const int argc = plugin_info->argc;
|
||||||
|
const struct plugin_argument * const argv = plugin_info->argv;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
PASS_INFO(check_local_variables, "ssa", 1, PASS_POS_INSERT_BEFORE);
|
||||||
|
|
||||||
|
if (!plugin_default_version_check(version, &gcc_version)) {
|
||||||
|
error_gcc_version(version);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < argc; ++i) {
|
||||||
|
if (!(strcmp(argv[i].key, "disable"))) {
|
||||||
|
enabled = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
error(G_("unknown option '-fplugin-arg-%s-%s'"), plugin_name, argv[i].key);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strncmp(lang_hooks.name, "GNU C", 5) && !strncmp(lang_hooks.name, "GNU C+", 6)) {
|
||||||
|
inform(UNKNOWN_LOCATION, G_("%s supports C only, not %s"), plugin_name, lang_hooks.name);
|
||||||
|
enabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
register_callback(plugin_name, PLUGIN_INFO, NULL, &const_plugin_info);
|
||||||
|
if (enabled) {
|
||||||
|
register_callback(plugin_name, PLUGIN_ALL_IPA_PASSES_START, check_global_variables, NULL);
|
||||||
|
register_callback(plugin_name, PLUGIN_FINISH_TYPE, finish_type, NULL);
|
||||||
|
register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &check_local_variables_pass_info);
|
||||||
|
register_callback(plugin_name, PLUGIN_START_UNIT, constify_start_unit, NULL);
|
||||||
|
}
|
||||||
|
register_callback(plugin_name, PLUGIN_ATTRIBUTES, register_attributes, NULL);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,69 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2011-2017 by Emese Revfy <re.emese@gmail.com>
|
||||||
|
* Licensed under the GPL v2, or (at your option) v3
|
||||||
|
*
|
||||||
|
* Homepage:
|
||||||
|
* https://github.com/ephox-gcc-plugins/cyclomatic_complexity
|
||||||
|
*
|
||||||
|
* http://en.wikipedia.org/wiki/Cyclomatic_complexity
|
||||||
|
* The complexity M is then defined as:
|
||||||
|
* M = E - N + 2P
|
||||||
|
* where
|
||||||
|
*
|
||||||
|
* E = the number of edges of the graph
|
||||||
|
* N = the number of nodes of the graph
|
||||||
|
* P = the number of connected components (exit nodes).
|
||||||
|
*
|
||||||
|
* Usage (4.5 - 5):
|
||||||
|
* $ make clean; make run
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "gcc-common.h"
|
||||||
|
|
||||||
|
__visible int plugin_is_GPL_compatible;
|
||||||
|
|
||||||
|
static struct plugin_info cyc_complexity_plugin_info = {
|
||||||
|
.version = "20160225",
|
||||||
|
.help = "Cyclomatic Complexity\n",
|
||||||
|
};
|
||||||
|
|
||||||
|
static unsigned int cyc_complexity_execute(void)
|
||||||
|
{
|
||||||
|
int complexity;
|
||||||
|
expanded_location xloc;
|
||||||
|
|
||||||
|
/* M = E - N + 2P */
|
||||||
|
complexity = n_edges_for_fn(cfun) - n_basic_blocks_for_fn(cfun) + 2;
|
||||||
|
|
||||||
|
xloc = expand_location(DECL_SOURCE_LOCATION(current_function_decl));
|
||||||
|
fprintf(stderr, "Cyclomatic Complexity %d %s:%s\n", complexity,
|
||||||
|
xloc.file, DECL_NAME_POINTER(current_function_decl));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define PASS_NAME cyc_complexity
|
||||||
|
|
||||||
|
#define NO_GATE
|
||||||
|
#define TODO_FLAGS_FINISH TODO_dump_func
|
||||||
|
|
||||||
|
#include "gcc-generate-gimple-pass.h"
|
||||||
|
|
||||||
|
__visible int plugin_init(struct plugin_name_args *plugin_info, struct plugin_gcc_version *version)
|
||||||
|
{
|
||||||
|
const char * const plugin_name = plugin_info->base_name;
|
||||||
|
|
||||||
|
PASS_INFO(cyc_complexity, "ssa", 1, PASS_POS_INSERT_AFTER);
|
||||||
|
|
||||||
|
if (!plugin_default_version_check(version, &gcc_version)) {
|
||||||
|
error_gcc_version(version);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
register_callback(plugin_name, PLUGIN_INFO, NULL,
|
||||||
|
&cyc_complexity_plugin_info);
|
||||||
|
register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL,
|
||||||
|
&cyc_complexity_pass_info);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -21,14 +21,22 @@
|
||||||
#include "rtl.h"
|
#include "rtl.h"
|
||||||
#include "tm_p.h"
|
#include "tm_p.h"
|
||||||
#include "flags.h"
|
#include "flags.h"
|
||||||
|
//#include "insn-attr.h"
|
||||||
|
//#include "insn-config.h"
|
||||||
|
//#include "insn-flags.h"
|
||||||
#include "hard-reg-set.h"
|
#include "hard-reg-set.h"
|
||||||
|
//#include "recog.h"
|
||||||
#include "output.h"
|
#include "output.h"
|
||||||
#include "except.h"
|
#include "except.h"
|
||||||
#include "function.h"
|
#include "function.h"
|
||||||
#include "toplev.h"
|
#include "toplev.h"
|
||||||
|
#if BUILDING_GCC_VERSION >= 5000
|
||||||
|
#include "expr.h"
|
||||||
|
#endif
|
||||||
#include "basic-block.h"
|
#include "basic-block.h"
|
||||||
#include "intl.h"
|
#include "intl.h"
|
||||||
#include "ggc.h"
|
#include "ggc.h"
|
||||||
|
//#include "regs.h"
|
||||||
#include "timevar.h"
|
#include "timevar.h"
|
||||||
|
|
||||||
#include "params.h"
|
#include "params.h"
|
||||||
|
@ -43,12 +51,18 @@
|
||||||
#include "memmodel.h"
|
#include "memmodel.h"
|
||||||
#endif
|
#endif
|
||||||
#include "emit-rtl.h"
|
#include "emit-rtl.h"
|
||||||
|
//#include "reload.h"
|
||||||
|
//#include "ira.h"
|
||||||
|
//#include "dwarf2asm.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "target.h"
|
#include "target.h"
|
||||||
#include "langhooks.h"
|
#include "langhooks.h"
|
||||||
#include "cfgloop.h"
|
#include "cfgloop.h"
|
||||||
|
//#include "hosthooks.h"
|
||||||
#include "cgraph.h"
|
#include "cgraph.h"
|
||||||
#include "opts.h"
|
#include "opts.h"
|
||||||
|
//#include "coverage.h"
|
||||||
|
//#include "value-prof.h"
|
||||||
|
|
||||||
#if BUILDING_GCC_VERSION == 4005
|
#if BUILDING_GCC_VERSION == 4005
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
|
@ -60,6 +74,8 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if BUILDING_GCC_VERSION >= 4006
|
#if BUILDING_GCC_VERSION >= 4006
|
||||||
|
//#include "c-tree.h"
|
||||||
|
//#include "cp/cp-tree.h"
|
||||||
#include "c-family/c-common.h"
|
#include "c-family/c-common.h"
|
||||||
#else
|
#else
|
||||||
#include "c-common.h"
|
#include "c-common.h"
|
||||||
|
@ -78,8 +94,13 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "diagnostic.h"
|
#include "diagnostic.h"
|
||||||
|
//#include "tree-diagnostic.h"
|
||||||
#include "tree-dump.h"
|
#include "tree-dump.h"
|
||||||
#include "tree-pass.h"
|
#include "tree-pass.h"
|
||||||
|
#if BUILDING_GCC_VERSION >= 4009
|
||||||
|
#include "pass_manager.h"
|
||||||
|
#endif
|
||||||
|
//#include "df.h"
|
||||||
#include "predict.h"
|
#include "predict.h"
|
||||||
#include "ipa-utils.h"
|
#include "ipa-utils.h"
|
||||||
|
|
||||||
|
@ -90,6 +111,7 @@
|
||||||
#include "internal-fn.h"
|
#include "internal-fn.h"
|
||||||
#include "gimple-expr.h"
|
#include "gimple-expr.h"
|
||||||
#include "gimple-fold.h"
|
#include "gimple-fold.h"
|
||||||
|
//#include "diagnostic-color.h"
|
||||||
#include "context.h"
|
#include "context.h"
|
||||||
#include "tree-ssa-alias.h"
|
#include "tree-ssa-alias.h"
|
||||||
#include "tree-ssa.h"
|
#include "tree-ssa.h"
|
||||||
|
@ -115,28 +137,34 @@
|
||||||
#include "ssa-iterators.h"
|
#include "ssa-iterators.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
//#include "lto/lto.h"
|
||||||
|
#if BUILDING_GCC_VERSION >= 4007
|
||||||
|
//#include "data-streamer.h"
|
||||||
|
#else
|
||||||
|
//#include "lto-streamer.h"
|
||||||
|
#endif
|
||||||
|
//#include "lto-compress.h"
|
||||||
#if BUILDING_GCC_VERSION >= 5000
|
#if BUILDING_GCC_VERSION >= 5000
|
||||||
|
//#include "lto-section-names.h"
|
||||||
#include "builtins.h"
|
#include "builtins.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* #include "expr.h" where are you... */
|
|
||||||
extern rtx emit_move_insn(rtx x, rtx y);
|
|
||||||
|
|
||||||
/* missing from basic_block.h... */
|
/* missing from basic_block.h... */
|
||||||
extern void debug_dominance_info(enum cdi_direction dir);
|
void debug_dominance_info(enum cdi_direction dir);
|
||||||
extern void debug_dominance_tree(enum cdi_direction dir, basic_block root);
|
void debug_dominance_tree(enum cdi_direction dir, basic_block root);
|
||||||
|
|
||||||
#if BUILDING_GCC_VERSION == 4006
|
#if BUILDING_GCC_VERSION == 4006
|
||||||
extern void debug_gimple_stmt(gimple);
|
void debug_gimple_stmt(gimple);
|
||||||
extern void debug_gimple_seq(gimple_seq);
|
void debug_gimple_seq(gimple_seq);
|
||||||
extern void print_gimple_seq(FILE *, gimple_seq, int, int);
|
void print_gimple_seq(FILE *, gimple_seq, int, int);
|
||||||
extern void print_gimple_stmt(FILE *, gimple, int, int);
|
void print_gimple_stmt(FILE *, gimple, int, int);
|
||||||
extern void print_gimple_expr(FILE *, gimple, int, int);
|
void print_gimple_expr(FILE *, gimple, int, int);
|
||||||
extern void dump_gimple_stmt(pretty_printer *, gimple, int, int);
|
void dump_gimple_stmt(pretty_printer *, gimple, int, int);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define __unused __attribute__((__unused__))
|
#define __unused __attribute__((unused))
|
||||||
#define __visible __attribute__((visibility("default")))
|
#define __visible __attribute__((visibility("default")))
|
||||||
|
#define __weak __attribute__((weak))
|
||||||
|
|
||||||
#define DECL_NAME_POINTER(node) IDENTIFIER_POINTER(DECL_NAME(node))
|
#define DECL_NAME_POINTER(node) IDENTIFIER_POINTER(DECL_NAME(node))
|
||||||
#define DECL_NAME_LENGTH(node) IDENTIFIER_LENGTH(DECL_NAME(node))
|
#define DECL_NAME_LENGTH(node) IDENTIFIER_LENGTH(DECL_NAME(node))
|
||||||
|
@ -146,6 +174,36 @@ extern void dump_gimple_stmt(pretty_printer *, gimple, int, int);
|
||||||
/* should come from c-tree.h if only it were installed for gcc 4.5... */
|
/* should come from c-tree.h if only it were installed for gcc 4.5... */
|
||||||
#define C_TYPE_FIELDS_READONLY(TYPE) TREE_LANG_FLAG_1(TYPE)
|
#define C_TYPE_FIELDS_READONLY(TYPE) TREE_LANG_FLAG_1(TYPE)
|
||||||
|
|
||||||
|
static inline tree build_const_char_string(int len, const char *str)
|
||||||
|
{
|
||||||
|
tree cstr, elem, index, type;
|
||||||
|
|
||||||
|
cstr = build_string(len, str);
|
||||||
|
elem = build_type_variant(char_type_node, 1, 0);
|
||||||
|
index = build_index_type(size_int(len - 1));
|
||||||
|
type = build_array_type(elem, index);
|
||||||
|
TREE_TYPE(cstr) = type;
|
||||||
|
TREE_CONSTANT(cstr) = 1;
|
||||||
|
TREE_READONLY(cstr) = 1;
|
||||||
|
TREE_STATIC(cstr) = 1;
|
||||||
|
return cstr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void error_gcc_version(struct plugin_gcc_version *version)
|
||||||
|
{
|
||||||
|
error(G_("incompatible gcc/plugin versions: need %s %s %s %s but have %s %s %s %s"),
|
||||||
|
gcc_version.basever, gcc_version.datestamp, gcc_version.devphase, gcc_version.revision,
|
||||||
|
version->basever, version->datestamp, version->devphase, version->revision);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define PASS_INFO(NAME, REF, ID, POS) \
|
||||||
|
struct register_pass_info NAME##_pass_info = { \
|
||||||
|
.pass = make_##NAME##_pass(), \
|
||||||
|
.reference_pass_name = REF, \
|
||||||
|
.ref_pass_instance_number = ID, \
|
||||||
|
.pos_op = POS, \
|
||||||
|
}
|
||||||
|
|
||||||
#if BUILDING_GCC_VERSION == 4005
|
#if BUILDING_GCC_VERSION == 4005
|
||||||
#define FOR_EACH_LOCAL_DECL(FUN, I, D) \
|
#define FOR_EACH_LOCAL_DECL(FUN, I, D) \
|
||||||
for (tree vars = (FUN)->local_decls, (I) = 0; \
|
for (tree vars = (FUN)->local_decls, (I) = 0; \
|
||||||
|
@ -172,6 +230,7 @@ static inline bool gimple_call_builtin_p(gimple stmt, enum built_in_function cod
|
||||||
fndecl = gimple_call_fndecl(stmt);
|
fndecl = gimple_call_fndecl(stmt);
|
||||||
if (!fndecl || DECL_BUILT_IN_CLASS(fndecl) != BUILT_IN_NORMAL)
|
if (!fndecl || DECL_BUILT_IN_CLASS(fndecl) != BUILT_IN_NORMAL)
|
||||||
return false;
|
return false;
|
||||||
|
// print_node(stderr, "pax", fndecl, 4);
|
||||||
return DECL_FUNCTION_CODE(fndecl) == code;
|
return DECL_FUNCTION_CODE(fndecl) == code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -345,6 +404,23 @@ static inline bool gimple_store_p(gimple gs)
|
||||||
static inline void gimple_init_singleton(gimple g __unused)
|
static inline void gimple_init_singleton(gimple g __unused)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum expand_modifier {
|
||||||
|
EXPAND_NORMAL = 0,
|
||||||
|
EXPAND_STACK_PARM,
|
||||||
|
EXPAND_SUM,
|
||||||
|
EXPAND_CONST_ADDRESS,
|
||||||
|
EXPAND_INITIALIZER,
|
||||||
|
EXPAND_WRITE,
|
||||||
|
EXPAND_MEMORY
|
||||||
|
};
|
||||||
|
|
||||||
|
rtx expand_expr_real(tree, rtx, enum machine_mode, enum expand_modifier, rtx *);
|
||||||
|
|
||||||
|
static inline rtx expand_expr(tree exp, rtx target, enum machine_mode mode, enum expand_modifier modifier)
|
||||||
|
{
|
||||||
|
return expand_expr_real(exp, target, mode, modifier, NULL);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if BUILDING_GCC_VERSION == 4007 || BUILDING_GCC_VERSION == 4008
|
#if BUILDING_GCC_VERSION == 4007 || BUILDING_GCC_VERSION == 4008
|
||||||
|
@ -518,6 +594,28 @@ static inline const greturn *as_a_const_greturn(const_gimple stmt)
|
||||||
#define create_var_ann(var)
|
#define create_var_ann(var)
|
||||||
#define TODO_dump_func 0
|
#define TODO_dump_func 0
|
||||||
#define TODO_dump_cgraph 0
|
#define TODO_dump_cgraph 0
|
||||||
|
|
||||||
|
#define VEC(T, A) vec<T, va_##A>
|
||||||
|
#define VEC_safe_push(T, A, V, O) vec_safe_push((V), (O));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if BUILDING_GCC_VERSION == 4008 || BUILDING_GCC_VERSION == 4009
|
||||||
|
enum expand_modifier {
|
||||||
|
EXPAND_NORMAL = 0,
|
||||||
|
EXPAND_STACK_PARM,
|
||||||
|
EXPAND_SUM,
|
||||||
|
EXPAND_CONST_ADDRESS,
|
||||||
|
EXPAND_INITIALIZER,
|
||||||
|
EXPAND_WRITE,
|
||||||
|
EXPAND_MEMORY
|
||||||
|
};
|
||||||
|
|
||||||
|
rtx expand_expr_real(tree, rtx, enum machine_mode, enum expand_modifier, rtx *, bool);
|
||||||
|
|
||||||
|
static inline rtx expand_expr(tree exp, rtx target, enum machine_mode mode, enum expand_modifier modifier)
|
||||||
|
{
|
||||||
|
return expand_expr_real(exp, target, mode, modifier, NULL, false);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if BUILDING_GCC_VERSION <= 4009
|
#if BUILDING_GCC_VERSION <= 4009
|
||||||
|
@ -527,6 +625,8 @@ static inline const greturn *as_a_const_greturn(const_gimple stmt)
|
||||||
#define section_name_prefix LTO_SECTION_NAME_PREFIX
|
#define section_name_prefix LTO_SECTION_NAME_PREFIX
|
||||||
#define fatal_error(loc, gmsgid, ...) fatal_error((gmsgid), __VA_ARGS__)
|
#define fatal_error(loc, gmsgid, ...) fatal_error((gmsgid), __VA_ARGS__)
|
||||||
|
|
||||||
|
rtx emit_move_insn(rtx x, rtx y);
|
||||||
|
|
||||||
typedef struct rtx_def rtx_insn;
|
typedef struct rtx_def rtx_insn;
|
||||||
|
|
||||||
static inline const char *get_decl_section_name(const_tree decl)
|
static inline const char *get_decl_section_name(const_tree decl)
|
||||||
|
@ -643,6 +743,11 @@ static inline const greturn *as_a_const_greturn(const_gimple stmt)
|
||||||
#define NODE_DECL(node) (node)->decl
|
#define NODE_DECL(node) (node)->decl
|
||||||
#define cgraph_node_name(node) (node)->name()
|
#define cgraph_node_name(node) (node)->name()
|
||||||
#define NODE_IMPLICIT_ALIAS(node) (node)->cpp_implicit_alias
|
#define NODE_IMPLICIT_ALIAS(node) (node)->cpp_implicit_alias
|
||||||
|
|
||||||
|
static inline opt_pass *get_pass_for_id(int id)
|
||||||
|
{
|
||||||
|
return g->get_passes()->get_pass_for_id(id);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if BUILDING_GCC_VERSION >= 5000 && BUILDING_GCC_VERSION < 6000
|
#if BUILDING_GCC_VERSION >= 5000 && BUILDING_GCC_VERSION < 6000
|
||||||
|
@ -661,6 +766,8 @@ inline bool is_a_helper<const gassign *>::test(const_gimple gs)
|
||||||
#define TODO_verify_stmts TODO_verify_il
|
#define TODO_verify_stmts TODO_verify_il
|
||||||
#define TODO_verify_rtl_sharing TODO_verify_il
|
#define TODO_verify_rtl_sharing TODO_verify_il
|
||||||
|
|
||||||
|
//#define TREE_INT_CST_HIGH(NODE) ({ TREE_INT_CST_EXT_NUNITS(NODE) > 1 ? (unsigned HOST_WIDE_INT)TREE_INT_CST_ELT(NODE, 1) : 0; })
|
||||||
|
|
||||||
#define INSN_DELETED_P(insn) (insn)->deleted()
|
#define INSN_DELETED_P(insn) (insn)->deleted()
|
||||||
|
|
||||||
static inline const char *get_decl_section_name(const_tree decl)
|
static inline const char *get_decl_section_name(const_tree decl)
|
||||||
|
@ -908,6 +1015,11 @@ static inline void debug_gimple_stmt(const_gimple s)
|
||||||
#define debug_gimple_stmt(s) debug_gimple_stmt(CONST_CAST_GIMPLE(s))
|
#define debug_gimple_stmt(s) debug_gimple_stmt(CONST_CAST_GIMPLE(s))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if BUILDING_GCC_VERSION < 7001
|
||||||
|
#define SET_DECL_ALIGN(n, a) ({ DECL_ALIGN(n) = (a); })
|
||||||
|
#define SET_DECL_MODE(n, m) ({ DECL_MODE(n) = (m); })
|
||||||
|
#endif
|
||||||
|
|
||||||
#if BUILDING_GCC_VERSION >= 7000
|
#if BUILDING_GCC_VERSION >= 7000
|
||||||
#define get_inner_reference(exp, pbitsize, pbitpos, poffset, pmode, punsignedp, preversep, pvolatilep, keep_aligning) \
|
#define get_inner_reference(exp, pbitsize, pbitpos, poffset, pmode, punsignedp, preversep, pvolatilep, keep_aligning) \
|
||||||
get_inner_reference(exp, pbitsize, pbitpos, poffset, pmode, punsignedp, preversep, pvolatilep)
|
get_inner_reference(exp, pbitsize, pbitpos, poffset, pmode, punsignedp, preversep, pvolatilep)
|
||||||
|
|
|
@ -119,7 +119,7 @@ public:
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
virtual opt_pass * clone () { return new _PASS_NAME_PASS(); }
|
virtual opt_pass *clone() { return new _PASS_NAME_PASS(); }
|
||||||
|
|
||||||
#ifndef NO_EXECUTE
|
#ifndef NO_EXECUTE
|
||||||
#if BUILDING_GCC_VERSION >= 5000
|
#if BUILDING_GCC_VERSION >= 5000
|
||||||
|
@ -136,6 +136,7 @@ opt_pass *_MAKE_PASS_NAME_PASS(void)
|
||||||
return new _PASS_NAME_PASS();
|
return new _PASS_NAME_PASS();
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
struct opt_pass *_MAKE_PASS_NAME_PASS(void);
|
||||||
struct opt_pass *_MAKE_PASS_NAME_PASS(void)
|
struct opt_pass *_MAKE_PASS_NAME_PASS(void)
|
||||||
{
|
{
|
||||||
return &_PASS_NAME_PASS.pass;
|
return &_PASS_NAME_PASS.pass;
|
||||||
|
|
|
@ -225,6 +225,7 @@ opt_pass *_MAKE_PASS_NAME_PASS(void)
|
||||||
return new _PASS_NAME_PASS();
|
return new _PASS_NAME_PASS();
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
struct opt_pass *_MAKE_PASS_NAME_PASS(void);
|
||||||
struct opt_pass *_MAKE_PASS_NAME_PASS(void)
|
struct opt_pass *_MAKE_PASS_NAME_PASS(void)
|
||||||
{
|
{
|
||||||
return &_PASS_NAME_PASS.pass;
|
return &_PASS_NAME_PASS.pass;
|
||||||
|
|
|
@ -136,6 +136,7 @@ opt_pass *_MAKE_PASS_NAME_PASS(void)
|
||||||
return new _PASS_NAME_PASS();
|
return new _PASS_NAME_PASS();
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
struct opt_pass *_MAKE_PASS_NAME_PASS(void);
|
||||||
struct opt_pass *_MAKE_PASS_NAME_PASS(void)
|
struct opt_pass *_MAKE_PASS_NAME_PASS(void)
|
||||||
{
|
{
|
||||||
return &_PASS_NAME_PASS.pass;
|
return &_PASS_NAME_PASS.pass;
|
||||||
|
|
|
@ -136,6 +136,7 @@ opt_pass *_MAKE_PASS_NAME_PASS(void)
|
||||||
return new _PASS_NAME_PASS();
|
return new _PASS_NAME_PASS();
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
struct opt_pass *_MAKE_PASS_NAME_PASS(void);
|
||||||
struct opt_pass *_MAKE_PASS_NAME_PASS(void)
|
struct opt_pass *_MAKE_PASS_NAME_PASS(void)
|
||||||
{
|
{
|
||||||
return &_PASS_NAME_PASS.pass;
|
return &_PASS_NAME_PASS.pass;
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
if [ ! -f "$1" ]; then
|
||||||
|
SEED=`od -A n -t x8 -N 32 /dev/urandom | tr -d ' \n'`
|
||||||
|
echo "const char *randstruct_seed = \"$SEED\";" > "$1"
|
||||||
|
HASH=`echo -n "$SEED" | sha256sum | cut -d" " -f1 | tr -d ' \n'`
|
||||||
|
echo "#define RANDSTRUCT_HASHED_SEED \"$HASH\"" > "$2"
|
||||||
|
fi
|
|
@ -0,0 +1,74 @@
|
||||||
|
/****************************************************************************
|
||||||
|
* *
|
||||||
|
* GNAT COMPILER COMPONENTS *
|
||||||
|
* *
|
||||||
|
* GNAT-SPECIFIC GCC TREE CODES *
|
||||||
|
* *
|
||||||
|
* Specification *
|
||||||
|
* *
|
||||||
|
* Copyright (C) 1992-2009, Free Software Foundation, Inc. *
|
||||||
|
* *
|
||||||
|
* GNAT is free software; you can redistribute it and/or modify it under *
|
||||||
|
* terms of the GNU General Public License as published by the Free Soft- *
|
||||||
|
* ware Foundation; either version 3, or (at your option) any later ver- *
|
||||||
|
* sion. GNAT is distributed in the hope that it will be useful, but WITH- *
|
||||||
|
* OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
|
||||||
|
* for more details. You should have received a copy of the GNU General *
|
||||||
|
* Public License along with GCC; see the file COPYING3. If not see *
|
||||||
|
* <http://www.gnu.org/licenses/>. *
|
||||||
|
* *
|
||||||
|
* GNAT was originally developed by the GNAT team at New York University. *
|
||||||
|
* Extensive contributions were provided by Ada Core Technologies Inc. *
|
||||||
|
* *
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/* A type that is an unconstrained array. This node is never passed to GCC.
|
||||||
|
TREE_TYPE is the type of the fat pointer and TYPE_OBJECT_RECORD_TYPE is
|
||||||
|
the type of a record containing the template and data. */
|
||||||
|
DEFTREECODE (UNCONSTRAINED_ARRAY_TYPE, "unconstrained_array_type", tcc_type, 0)
|
||||||
|
|
||||||
|
/* A reference to an unconstrained array. This node only exists as an
|
||||||
|
intermediate node during the translation of a GNAT tree to a GCC tree;
|
||||||
|
it is never passed to GCC. The only field used is operand 0, which
|
||||||
|
is the fat pointer object. */
|
||||||
|
DEFTREECODE (UNCONSTRAINED_ARRAY_REF, "unconstrained_array_ref",
|
||||||
|
tcc_reference, 1)
|
||||||
|
|
||||||
|
/* An expression that returns an RTL suitable for its type. Operand 0
|
||||||
|
is an expression to be evaluated for side effects only. */
|
||||||
|
DEFTREECODE (NULL_EXPR, "null_expr", tcc_expression, 1)
|
||||||
|
|
||||||
|
/* Same as PLUS_EXPR, except that no modulo reduction is applied.
|
||||||
|
This is used for loops and never shows up in the tree. */
|
||||||
|
DEFTREECODE (PLUS_NOMOD_EXPR, "plus_nomod_expr", tcc_binary, 2)
|
||||||
|
|
||||||
|
/* Same as MINUS_EXPR, except that no modulo reduction is applied.
|
||||||
|
This is used for loops and never shows up in the tree. */
|
||||||
|
DEFTREECODE (MINUS_NOMOD_EXPR, "minus_nomod_expr", tcc_binary, 2)
|
||||||
|
|
||||||
|
/* Same as ADDR_EXPR, except that if the operand represents a bit field,
|
||||||
|
return the address of the byte containing the bit. This is used
|
||||||
|
for the Address attribute and never shows up in the tree. */
|
||||||
|
DEFTREECODE (ATTR_ADDR_EXPR, "attr_addr_expr", tcc_reference, 1)
|
||||||
|
|
||||||
|
/* Here are the tree codes for the statement types known to Ada. These
|
||||||
|
must be at the end of this file to allow IS_ADA_STMT to work. */
|
||||||
|
|
||||||
|
/* This is how record_code_position and insert_code_for work. The former
|
||||||
|
makes this tree node, whose operand is a statement. The latter inserts
|
||||||
|
the actual statements into this node. Gimplification consists of
|
||||||
|
just returning the inner statement. */
|
||||||
|
DEFTREECODE (STMT_STMT, "stmt_stmt", tcc_statement, 1)
|
||||||
|
|
||||||
|
/* A loop. LOOP_STMT_COND is the test to exit the loop. LOOP_STMT_UPDATE
|
||||||
|
is the statement to update the loop iteration variable at the continue
|
||||||
|
point. LOOP_STMT_BODY are the statements in the body of the loop. And
|
||||||
|
LOOP_STMT_LABEL points to the LABEL_DECL of the end label of the loop. */
|
||||||
|
DEFTREECODE (LOOP_STMT, "loop_stmt", tcc_statement, 4)
|
||||||
|
|
||||||
|
/* Conditionally exit a loop. EXIT_STMT_COND is the condition, which, if
|
||||||
|
true, will cause the loop to be exited. If no condition is specified,
|
||||||
|
the loop is unconditionally exited. EXIT_STMT_LABEL is the end label
|
||||||
|
corresponding to the loop to exit. */
|
||||||
|
DEFTREECODE (EXIT_STMT, "exit_stmt", tcc_statement, 2)
|
|
@ -0,0 +1,51 @@
|
||||||
|
/* Exported functions from alias.c
|
||||||
|
Copyright (C) 2004-2013 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free
|
||||||
|
Software Foundation; either version 3, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GCC; see the file COPYING3. If not see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#ifndef GCC_ALIAS_H
|
||||||
|
#define GCC_ALIAS_H
|
||||||
|
|
||||||
|
/* The type of an alias set. Code currently assumes that variables of
|
||||||
|
this type can take the values 0 (the alias set which aliases
|
||||||
|
everything) and -1 (sometimes indicating that the alias set is
|
||||||
|
unknown, sometimes indicating a memory barrier) and -2 (indicating
|
||||||
|
that the alias set should be set to a unique value but has not been
|
||||||
|
set yet). */
|
||||||
|
typedef int alias_set_type;
|
||||||
|
|
||||||
|
extern alias_set_type new_alias_set (void);
|
||||||
|
extern alias_set_type get_alias_set (tree);
|
||||||
|
extern alias_set_type get_deref_alias_set (tree);
|
||||||
|
extern alias_set_type get_varargs_alias_set (void);
|
||||||
|
extern alias_set_type get_frame_alias_set (void);
|
||||||
|
extern bool component_uses_parent_alias_set (const_tree);
|
||||||
|
extern bool alias_set_subset_of (alias_set_type, alias_set_type);
|
||||||
|
extern void record_alias_subset (alias_set_type, alias_set_type);
|
||||||
|
extern void record_component_aliases (tree);
|
||||||
|
extern int alias_sets_conflict_p (alias_set_type, alias_set_type);
|
||||||
|
extern int alias_sets_must_conflict_p (alias_set_type, alias_set_type);
|
||||||
|
extern int objects_must_conflict_p (tree, tree);
|
||||||
|
extern int nonoverlapping_memrefs_p (const_rtx, const_rtx, bool);
|
||||||
|
|
||||||
|
/* This alias set can be used to force a memory to conflict with all
|
||||||
|
other memories, creating a barrier across which no memory reference
|
||||||
|
can move. Note that there are other legacy ways to create such
|
||||||
|
memory barriers, including an address of SCRATCH. */
|
||||||
|
#define ALIAS_SET_MEMORY_BARRIER ((alias_set_type) -1)
|
||||||
|
|
||||||
|
#endif /* GCC_ALIAS_H */
|
|
@ -0,0 +1,7 @@
|
||||||
|
#include "tree.def"
|
||||||
|
END_OF_BASE_TREE_CODES
|
||||||
|
#include "c-family/c-common.def"
|
||||||
|
#include "ada/gcc-interface/ada-tree.def"
|
||||||
|
#include "cp/cp-tree.def"
|
||||||
|
#include "java/java-tree.def"
|
||||||
|
#include "objc/objc-tree.def"
|
|
@ -0,0 +1,66 @@
|
||||||
|
/* Functions to support a pool of allocatable objects
|
||||||
|
Copyright (C) 1997-2013 Free Software Foundation, Inc.
|
||||||
|
Contributed by Daniel Berlin <dan@cgsoftware.com>
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GCC; see the file COPYING3. If not see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
#ifndef ALLOC_POOL_H
|
||||||
|
#define ALLOC_POOL_H
|
||||||
|
|
||||||
|
typedef unsigned long ALLOC_POOL_ID_TYPE;
|
||||||
|
|
||||||
|
typedef struct alloc_pool_list_def
|
||||||
|
{
|
||||||
|
struct alloc_pool_list_def *next;
|
||||||
|
}
|
||||||
|
*alloc_pool_list;
|
||||||
|
|
||||||
|
typedef struct alloc_pool_def
|
||||||
|
{
|
||||||
|
const char *name;
|
||||||
|
#ifdef ENABLE_CHECKING
|
||||||
|
ALLOC_POOL_ID_TYPE id;
|
||||||
|
#endif
|
||||||
|
size_t elts_per_block;
|
||||||
|
|
||||||
|
/* These are the elements that have been allocated at least once and freed. */
|
||||||
|
alloc_pool_list returned_free_list;
|
||||||
|
|
||||||
|
/* These are the elements that have not yet been allocated out of
|
||||||
|
the last block obtained from XNEWVEC. */
|
||||||
|
char* virgin_free_list;
|
||||||
|
|
||||||
|
/* The number of elements in the virgin_free_list that can be
|
||||||
|
allocated before needing another block. */
|
||||||
|
size_t virgin_elts_remaining;
|
||||||
|
|
||||||
|
size_t elts_allocated;
|
||||||
|
size_t elts_free;
|
||||||
|
size_t blocks_allocated;
|
||||||
|
alloc_pool_list block_list;
|
||||||
|
size_t block_size;
|
||||||
|
size_t elt_size;
|
||||||
|
}
|
||||||
|
*alloc_pool;
|
||||||
|
|
||||||
|
extern alloc_pool create_alloc_pool (const char *, size_t, size_t);
|
||||||
|
extern void free_alloc_pool (alloc_pool);
|
||||||
|
extern void empty_alloc_pool (alloc_pool);
|
||||||
|
extern void free_alloc_pool_if_empty (alloc_pool *);
|
||||||
|
extern void *pool_alloc (alloc_pool) ATTRIBUTE_MALLOC;
|
||||||
|
extern void pool_free (alloc_pool, void *);
|
||||||
|
extern void dump_alloc_pool_statistics (void);
|
||||||
|
#endif
|
|
@ -0,0 +1,441 @@
|
||||||
|
/* ANSI and traditional C compatability macros
|
||||||
|
Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
|
||||||
|
2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010
|
||||||
|
Free Software Foundation, Inc.
|
||||||
|
This file is part of the GNU C Library.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||||
|
|
||||||
|
/* ANSI and traditional C compatibility macros
|
||||||
|
|
||||||
|
ANSI C is assumed if __STDC__ is #defined.
|
||||||
|
|
||||||
|
Macro ANSI C definition Traditional C definition
|
||||||
|
----- ---- - ---------- ----------- - ----------
|
||||||
|
ANSI_PROTOTYPES 1 not defined
|
||||||
|
PTR `void *' `char *'
|
||||||
|
PTRCONST `void *const' `char *'
|
||||||
|
LONG_DOUBLE `long double' `double'
|
||||||
|
const not defined `'
|
||||||
|
volatile not defined `'
|
||||||
|
signed not defined `'
|
||||||
|
VA_START(ap, var) va_start(ap, var) va_start(ap)
|
||||||
|
|
||||||
|
Note that it is safe to write "void foo();" indicating a function
|
||||||
|
with no return value, in all K+R compilers we have been able to test.
|
||||||
|
|
||||||
|
For declaring functions with prototypes, we also provide these:
|
||||||
|
|
||||||
|
PARAMS ((prototype))
|
||||||
|
-- for functions which take a fixed number of arguments. Use this
|
||||||
|
when declaring the function. When defining the function, write a
|
||||||
|
K+R style argument list. For example:
|
||||||
|
|
||||||
|
char *strcpy PARAMS ((char *dest, char *source));
|
||||||
|
...
|
||||||
|
char *
|
||||||
|
strcpy (dest, source)
|
||||||
|
char *dest;
|
||||||
|
char *source;
|
||||||
|
{ ... }
|
||||||
|
|
||||||
|
|
||||||
|
VPARAMS ((prototype, ...))
|
||||||
|
-- for functions which take a variable number of arguments. Use
|
||||||
|
PARAMS to declare the function, VPARAMS to define it. For example:
|
||||||
|
|
||||||
|
int printf PARAMS ((const char *format, ...));
|
||||||
|
...
|
||||||
|
int
|
||||||
|
printf VPARAMS ((const char *format, ...))
|
||||||
|
{
|
||||||
|
...
|
||||||
|
}
|
||||||
|
|
||||||
|
For writing functions which take variable numbers of arguments, we
|
||||||
|
also provide the VA_OPEN, VA_CLOSE, and VA_FIXEDARG macros. These
|
||||||
|
hide the differences between K+R <varargs.h> and C89 <stdarg.h> more
|
||||||
|
thoroughly than the simple VA_START() macro mentioned above.
|
||||||
|
|
||||||
|
VA_OPEN and VA_CLOSE are used *instead of* va_start and va_end.
|
||||||
|
Immediately after VA_OPEN, put a sequence of VA_FIXEDARG calls
|
||||||
|
corresponding to the list of fixed arguments. Then use va_arg
|
||||||
|
normally to get the variable arguments, or pass your va_list object
|
||||||
|
around. You do not declare the va_list yourself; VA_OPEN does it
|
||||||
|
for you.
|
||||||
|
|
||||||
|
Here is a complete example:
|
||||||
|
|
||||||
|
int
|
||||||
|
printf VPARAMS ((const char *format, ...))
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
|
||||||
|
VA_OPEN (ap, format);
|
||||||
|
VA_FIXEDARG (ap, const char *, format);
|
||||||
|
|
||||||
|
result = vfprintf (stdout, format, ap);
|
||||||
|
VA_CLOSE (ap);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
You can declare variables either before or after the VA_OPEN,
|
||||||
|
VA_FIXEDARG sequence. Also, VA_OPEN and VA_CLOSE are the beginning
|
||||||
|
and end of a block. They must appear at the same nesting level,
|
||||||
|
and any variables declared after VA_OPEN go out of scope at
|
||||||
|
VA_CLOSE. Unfortunately, with a K+R compiler, that includes the
|
||||||
|
argument list. You can have multiple instances of VA_OPEN/VA_CLOSE
|
||||||
|
pairs in a single function in case you need to traverse the
|
||||||
|
argument list more than once.
|
||||||
|
|
||||||
|
For ease of writing code which uses GCC extensions but needs to be
|
||||||
|
portable to other compilers, we provide the GCC_VERSION macro that
|
||||||
|
simplifies testing __GNUC__ and __GNUC_MINOR__ together, and various
|
||||||
|
wrappers around __attribute__. Also, __extension__ will be #defined
|
||||||
|
to nothing if it doesn't work. See below.
|
||||||
|
|
||||||
|
This header also defines a lot of obsolete macros:
|
||||||
|
CONST, VOLATILE, SIGNED, PROTO, EXFUN, DEFUN, DEFUN_VOID,
|
||||||
|
AND, DOTS, NOARGS. Don't use them. */
|
||||||
|
|
||||||
|
#ifndef _ANSIDECL_H
|
||||||
|
#define _ANSIDECL_H 1
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Every source file includes this file,
|
||||||
|
so they will all get the switch for lint. */
|
||||||
|
/* LINTLIBRARY */
|
||||||
|
|
||||||
|
/* Using MACRO(x,y) in cpp #if conditionals does not work with some
|
||||||
|
older preprocessors. Thus we can't define something like this:
|
||||||
|
|
||||||
|
#define HAVE_GCC_VERSION(MAJOR, MINOR) \
|
||||||
|
(__GNUC__ > (MAJOR) || (__GNUC__ == (MAJOR) && __GNUC_MINOR__ >= (MINOR)))
|
||||||
|
|
||||||
|
and then test "#if HAVE_GCC_VERSION(2,7)".
|
||||||
|
|
||||||
|
So instead we use the macro below and test it against specific values. */
|
||||||
|
|
||||||
|
/* This macro simplifies testing whether we are using gcc, and if it
|
||||||
|
is of a particular minimum version. (Both major & minor numbers are
|
||||||
|
significant.) This macro will evaluate to 0 if we are not using
|
||||||
|
gcc at all. */
|
||||||
|
#ifndef GCC_VERSION
|
||||||
|
#define GCC_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__)
|
||||||
|
#endif /* GCC_VERSION */
|
||||||
|
|
||||||
|
#if defined (__STDC__) || defined(__cplusplus) || defined (_AIX) || (defined (__mips) && defined (_SYSTYPE_SVR4)) || defined(_WIN32)
|
||||||
|
/* All known AIX compilers implement these things (but don't always
|
||||||
|
define __STDC__). The RISC/OS MIPS compiler defines these things
|
||||||
|
in SVR4 mode, but does not define __STDC__. */
|
||||||
|
/* eraxxon@alumni.rice.edu: The Compaq C++ compiler, unlike many other
|
||||||
|
C++ compilers, does not define __STDC__, though it acts as if this
|
||||||
|
was so. (Verified versions: 5.7, 6.2, 6.3, 6.5) */
|
||||||
|
|
||||||
|
#define ANSI_PROTOTYPES 1
|
||||||
|
#define PTR void *
|
||||||
|
#define PTRCONST void *const
|
||||||
|
#define LONG_DOUBLE long double
|
||||||
|
|
||||||
|
/* PARAMS is often defined elsewhere (e.g. by libintl.h), so wrap it in
|
||||||
|
a #ifndef. */
|
||||||
|
#ifndef PARAMS
|
||||||
|
#define PARAMS(ARGS) ARGS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define VPARAMS(ARGS) ARGS
|
||||||
|
#define VA_START(VA_LIST, VAR) va_start(VA_LIST, VAR)
|
||||||
|
|
||||||
|
/* variadic function helper macros */
|
||||||
|
/* "struct Qdmy" swallows the semicolon after VA_OPEN/VA_FIXEDARG's
|
||||||
|
use without inhibiting further decls and without declaring an
|
||||||
|
actual variable. */
|
||||||
|
#define VA_OPEN(AP, VAR) { va_list AP; va_start(AP, VAR); { struct Qdmy
|
||||||
|
#define VA_CLOSE(AP) } va_end(AP); }
|
||||||
|
#define VA_FIXEDARG(AP, T, N) struct Qdmy
|
||||||
|
|
||||||
|
#undef const
|
||||||
|
#undef volatile
|
||||||
|
#undef signed
|
||||||
|
|
||||||
|
/* inline requires special treatment; it's in C99, and GCC >=2.7 supports
|
||||||
|
it too, but it's not in C89. */
|
||||||
|
#undef inline
|
||||||
|
#if __STDC_VERSION__ >= 199901L || defined(__cplusplus) || (defined(__SUNPRO_C) && defined(__C99FEATURES__))
|
||||||
|
/* it's a keyword */
|
||||||
|
#else
|
||||||
|
# if GCC_VERSION >= 2007
|
||||||
|
# define inline __inline__ /* __inline__ prevents -pedantic warnings */
|
||||||
|
# else
|
||||||
|
# define inline /* nothing */
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* These are obsolete. Do not use. */
|
||||||
|
#ifndef IN_GCC
|
||||||
|
#define CONST const
|
||||||
|
#define VOLATILE volatile
|
||||||
|
#define SIGNED signed
|
||||||
|
|
||||||
|
#define PROTO(type, name, arglist) type name arglist
|
||||||
|
#define EXFUN(name, proto) name proto
|
||||||
|
#define DEFUN(name, arglist, args) name(args)
|
||||||
|
#define DEFUN_VOID(name) name(void)
|
||||||
|
#define AND ,
|
||||||
|
#define DOTS , ...
|
||||||
|
#define NOARGS void
|
||||||
|
#endif /* ! IN_GCC */
|
||||||
|
|
||||||
|
#else /* Not ANSI C. */
|
||||||
|
|
||||||
|
#undef ANSI_PROTOTYPES
|
||||||
|
#define PTR char *
|
||||||
|
#define PTRCONST PTR
|
||||||
|
#define LONG_DOUBLE double
|
||||||
|
|
||||||
|
#define PARAMS(args) ()
|
||||||
|
#define VPARAMS(args) (va_alist) va_dcl
|
||||||
|
#define VA_START(va_list, var) va_start(va_list)
|
||||||
|
|
||||||
|
#define VA_OPEN(AP, VAR) { va_list AP; va_start(AP); { struct Qdmy
|
||||||
|
#define VA_CLOSE(AP) } va_end(AP); }
|
||||||
|
#define VA_FIXEDARG(AP, TYPE, NAME) TYPE NAME = va_arg(AP, TYPE)
|
||||||
|
|
||||||
|
/* some systems define these in header files for non-ansi mode */
|
||||||
|
#undef const
|
||||||
|
#undef volatile
|
||||||
|
#undef signed
|
||||||
|
#undef inline
|
||||||
|
#define const
|
||||||
|
#define volatile
|
||||||
|
#define signed
|
||||||
|
#define inline
|
||||||
|
|
||||||
|
#ifndef IN_GCC
|
||||||
|
#define CONST
|
||||||
|
#define VOLATILE
|
||||||
|
#define SIGNED
|
||||||
|
|
||||||
|
#define PROTO(type, name, arglist) type name ()
|
||||||
|
#define EXFUN(name, proto) name()
|
||||||
|
#define DEFUN(name, arglist, args) name arglist args;
|
||||||
|
#define DEFUN_VOID(name) name()
|
||||||
|
#define AND ;
|
||||||
|
#define DOTS
|
||||||
|
#define NOARGS
|
||||||
|
#endif /* ! IN_GCC */
|
||||||
|
|
||||||
|
#endif /* ANSI C. */
|
||||||
|
|
||||||
|
/* Define macros for some gcc attributes. This permits us to use the
|
||||||
|
macros freely, and know that they will come into play for the
|
||||||
|
version of gcc in which they are supported. */
|
||||||
|
|
||||||
|
#if (GCC_VERSION < 2007)
|
||||||
|
# define __attribute__(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Attribute __malloc__ on functions was valid as of gcc 2.96. */
|
||||||
|
#ifndef ATTRIBUTE_MALLOC
|
||||||
|
# if (GCC_VERSION >= 2096)
|
||||||
|
# define ATTRIBUTE_MALLOC __attribute__ ((__malloc__))
|
||||||
|
# else
|
||||||
|
# define ATTRIBUTE_MALLOC
|
||||||
|
# endif /* GNUC >= 2.96 */
|
||||||
|
#endif /* ATTRIBUTE_MALLOC */
|
||||||
|
|
||||||
|
/* Attributes on labels were valid as of gcc 2.93 and g++ 4.5. For
|
||||||
|
g++ an attribute on a label must be followed by a semicolon. */
|
||||||
|
#ifndef ATTRIBUTE_UNUSED_LABEL
|
||||||
|
# ifndef __cplusplus
|
||||||
|
# if GCC_VERSION >= 2093
|
||||||
|
# define ATTRIBUTE_UNUSED_LABEL ATTRIBUTE_UNUSED
|
||||||
|
# else
|
||||||
|
# define ATTRIBUTE_UNUSED_LABEL
|
||||||
|
# endif
|
||||||
|
# else
|
||||||
|
# if GCC_VERSION >= 4005
|
||||||
|
# define ATTRIBUTE_UNUSED_LABEL ATTRIBUTE_UNUSED ;
|
||||||
|
# else
|
||||||
|
# define ATTRIBUTE_UNUSED_LABEL
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Similarly to ARG_UNUSED below. Prior to GCC 3.4, the C++ frontend
|
||||||
|
couldn't parse attributes placed after the identifier name, and now
|
||||||
|
the entire compiler is built with C++. */
|
||||||
|
#ifndef ATTRIBUTE_UNUSED
|
||||||
|
#if GCC_VERSION >= 3004
|
||||||
|
# define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
|
||||||
|
#else
|
||||||
|
#define ATTRIBUTE_UNUSED
|
||||||
|
#endif
|
||||||
|
#endif /* ATTRIBUTE_UNUSED */
|
||||||
|
|
||||||
|
/* Before GCC 3.4, the C++ frontend couldn't parse attributes placed after the
|
||||||
|
identifier name. */
|
||||||
|
#if ! defined(__cplusplus) || (GCC_VERSION >= 3004)
|
||||||
|
# define ARG_UNUSED(NAME) NAME ATTRIBUTE_UNUSED
|
||||||
|
#else /* !__cplusplus || GNUC >= 3.4 */
|
||||||
|
# define ARG_UNUSED(NAME) NAME
|
||||||
|
#endif /* !__cplusplus || GNUC >= 3.4 */
|
||||||
|
|
||||||
|
#ifndef ATTRIBUTE_NORETURN
|
||||||
|
#define ATTRIBUTE_NORETURN __attribute__ ((__noreturn__))
|
||||||
|
#endif /* ATTRIBUTE_NORETURN */
|
||||||
|
|
||||||
|
/* Attribute `nonnull' was valid as of gcc 3.3. */
|
||||||
|
#ifndef ATTRIBUTE_NONNULL
|
||||||
|
# if (GCC_VERSION >= 3003)
|
||||||
|
# define ATTRIBUTE_NONNULL(m) __attribute__ ((__nonnull__ (m)))
|
||||||
|
# else
|
||||||
|
# define ATTRIBUTE_NONNULL(m)
|
||||||
|
# endif /* GNUC >= 3.3 */
|
||||||
|
#endif /* ATTRIBUTE_NONNULL */
|
||||||
|
|
||||||
|
/* Attribute `pure' was valid as of gcc 3.0. */
|
||||||
|
#ifndef ATTRIBUTE_PURE
|
||||||
|
# if (GCC_VERSION >= 3000)
|
||||||
|
# define ATTRIBUTE_PURE __attribute__ ((__pure__))
|
||||||
|
# else
|
||||||
|
# define ATTRIBUTE_PURE
|
||||||
|
# endif /* GNUC >= 3.0 */
|
||||||
|
#endif /* ATTRIBUTE_PURE */
|
||||||
|
|
||||||
|
/* Use ATTRIBUTE_PRINTF when the format specifier must not be NULL.
|
||||||
|
This was the case for the `printf' format attribute by itself
|
||||||
|
before GCC 3.3, but as of 3.3 we need to add the `nonnull'
|
||||||
|
attribute to retain this behavior. */
|
||||||
|
#ifndef ATTRIBUTE_PRINTF
|
||||||
|
#define ATTRIBUTE_PRINTF(m, n) __attribute__ ((__format__ (__printf__, m, n))) ATTRIBUTE_NONNULL(m)
|
||||||
|
#define ATTRIBUTE_PRINTF_1 ATTRIBUTE_PRINTF(1, 2)
|
||||||
|
#define ATTRIBUTE_PRINTF_2 ATTRIBUTE_PRINTF(2, 3)
|
||||||
|
#define ATTRIBUTE_PRINTF_3 ATTRIBUTE_PRINTF(3, 4)
|
||||||
|
#define ATTRIBUTE_PRINTF_4 ATTRIBUTE_PRINTF(4, 5)
|
||||||
|
#define ATTRIBUTE_PRINTF_5 ATTRIBUTE_PRINTF(5, 6)
|
||||||
|
#endif /* ATTRIBUTE_PRINTF */
|
||||||
|
|
||||||
|
/* Use ATTRIBUTE_FPTR_PRINTF when the format attribute is to be set on
|
||||||
|
a function pointer. Format attributes were allowed on function
|
||||||
|
pointers as of gcc 3.1. */
|
||||||
|
#ifndef ATTRIBUTE_FPTR_PRINTF
|
||||||
|
# if (GCC_VERSION >= 3001)
|
||||||
|
# define ATTRIBUTE_FPTR_PRINTF(m, n) ATTRIBUTE_PRINTF(m, n)
|
||||||
|
# else
|
||||||
|
# define ATTRIBUTE_FPTR_PRINTF(m, n)
|
||||||
|
# endif /* GNUC >= 3.1 */
|
||||||
|
# define ATTRIBUTE_FPTR_PRINTF_1 ATTRIBUTE_FPTR_PRINTF(1, 2)
|
||||||
|
# define ATTRIBUTE_FPTR_PRINTF_2 ATTRIBUTE_FPTR_PRINTF(2, 3)
|
||||||
|
# define ATTRIBUTE_FPTR_PRINTF_3 ATTRIBUTE_FPTR_PRINTF(3, 4)
|
||||||
|
# define ATTRIBUTE_FPTR_PRINTF_4 ATTRIBUTE_FPTR_PRINTF(4, 5)
|
||||||
|
# define ATTRIBUTE_FPTR_PRINTF_5 ATTRIBUTE_FPTR_PRINTF(5, 6)
|
||||||
|
#endif /* ATTRIBUTE_FPTR_PRINTF */
|
||||||
|
|
||||||
|
/* Use ATTRIBUTE_NULL_PRINTF when the format specifier may be NULL. A
|
||||||
|
NULL format specifier was allowed as of gcc 3.3. */
|
||||||
|
#ifndef ATTRIBUTE_NULL_PRINTF
|
||||||
|
# if (GCC_VERSION >= 3003)
|
||||||
|
# define ATTRIBUTE_NULL_PRINTF(m, n) __attribute__ ((__format__ (__printf__, m, n)))
|
||||||
|
# else
|
||||||
|
# define ATTRIBUTE_NULL_PRINTF(m, n)
|
||||||
|
# endif /* GNUC >= 3.3 */
|
||||||
|
# define ATTRIBUTE_NULL_PRINTF_1 ATTRIBUTE_NULL_PRINTF(1, 2)
|
||||||
|
# define ATTRIBUTE_NULL_PRINTF_2 ATTRIBUTE_NULL_PRINTF(2, 3)
|
||||||
|
# define ATTRIBUTE_NULL_PRINTF_3 ATTRIBUTE_NULL_PRINTF(3, 4)
|
||||||
|
# define ATTRIBUTE_NULL_PRINTF_4 ATTRIBUTE_NULL_PRINTF(4, 5)
|
||||||
|
# define ATTRIBUTE_NULL_PRINTF_5 ATTRIBUTE_NULL_PRINTF(5, 6)
|
||||||
|
#endif /* ATTRIBUTE_NULL_PRINTF */
|
||||||
|
|
||||||
|
/* Attribute `sentinel' was valid as of gcc 3.5. */
|
||||||
|
#ifndef ATTRIBUTE_SENTINEL
|
||||||
|
# if (GCC_VERSION >= 3005)
|
||||||
|
# define ATTRIBUTE_SENTINEL __attribute__ ((__sentinel__))
|
||||||
|
# else
|
||||||
|
# define ATTRIBUTE_SENTINEL
|
||||||
|
# endif /* GNUC >= 3.5 */
|
||||||
|
#endif /* ATTRIBUTE_SENTINEL */
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef ATTRIBUTE_ALIGNED_ALIGNOF
|
||||||
|
# if (GCC_VERSION >= 3000)
|
||||||
|
# define ATTRIBUTE_ALIGNED_ALIGNOF(m) __attribute__ ((__aligned__ (__alignof__ (m))))
|
||||||
|
# else
|
||||||
|
# define ATTRIBUTE_ALIGNED_ALIGNOF(m)
|
||||||
|
# endif /* GNUC >= 3.0 */
|
||||||
|
#endif /* ATTRIBUTE_ALIGNED_ALIGNOF */
|
||||||
|
|
||||||
|
/* Useful for structures whose layout must much some binary specification
|
||||||
|
regardless of the alignment and padding qualities of the compiler. */
|
||||||
|
#ifndef ATTRIBUTE_PACKED
|
||||||
|
# define ATTRIBUTE_PACKED __attribute__ ((packed))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Attribute `hot' and `cold' was valid as of gcc 4.3. */
|
||||||
|
#ifndef ATTRIBUTE_COLD
|
||||||
|
# if (GCC_VERSION >= 4003)
|
||||||
|
# define ATTRIBUTE_COLD __attribute__ ((__cold__))
|
||||||
|
# else
|
||||||
|
# define ATTRIBUTE_COLD
|
||||||
|
# endif /* GNUC >= 4.3 */
|
||||||
|
#endif /* ATTRIBUTE_COLD */
|
||||||
|
#ifndef ATTRIBUTE_HOT
|
||||||
|
# if (GCC_VERSION >= 4003)
|
||||||
|
# define ATTRIBUTE_HOT __attribute__ ((__hot__))
|
||||||
|
# else
|
||||||
|
# define ATTRIBUTE_HOT
|
||||||
|
# endif /* GNUC >= 4.3 */
|
||||||
|
#endif /* ATTRIBUTE_HOT */
|
||||||
|
|
||||||
|
/* We use __extension__ in some places to suppress -pedantic warnings
|
||||||
|
about GCC extensions. This feature didn't work properly before
|
||||||
|
gcc 2.8. */
|
||||||
|
#if GCC_VERSION < 2008
|
||||||
|
#define __extension__
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* This is used to declare a const variable which should be visible
|
||||||
|
outside of the current compilation unit. Use it as
|
||||||
|
EXPORTED_CONST int i = 1;
|
||||||
|
This is because the semantics of const are different in C and C++.
|
||||||
|
"extern const" is permitted in C but it looks strange, and gcc
|
||||||
|
warns about it when -Wc++-compat is not used. */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
#define EXPORTED_CONST extern const
|
||||||
|
#else
|
||||||
|
#define EXPORTED_CONST const
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Be conservative and only use enum bitfields with C++ or GCC.
|
||||||
|
FIXME: provide a complete autoconf test for buggy enum bitfields. */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
#define ENUM_BITFIELD(TYPE) enum TYPE
|
||||||
|
#elif (GCC_VERSION > 2000)
|
||||||
|
#define ENUM_BITFIELD(TYPE) __extension__ enum TYPE
|
||||||
|
#else
|
||||||
|
#define ENUM_BITFIELD(TYPE) unsigned int
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* ansidecl.h */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,121 @@
|
||||||
|
USER_H=xsaveoptintrin.h mm_malloc.h
|
||||||
|
HASHTAB_H=hashtab.h
|
||||||
|
OBSTACK_H=obstack.h
|
||||||
|
SPLAY_TREE_H=splay-tree.h
|
||||||
|
FIBHEAP_H=fibheap.h
|
||||||
|
PARTITION_H=partition.h
|
||||||
|
DWARF2_H=dwarf2.def
|
||||||
|
XREGEX_H=xregex.h
|
||||||
|
FNMATCH_H=fnmatch.h
|
||||||
|
LINKER_PLUGIN_API_H=plugin-api.h
|
||||||
|
LTO_SYMTAB_H=lto-symtab.h
|
||||||
|
BCONFIG_H=bconfig.h auto-host.h ansidecl.h
|
||||||
|
CONFIG_H=config.h auto-host.h ansidecl.h
|
||||||
|
TCONFIG_H=tconfig.h auto-host.h ansidecl.h
|
||||||
|
TM_P_H=tm_p.h config/i386/i386-protos.h tm-preds.h
|
||||||
|
GTM_H=tm.h options.h config/vxworks-dummy.h defaults.h insn-constants.h
|
||||||
|
TM_H=tm.h options.h config/vxworks-dummy.h i386-opts.h
|
||||||
|
VEC_H=vec.h statistics.h ggc.h gtype-desc.h statistics.h
|
||||||
|
HASH_TABLE_H=hashtab.h hash-table.h
|
||||||
|
EXCEPT_H=except.h hashtab.h
|
||||||
|
TARGET_H=tm.h options.h config/vxworks-dummy.h i386-opts.h target.h target.def target-hooks-macros.h insn-modes.h
|
||||||
|
C_TARGET_H=c-family/c-target.h c-family/c-target.def target-hooks-macros.h
|
||||||
|
COMMON_TARGET_H=common/common-target.h common-target.def target-hooks-macros.h
|
||||||
|
MACHMODE_H=machmode.h mode-classes.def insn-modes.h
|
||||||
|
HOOKS_H=hooks.h machmode.h mode-classes.def insn-modes.h
|
||||||
|
HOSTHOOKS_DEF_H=hosthooks-def.h hooks.h machmode.h mode-classes.def insn-modes.h
|
||||||
|
LANGHOOKS_DEF_H=langhooks-def.h hooks.h machmode.h mode-classes.def insn-modes.h
|
||||||
|
TARGET_DEF_H=target-def.h target-hooks-def.h hooks.h machmode.h mode-classes.def insn-modes.h targhooks.h
|
||||||
|
C_TARGET_DEF_H=c-family/c-target-def.h c-family/c-target-hooks-def.h coretypes.h tree.h all-tree.def tree.def c-family/c-common.def common-targhooks.h
|
||||||
|
COMMON_TARGET_DEF_H=common/common-target-def.h common/common-target-hooks-def.h hooks.h machmode.h mode-classes.def insn-modes.h
|
||||||
|
RTL_BASE_H=coretypes.h rtl.h rtl.def machmode.h mode-classes.def insn-modes.h reg-notes.def insn-notes.def hashtab.h
|
||||||
|
FIXED_VALUE_H=fixed-value.h machmode.h mode-classes.def insn-modes.h double-int.h
|
||||||
|
RTL_H=coretypes.h rtl.h rtl.def machmode.h mode-classes.def insn-modes.h reg-notes.def insn-notes.def i386-opts.h genrtl.h
|
||||||
|
RTL_ERROR_H=rtl-error.h coretypes.h rtl.h rtl.def machmode.h mode-classes.def insn-modes.h reg-notes.def insn-notes.def line-map.h input.h bversion.h diagnostic.def
|
||||||
|
READ_MD_H=hashtab.h read-md.h
|
||||||
|
PARAMS_H=params.h params.def
|
||||||
|
INTERNAL_FN_H=internal-fn.h internal-fn.def
|
||||||
|
TREE_H=coretypes.h tree.h all-tree.def tree.def c-family/c-common.def i386-opts.h real.h machmode.h mode-classes.def insn-modes.h fixed-value.h machmode.h mode-classes.def insn-modes.h double-int.h
|
||||||
|
REGSET_H=regset.h bitmap.h hashtab.h statistics.h hard-reg-set.h
|
||||||
|
BASIC_BLOCK_H=basic-block.h predict.h predict.def vec.h statistics.h ggc.h gtype-desc.h statistics.h function.h line-map.h input.h machmode.h mode-classes.def insn-modes.h cfg-flags.def cfghooks.h
|
||||||
|
GIMPLE_H=gimple.h gimple.def gsstruct.def pointer-set.h vec.h statistics.h ggc.h gtype-desc.h statistics.h ggc.h gtype-desc.h statistics.h basic-block.h predict.h predict.def vec.h statistics.h ggc.h gtype-desc.h statistics.h function.h i386-opts.h real.h machmode.h mode-classes.def insn-modes.h fixed-value.h machmode.h mode-classes.def insn-modes.h double-int.h tree-ssa-operands.h tree-ssa-alias.h internal-fn.h internal-fn.def
|
||||||
|
TRANS_MEM_H=trans-mem.h
|
||||||
|
GCOV_IO_H=gcov-io.h gcov-iov.h auto-host.h
|
||||||
|
COVERAGE_H=coverage.h gcov-io.h gcov-iov.h auto-host.h
|
||||||
|
DEMANGLE_H=demangle.h
|
||||||
|
RECOG_H=recog.h
|
||||||
|
ALIAS_H=alias.h
|
||||||
|
EMIT_RTL_H=emit-rtl.h
|
||||||
|
FLAGS_H=flags.h flag-types.h options.h flag-types.h config/i386/i386-opts.h
|
||||||
|
OPTIONS_H=options.h flag-types.h config/i386/i386-opts.h
|
||||||
|
FUNCTION_H=function.h line-map.h input.h machmode.h mode-classes.def insn-modes.h
|
||||||
|
EXPR_H=expr.h insn-config.h function.h i386-opts.h real.h machmode.h mode-classes.def insn-modes.h fixed-value.h machmode.h mode-classes.def insn-modes.h double-int.h machmode.h mode-classes.def insn-modes.h emit-rtl.h
|
||||||
|
OPTABS_H=optabs.h insn-codes.h insn-opinit.h
|
||||||
|
REGS_H=regs.h machmode.h mode-classes.def insn-modes.h hard-reg-set.h
|
||||||
|
SCHED_INT_H=sched-int.h insn-attr.h insn-attr-common.h hashtab.h statistics.h hard-reg-set.h
|
||||||
|
SEL_SCHED_IR_H=sel-sched-ir.h insn-attr.h insn-attr-common.h hashtab.h statistics.h hard-reg-set.h
|
||||||
|
SEL_SCHED_DUMP_H=sel-sched-dump.h sel-sched-ir.h insn-attr.h insn-attr-common.h hashtab.h statistics.h hard-reg-set.h
|
||||||
|
CFGLOOP_H=cfgloop.h basic-block.h predict.h predict.def vec.h statistics.h ggc.h gtype-desc.h statistics.h function.h hashtab.h statistics.h sbitmap.h
|
||||||
|
IPA_UTILS_H=ipa-utils.h coretypes.h tree.h all-tree.def tree.def c-family/c-common.def plugin-api.h is-a.h
|
||||||
|
IPA_REFERENCE_H=ipa-reference.h bitmap.h i386-opts.h real.h machmode.h mode-classes.def insn-modes.h fixed-value.h machmode.h mode-classes.def insn-modes.h double-int.h
|
||||||
|
CGRAPH_H=cgraph.h vec.h statistics.h ggc.h gtype-desc.h statistics.h coretypes.h tree.h all-tree.def tree.def c-family/c-common.def plugin-api.h is-a.h
|
||||||
|
DF_H=df.h bitmap.h line-map.h input.h machmode.h mode-classes.def insn-modes.h cfg-flags.def cfghooks.h alloc-pool.h timevar.h timevar.def
|
||||||
|
VALTRACK_H=valtrack.h bitmap.h hashtab.h hash-table.h
|
||||||
|
RESOURCE_H=resource.h hard-reg-set.h df.h bitmap.h line-map.h input.h machmode.h mode-classes.def insn-modes.h cfg-flags.def cfghooks.h alloc-pool.h timevar.h timevar.def
|
||||||
|
DDG_H=ddg.h sbitmap.h df.h bitmap.h line-map.h input.h machmode.h mode-classes.def insn-modes.h cfg-flags.def cfghooks.h alloc-pool.h timevar.h timevar.def
|
||||||
|
GCC_H=gcc.h version.h diagnostic-core.h line-map.h input.h bversion.h diagnostic.def
|
||||||
|
GGC_H=ggc.h gtype-desc.h statistics.h
|
||||||
|
GGC_INTERNAL_H=ggc-internal.h ggc.h gtype-desc.h statistics.h
|
||||||
|
TIMEVAR_H=timevar.h timevar.def
|
||||||
|
INSN_ATTR_H=insn-attr.h insn-attr-common.h insn-addr.h
|
||||||
|
INSN_ADDR_H=insn-addr.h
|
||||||
|
C_COMMON_H=c-family/c-common.h c-family/c-common.def coretypes.h tree.h all-tree.def tree.def c-family/c-common.def line-map.h input.h bversion.h diagnostic.def
|
||||||
|
C_PRAGMA_H=c-family/c-pragma.h cpplib.h
|
||||||
|
C_TREE_H=c/c-tree.h c-family/c-common.h c-family/c-common.def coretypes.h tree.h all-tree.def tree.def c-family/c-common.def obstack.h
|
||||||
|
SYSTEM_H=system.h hwint.h filenames.h
|
||||||
|
PREDICT_H=predict.h predict.def
|
||||||
|
CPPLIB_H=cpplib.h
|
||||||
|
INPUT_H=line-map.h input.h
|
||||||
|
OPTS_H=obstack.h
|
||||||
|
DECNUM_H=decimal128Local.h
|
||||||
|
BACKTRACE_H=backtrace.h
|
||||||
|
MKDEPS_H=mkdeps.h
|
||||||
|
SYMTAB_H=obstack.h
|
||||||
|
CPP_ID_DATA_H=cpp-id-data.h
|
||||||
|
CPP_INTERNAL_H=cpp-id-data.h
|
||||||
|
TREE_DUMP_H=tree-dump.h splay-tree.h dumpfile.h
|
||||||
|
TREE_PASS_H=tree-pass.h timevar.h timevar.def dumpfile.h
|
||||||
|
TREE_FLOW_H=tree-flow.h tree-flow-inline.h tree-ssa-operands.h bitmap.h i386-opts.h real.h machmode.h mode-classes.def insn-modes.h fixed-value.h machmode.h mode-classes.def insn-modes.h double-int.h tree-ssa-alias.h
|
||||||
|
TREE_SSA_LIVE_H=tree-ssa-live.h partition.h
|
||||||
|
SSAEXPAND_H=ssaexpand.h tree-ssa-live.h partition.h
|
||||||
|
PRETTY_PRINT_H=pretty-print.h obstack.h
|
||||||
|
TREE_PRETTY_PRINT_H=tree-pretty-print.h pretty-print.h obstack.h
|
||||||
|
GIMPLE_PRETTY_PRINT_H=gimple-pretty-print.h tree-pretty-print.h pretty-print.h obstack.h
|
||||||
|
DIAGNOSTIC_CORE_H=diagnostic-core.h line-map.h input.h bversion.h diagnostic.def
|
||||||
|
DIAGNOSTIC_H=diagnostic.h diagnostic-core.h obstack.h
|
||||||
|
DWARF2OUT_H=dwarf2out.h dwarf2.def
|
||||||
|
C_PRETTY_PRINT_H=c-family/c-pretty-print.h pretty-print.h i386-opts.h real.h machmode.h mode-classes.def insn-modes.h fixed-value.h machmode.h mode-classes.def insn-modes.h double-int.h
|
||||||
|
SCEV_H=tree-scalar-evolution.h ggc.h gtype-desc.h statistics.h tree-chrec.h params.h params.def
|
||||||
|
OMEGA_H=omega.h params.h params.def
|
||||||
|
TREE_DATA_REF_H=tree-data-ref.h omega.h params.h params.def graphds.h tree-scalar-evolution.h ggc.h gtype-desc.h statistics.h tree-chrec.h params.h params.def
|
||||||
|
TREE_INLINE_H=tree-inline.h
|
||||||
|
REAL_H=real.h machmode.h mode-classes.def insn-modes.h
|
||||||
|
IRA_INT_H=ira.h ira-int.h cfgloop.h basic-block.h predict.h predict.def vec.h statistics.h ggc.h gtype-desc.h statistics.h function.h hashtab.h statistics.h sbitmap.h alloc-pool.h
|
||||||
|
LRA_INT_H=lra.h bitmap.h insn-addr.h insn-codes.h lra-int.h
|
||||||
|
DBGCNT_H=dbgcnt.h dbgcnt.def
|
||||||
|
LTO_STREAMER_H=lto-streamer.h obstack.h alloc-pool.h
|
||||||
|
DATA_STREAMER_H=data-streamer.h vec.h statistics.h ggc.h gtype-desc.h statistics.h lto-streamer.h obstack.h alloc-pool.h
|
||||||
|
GIMPLE_STREAMER_H=gimple-streamer.h lto-streamer.h line-map.h input.h machmode.h mode-classes.def insn-modes.h
|
||||||
|
TREE_STREAMER_H=tree-streamer.h coretypes.h tree.h all-tree.def tree.def c-family/c-common.def i386-opts.h real.h machmode.h mode-classes.def insn-modes.h fixed-value.h machmode.h mode-classes.def insn-modes.h double-int.h
|
||||||
|
STREAMER_HOOKS_H=streamer-hooks.h coretypes.h tree.h all-tree.def tree.def c-family/c-common.def i386-opts.h real.h machmode.h mode-classes.def insn-modes.h fixed-value.h machmode.h mode-classes.def insn-modes.h double-int.h
|
||||||
|
TREE_VECTORIZER_H=tree-vectorizer.h tree-data-ref.h omega.h params.h params.def graphds.h tree-scalar-evolution.h ggc.h gtype-desc.h statistics.h tree-chrec.h params.h params.def tm.h options.h config/vxworks-dummy.h i386-opts.h target.h target.def target-hooks-macros.h insn-modes.h
|
||||||
|
IPA_PROP_H=ipa-prop.h coretypes.h tree.h all-tree.def tree.def c-family/c-common.def i386-opts.h real.h machmode.h mode-classes.def insn-modes.h fixed-value.h machmode.h mode-classes.def insn-modes.h double-int.h tree-ssa-operands.h tree-ssa-alias.h internal-fn.h internal-fn.def alloc-pool.h
|
||||||
|
IPA_INLINE_H=ipa-inline.h ipa-prop.h coretypes.h tree.h all-tree.def tree.def c-family/c-common.def i386-opts.h real.h machmode.h mode-classes.def insn-modes.h fixed-value.h machmode.h mode-classes.def insn-modes.h double-int.h tree-ssa-operands.h tree-ssa-alias.h internal-fn.h internal-fn.def alloc-pool.h
|
||||||
|
GSTAB_H=gstab.h stab.def
|
||||||
|
BITMAP_H=bitmap.h hashtab.h statistics.h
|
||||||
|
GCC_PLUGIN_H=gcc-plugin.h highlev-plugin-common.h plugin.def config.h auto-host.h hashtab.h
|
||||||
|
PLUGIN_H=plugin.h gcc-plugin.h highlev-plugin-common.h plugin.def config.h auto-host.h hashtab.h
|
||||||
|
PLUGIN_VERSION_H=plugin-version.h configargs.h
|
||||||
|
LIBFUNCS_H=libfuncs.h hashtab.h
|
||||||
|
GTFILES_H=gt-coverage.h gt-caller-save.h gt-symtab.h gt-alias.h gt-bitmap.h gt-cselib.h gt-cgraph.h gt-ipa-prop.h gt-ipa-cp.h gt-dbxout.h gt-dwarf2asm.h gt-dwarf2cfi.h gt-dwarf2out.h gt-tree-vect-generic.h gt-dojump.h gt-emit-rtl.h gt-explow.h gt-expr.h gt-function.h gt-except.h gt-gcse.h gt-godump.h gt-lists.h gt-optabs.h gt-profile.h gt-mcf.h gt-reg-stack.h gt-cfgrtl.h gt-sdbout.h gt-stor-layout.h gt-stringpool.h gt-tree.h gt-varasm.h gt-gimple.h gt-tree-mudflap.h gt-tree-ssanames.h gt-tree-eh.h gt-tree-ssa-address.h gt-tree-cfg.h gt-tree-dfa.h gt-tree-iterator.h gt-gimplify.h gt-tree-scalar-evolution.h gt-tree-profile.h gt-tree-nested.h gt-tree-parloops.h gt-omp-low.h gt-targhooks.h gt-i386.h gt-passes.h gt-cgraphunit.h gt-cgraphclones.h gt-tree-ssa-propagate.h gt-tree-phinodes.h gt-lto-symtab.h gt-trans-mem.h gt-asan.h gt-tsan.h gt-ada-decl.h gt-ada-trans.h gt-ada-utils.h gt-ada-misc.h gt-c-c-lang.h gt-c-c-decl.h gt-c-family-c-common.h gt-c-family-c-cppbuiltin.h gt-c-family-c-pragma.h gt-c-c-objc-common.h gt-c-c-parser.h gt-cp-rtti.h gt-cp-mangle.h gt-cp-name-lookup.h gt-cp-call.h gt-cp-decl.h gt-cp-decl2.h gt-cp-pt.h gt-cp-repo.h gt-cp-semantics.h gt-cp-tree.h gt-cp-parser.h gt-cp-method.h gt-cp-typeck2.h gt-c-family-c-common.h gt-c-family-c-lex.h gt-c-family-c-pragma.h gt-cp-class.h gt-cp-cp-objcp-common.h gt-cp-cp-lang.h gt-cp-except.h gt-fortran-f95-lang.h gt-fortran-trans-decl.h gt-fortran-trans-intrinsic.h gt-fortran-trans-io.h gt-fortran-trans-stmt.h gt-fortran-trans-types.h gt-go-go-lang.h gt-java-builtins.h gt-java-class.h gt-java-constants.h gt-java-decl.h gt-java-expr.h gt-java-jcf-parse.h gt-java-lang.h gt-java-mangle.h gt-java-resource.h gt-lto-lto-lang.h gt-lto-lto.h gt-objc-objc-act.h gt-objc-objc-runtime-shared-support.h gt-objc-objc-gnu-runtime-abi-01.h gt-objc-objc-next-runtime-abi-01.h gt-objc-objc-next-runtime-abi-02.h gt-c-c-parser.h gt-c-c-decl.h gt-c-c-objc-common.h gt-c-family-c-common.h gt-c-family-c-cppbuiltin.h gt-c-family-c-pragma.h gt-cp-rtti.h gt-cp-mangle.h gt-cp-name-lookup.h gt-cp-call.h gt-cp-decl.h gt-cp-decl2.h gt-cp-pt.h gt-cp-repo.h gt-cp-semantics.h gt-cp-tree.h gt-cp-parser.h gt-cp-method.h gt-cp-typeck2.h gt-c-family-c-common.h gt-c-family-c-lex.h gt-c-family-c-pragma.h gt-cp-class.h gt-cp-cp-objcp-common.h gt-objc-objc-act.h gt-objc-objc-runtime-shared-support.h gt-objc-objc-gnu-runtime-abi-01.h gt-objc-objc-next-runtime-abi-01.h gt-objc-objc-next-runtime-abi-02.h gt-c-family-c-cppbuiltin.h
|
||||||
|
GTFILES_LANG_H=gtype-ada.h gtype-c.h gtype-cp.h gtype-fortran.h gtype-go.h gtype-java.h gtype-lto.h gtype-objc.h gtype-objcp.h
|
|
@ -0,0 +1,974 @@
|
||||||
|
/* Define control flow data structures for the CFG.
|
||||||
|
Copyright (C) 1987-2013 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free
|
||||||
|
Software Foundation; either version 3, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GCC; see the file COPYING3. If not see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#ifndef GCC_BASIC_BLOCK_H
|
||||||
|
#define GCC_BASIC_BLOCK_H
|
||||||
|
|
||||||
|
#include "predict.h"
|
||||||
|
#include "vec.h"
|
||||||
|
#include "function.h"
|
||||||
|
|
||||||
|
/* Type we use to hold basic block counters. Should be at least
|
||||||
|
64bit. Although a counter cannot be negative, we use a signed
|
||||||
|
type, because erroneous negative counts can be generated when the
|
||||||
|
flow graph is manipulated by various optimizations. A signed type
|
||||||
|
makes those easy to detect. */
|
||||||
|
typedef HOST_WIDEST_INT gcov_type;
|
||||||
|
typedef unsigned HOST_WIDEST_INT gcov_type_unsigned;
|
||||||
|
|
||||||
|
/* Control flow edge information. */
|
||||||
|
struct GTY((user)) edge_def {
|
||||||
|
/* The two blocks at the ends of the edge. */
|
||||||
|
basic_block src;
|
||||||
|
basic_block dest;
|
||||||
|
|
||||||
|
/* Instructions queued on the edge. */
|
||||||
|
union edge_def_insns {
|
||||||
|
gimple_seq g;
|
||||||
|
rtx r;
|
||||||
|
} insns;
|
||||||
|
|
||||||
|
/* Auxiliary info specific to a pass. */
|
||||||
|
PTR aux;
|
||||||
|
|
||||||
|
/* Location of any goto implicit in the edge. */
|
||||||
|
location_t goto_locus;
|
||||||
|
|
||||||
|
/* The index number corresponding to this edge in the edge vector
|
||||||
|
dest->preds. */
|
||||||
|
unsigned int dest_idx;
|
||||||
|
|
||||||
|
int flags; /* see cfg-flags.def */
|
||||||
|
int probability; /* biased by REG_BR_PROB_BASE */
|
||||||
|
gcov_type count; /* Expected number of executions calculated
|
||||||
|
in profile.c */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* Garbage collection and PCH support for edge_def. */
|
||||||
|
extern void gt_ggc_mx (edge_def *e);
|
||||||
|
extern void gt_pch_nx (edge_def *e);
|
||||||
|
extern void gt_pch_nx (edge_def *e, gt_pointer_operator, void *);
|
||||||
|
|
||||||
|
/* Masks for edge.flags. */
|
||||||
|
#define DEF_EDGE_FLAG(NAME,IDX) EDGE_##NAME = 1 << IDX ,
|
||||||
|
enum cfg_edge_flags {
|
||||||
|
#include "cfg-flags.def"
|
||||||
|
LAST_CFG_EDGE_FLAG /* this is only used for EDGE_ALL_FLAGS */
|
||||||
|
};
|
||||||
|
#undef DEF_EDGE_FLAG
|
||||||
|
|
||||||
|
/* Bit mask for all edge flags. */
|
||||||
|
#define EDGE_ALL_FLAGS ((LAST_CFG_EDGE_FLAG - 1) * 2 - 1)
|
||||||
|
|
||||||
|
/* The following four flags all indicate something special about an edge.
|
||||||
|
Test the edge flags on EDGE_COMPLEX to detect all forms of "strange"
|
||||||
|
control flow transfers. */
|
||||||
|
#define EDGE_COMPLEX \
|
||||||
|
(EDGE_ABNORMAL | EDGE_ABNORMAL_CALL | EDGE_EH | EDGE_PRESERVE)
|
||||||
|
|
||||||
|
/* Counter summary from the last set of coverage counts read by
|
||||||
|
profile.c. */
|
||||||
|
extern const struct gcov_ctr_summary *profile_info;
|
||||||
|
|
||||||
|
/* Working set size statistics for a given percentage of the entire
|
||||||
|
profile (sum_all from the counter summary). */
|
||||||
|
typedef struct gcov_working_set_info
|
||||||
|
{
|
||||||
|
/* Number of hot counters included in this working set. */
|
||||||
|
unsigned num_counters;
|
||||||
|
/* Smallest counter included in this working set. */
|
||||||
|
gcov_type min_counter;
|
||||||
|
} gcov_working_set_t;
|
||||||
|
|
||||||
|
/* Structure to gather statistic about profile consistency, per pass.
|
||||||
|
An array of this structure, indexed by pass static number, is allocated
|
||||||
|
in passes.c. The structure is defined here so that different CFG modes
|
||||||
|
can do their book-keeping via CFG hooks.
|
||||||
|
|
||||||
|
For every field[2], field[0] is the count before the pass runs, and
|
||||||
|
field[1] is the post-pass count. This allows us to monitor the effect
|
||||||
|
of each individual pass on the profile consistency.
|
||||||
|
|
||||||
|
This structure is not supposed to be used by anything other than passes.c
|
||||||
|
and one CFG hook per CFG mode. */
|
||||||
|
struct profile_record
|
||||||
|
{
|
||||||
|
/* The number of basic blocks where sum(freq) of the block's predecessors
|
||||||
|
doesn't match reasonably well with the incoming frequency. */
|
||||||
|
int num_mismatched_freq_in[2];
|
||||||
|
/* Likewise for a basic block's successors. */
|
||||||
|
int num_mismatched_freq_out[2];
|
||||||
|
/* The number of basic blocks where sum(count) of the block's predecessors
|
||||||
|
doesn't match reasonably well with the incoming frequency. */
|
||||||
|
int num_mismatched_count_in[2];
|
||||||
|
/* Likewise for a basic block's successors. */
|
||||||
|
int num_mismatched_count_out[2];
|
||||||
|
/* A weighted cost of the run-time of the function body. */
|
||||||
|
gcov_type time[2];
|
||||||
|
/* A weighted cost of the size of the function body. */
|
||||||
|
int size[2];
|
||||||
|
/* True iff this pass actually was run. */
|
||||||
|
bool run;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Declared in cfgloop.h. */
|
||||||
|
struct loop;
|
||||||
|
|
||||||
|
struct GTY(()) rtl_bb_info {
|
||||||
|
/* The first insn of the block is embedded into bb->il.x. */
|
||||||
|
/* The last insn of the block. */
|
||||||
|
rtx end_;
|
||||||
|
|
||||||
|
/* In CFGlayout mode points to insn notes/jumptables to be placed just before
|
||||||
|
and after the block. */
|
||||||
|
rtx header_;
|
||||||
|
rtx footer_;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GTY(()) gimple_bb_info {
|
||||||
|
/* Sequence of statements in this block. */
|
||||||
|
gimple_seq seq;
|
||||||
|
|
||||||
|
/* PHI nodes for this block. */
|
||||||
|
gimple_seq phi_nodes;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* A basic block is a sequence of instructions with only one entry and
|
||||||
|
only one exit. If any one of the instructions are executed, they
|
||||||
|
will all be executed, and in sequence from first to last.
|
||||||
|
|
||||||
|
There may be COND_EXEC instructions in the basic block. The
|
||||||
|
COND_EXEC *instructions* will be executed -- but if the condition
|
||||||
|
is false the conditionally executed *expressions* will of course
|
||||||
|
not be executed. We don't consider the conditionally executed
|
||||||
|
expression (which might have side-effects) to be in a separate
|
||||||
|
basic block because the program counter will always be at the same
|
||||||
|
location after the COND_EXEC instruction, regardless of whether the
|
||||||
|
condition is true or not.
|
||||||
|
|
||||||
|
Basic blocks need not start with a label nor end with a jump insn.
|
||||||
|
For example, a previous basic block may just "conditionally fall"
|
||||||
|
into the succeeding basic block, and the last basic block need not
|
||||||
|
end with a jump insn. Block 0 is a descendant of the entry block.
|
||||||
|
|
||||||
|
A basic block beginning with two labels cannot have notes between
|
||||||
|
the labels.
|
||||||
|
|
||||||
|
Data for jump tables are stored in jump_insns that occur in no
|
||||||
|
basic block even though these insns can follow or precede insns in
|
||||||
|
basic blocks. */
|
||||||
|
|
||||||
|
/* Basic block information indexed by block number. */
|
||||||
|
struct GTY((chain_next ("%h.next_bb"), chain_prev ("%h.prev_bb"))) basic_block_def {
|
||||||
|
/* The edges into and out of the block. */
|
||||||
|
vec<edge, va_gc> *preds;
|
||||||
|
vec<edge, va_gc> *succs;
|
||||||
|
|
||||||
|
/* Auxiliary info specific to a pass. */
|
||||||
|
PTR GTY ((skip (""))) aux;
|
||||||
|
|
||||||
|
/* Innermost loop containing the block. */
|
||||||
|
struct loop *loop_father;
|
||||||
|
|
||||||
|
/* The dominance and postdominance information node. */
|
||||||
|
struct et_node * GTY ((skip (""))) dom[2];
|
||||||
|
|
||||||
|
/* Previous and next blocks in the chain. */
|
||||||
|
basic_block prev_bb;
|
||||||
|
basic_block next_bb;
|
||||||
|
|
||||||
|
union basic_block_il_dependent {
|
||||||
|
struct gimple_bb_info GTY ((tag ("0"))) gimple;
|
||||||
|
struct {
|
||||||
|
rtx head_;
|
||||||
|
struct rtl_bb_info * rtl;
|
||||||
|
} GTY ((tag ("1"))) x;
|
||||||
|
} GTY ((desc ("((%1.flags & BB_RTL) != 0)"))) il;
|
||||||
|
|
||||||
|
/* Various flags. See cfg-flags.def. */
|
||||||
|
int flags;
|
||||||
|
|
||||||
|
/* The index of this block. */
|
||||||
|
int index;
|
||||||
|
|
||||||
|
/* Expected number of executions: calculated in profile.c. */
|
||||||
|
gcov_type count;
|
||||||
|
|
||||||
|
/* Expected frequency. Normalized to be in range 0 to BB_FREQ_MAX. */
|
||||||
|
int frequency;
|
||||||
|
|
||||||
|
/* The discriminator for this block. The discriminator distinguishes
|
||||||
|
among several basic blocks that share a common locus, allowing for
|
||||||
|
more accurate sample-based profiling. */
|
||||||
|
int discriminator;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* This ensures that struct gimple_bb_info is smaller than
|
||||||
|
struct rtl_bb_info, so that inlining the former into basic_block_def
|
||||||
|
is the better choice. */
|
||||||
|
typedef int __assert_gimple_bb_smaller_rtl_bb
|
||||||
|
[(int)sizeof(struct rtl_bb_info)
|
||||||
|
- (int)sizeof (struct gimple_bb_info)];
|
||||||
|
|
||||||
|
|
||||||
|
#define BB_FREQ_MAX 10000
|
||||||
|
|
||||||
|
/* Masks for basic_block.flags. */
|
||||||
|
#define DEF_BASIC_BLOCK_FLAG(NAME,IDX) BB_##NAME = 1 << IDX ,
|
||||||
|
enum cfg_bb_flags
|
||||||
|
{
|
||||||
|
#include "cfg-flags.def"
|
||||||
|
LAST_CFG_BB_FLAG /* this is only used for BB_ALL_FLAGS */
|
||||||
|
};
|
||||||
|
#undef DEF_BASIC_BLOCK_FLAG
|
||||||
|
|
||||||
|
/* Bit mask for all basic block flags. */
|
||||||
|
#define BB_ALL_FLAGS ((LAST_CFG_BB_FLAG - 1) * 2 - 1)
|
||||||
|
|
||||||
|
/* Bit mask for all basic block flags that must be preserved. These are
|
||||||
|
the bit masks that are *not* cleared by clear_bb_flags. */
|
||||||
|
#define BB_FLAGS_TO_PRESERVE \
|
||||||
|
(BB_DISABLE_SCHEDULE | BB_RTL | BB_NON_LOCAL_GOTO_TARGET \
|
||||||
|
| BB_HOT_PARTITION | BB_COLD_PARTITION)
|
||||||
|
|
||||||
|
/* Dummy bitmask for convenience in the hot/cold partitioning code. */
|
||||||
|
#define BB_UNPARTITIONED 0
|
||||||
|
|
||||||
|
/* Partitions, to be used when partitioning hot and cold basic blocks into
|
||||||
|
separate sections. */
|
||||||
|
#define BB_PARTITION(bb) ((bb)->flags & (BB_HOT_PARTITION|BB_COLD_PARTITION))
|
||||||
|
#define BB_SET_PARTITION(bb, part) do { \
|
||||||
|
basic_block bb_ = (bb); \
|
||||||
|
bb_->flags = ((bb_->flags & ~(BB_HOT_PARTITION|BB_COLD_PARTITION)) \
|
||||||
|
| (part)); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define BB_COPY_PARTITION(dstbb, srcbb) \
|
||||||
|
BB_SET_PARTITION (dstbb, BB_PARTITION (srcbb))
|
||||||
|
|
||||||
|
/* State of dominance information. */
|
||||||
|
|
||||||
|
enum dom_state
|
||||||
|
{
|
||||||
|
DOM_NONE, /* Not computed at all. */
|
||||||
|
DOM_NO_FAST_QUERY, /* The data is OK, but the fast query data are not usable. */
|
||||||
|
DOM_OK /* Everything is ok. */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* What sort of profiling information we have. */
|
||||||
|
enum profile_status_d
|
||||||
|
{
|
||||||
|
PROFILE_ABSENT,
|
||||||
|
PROFILE_GUESSED,
|
||||||
|
PROFILE_READ,
|
||||||
|
PROFILE_LAST /* Last value, used by profile streaming. */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* A structure to group all the per-function control flow graph data.
|
||||||
|
The x_* prefixing is necessary because otherwise references to the
|
||||||
|
fields of this struct are interpreted as the defines for backward
|
||||||
|
source compatibility following the definition of this struct. */
|
||||||
|
struct GTY(()) control_flow_graph {
|
||||||
|
/* Block pointers for the exit and entry of a function.
|
||||||
|
These are always the head and tail of the basic block list. */
|
||||||
|
basic_block x_entry_block_ptr;
|
||||||
|
basic_block x_exit_block_ptr;
|
||||||
|
|
||||||
|
/* Index by basic block number, get basic block struct info. */
|
||||||
|
vec<basic_block, va_gc> *x_basic_block_info;
|
||||||
|
|
||||||
|
/* Number of basic blocks in this flow graph. */
|
||||||
|
int x_n_basic_blocks;
|
||||||
|
|
||||||
|
/* Number of edges in this flow graph. */
|
||||||
|
int x_n_edges;
|
||||||
|
|
||||||
|
/* The first free basic block number. */
|
||||||
|
int x_last_basic_block;
|
||||||
|
|
||||||
|
/* UIDs for LABEL_DECLs. */
|
||||||
|
int last_label_uid;
|
||||||
|
|
||||||
|
/* Mapping of labels to their associated blocks. At present
|
||||||
|
only used for the gimple CFG. */
|
||||||
|
vec<basic_block, va_gc> *x_label_to_block_map;
|
||||||
|
|
||||||
|
enum profile_status_d x_profile_status;
|
||||||
|
|
||||||
|
/* Whether the dominators and the postdominators are available. */
|
||||||
|
enum dom_state x_dom_computed[2];
|
||||||
|
|
||||||
|
/* Number of basic blocks in the dominance tree. */
|
||||||
|
unsigned x_n_bbs_in_dom_tree[2];
|
||||||
|
|
||||||
|
/* Maximal number of entities in the single jumptable. Used to estimate
|
||||||
|
final flowgraph size. */
|
||||||
|
int max_jumptable_ents;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Defines for accessing the fields of the CFG structure for function FN. */
|
||||||
|
#define ENTRY_BLOCK_PTR_FOR_FUNCTION(FN) ((FN)->cfg->x_entry_block_ptr)
|
||||||
|
#define EXIT_BLOCK_PTR_FOR_FUNCTION(FN) ((FN)->cfg->x_exit_block_ptr)
|
||||||
|
#define basic_block_info_for_function(FN) ((FN)->cfg->x_basic_block_info)
|
||||||
|
#define n_basic_blocks_for_function(FN) ((FN)->cfg->x_n_basic_blocks)
|
||||||
|
#define n_edges_for_function(FN) ((FN)->cfg->x_n_edges)
|
||||||
|
#define last_basic_block_for_function(FN) ((FN)->cfg->x_last_basic_block)
|
||||||
|
#define label_to_block_map_for_function(FN) ((FN)->cfg->x_label_to_block_map)
|
||||||
|
#define profile_status_for_function(FN) ((FN)->cfg->x_profile_status)
|
||||||
|
|
||||||
|
#define BASIC_BLOCK_FOR_FUNCTION(FN,N) \
|
||||||
|
((*basic_block_info_for_function(FN))[(N)])
|
||||||
|
#define SET_BASIC_BLOCK_FOR_FUNCTION(FN,N,BB) \
|
||||||
|
((*basic_block_info_for_function(FN))[(N)] = (BB))
|
||||||
|
|
||||||
|
/* Defines for textual backward source compatibility. */
|
||||||
|
#define ENTRY_BLOCK_PTR (cfun->cfg->x_entry_block_ptr)
|
||||||
|
#define EXIT_BLOCK_PTR (cfun->cfg->x_exit_block_ptr)
|
||||||
|
#define basic_block_info (cfun->cfg->x_basic_block_info)
|
||||||
|
#define n_basic_blocks (cfun->cfg->x_n_basic_blocks)
|
||||||
|
#define n_edges (cfun->cfg->x_n_edges)
|
||||||
|
#define last_basic_block (cfun->cfg->x_last_basic_block)
|
||||||
|
#define label_to_block_map (cfun->cfg->x_label_to_block_map)
|
||||||
|
#define profile_status (cfun->cfg->x_profile_status)
|
||||||
|
|
||||||
|
#define BASIC_BLOCK(N) ((*basic_block_info)[(N)])
|
||||||
|
#define SET_BASIC_BLOCK(N,BB) ((*basic_block_info)[(N)] = (BB))
|
||||||
|
|
||||||
|
/* For iterating over basic blocks. */
|
||||||
|
#define FOR_BB_BETWEEN(BB, FROM, TO, DIR) \
|
||||||
|
for (BB = FROM; BB != TO; BB = BB->DIR)
|
||||||
|
|
||||||
|
#define FOR_EACH_BB_FN(BB, FN) \
|
||||||
|
FOR_BB_BETWEEN (BB, (FN)->cfg->x_entry_block_ptr->next_bb, (FN)->cfg->x_exit_block_ptr, next_bb)
|
||||||
|
|
||||||
|
#define FOR_EACH_BB(BB) FOR_EACH_BB_FN (BB, cfun)
|
||||||
|
|
||||||
|
#define FOR_EACH_BB_REVERSE_FN(BB, FN) \
|
||||||
|
FOR_BB_BETWEEN (BB, (FN)->cfg->x_exit_block_ptr->prev_bb, (FN)->cfg->x_entry_block_ptr, prev_bb)
|
||||||
|
|
||||||
|
#define FOR_EACH_BB_REVERSE(BB) FOR_EACH_BB_REVERSE_FN(BB, cfun)
|
||||||
|
|
||||||
|
/* For iterating over insns in basic block. */
|
||||||
|
#define FOR_BB_INSNS(BB, INSN) \
|
||||||
|
for ((INSN) = BB_HEAD (BB); \
|
||||||
|
(INSN) && (INSN) != NEXT_INSN (BB_END (BB)); \
|
||||||
|
(INSN) = NEXT_INSN (INSN))
|
||||||
|
|
||||||
|
/* For iterating over insns in basic block when we might remove the
|
||||||
|
current insn. */
|
||||||
|
#define FOR_BB_INSNS_SAFE(BB, INSN, CURR) \
|
||||||
|
for ((INSN) = BB_HEAD (BB), (CURR) = (INSN) ? NEXT_INSN ((INSN)): NULL; \
|
||||||
|
(INSN) && (INSN) != NEXT_INSN (BB_END (BB)); \
|
||||||
|
(INSN) = (CURR), (CURR) = (INSN) ? NEXT_INSN ((INSN)) : NULL)
|
||||||
|
|
||||||
|
#define FOR_BB_INSNS_REVERSE(BB, INSN) \
|
||||||
|
for ((INSN) = BB_END (BB); \
|
||||||
|
(INSN) && (INSN) != PREV_INSN (BB_HEAD (BB)); \
|
||||||
|
(INSN) = PREV_INSN (INSN))
|
||||||
|
|
||||||
|
#define FOR_BB_INSNS_REVERSE_SAFE(BB, INSN, CURR) \
|
||||||
|
for ((INSN) = BB_END (BB),(CURR) = (INSN) ? PREV_INSN ((INSN)) : NULL; \
|
||||||
|
(INSN) && (INSN) != PREV_INSN (BB_HEAD (BB)); \
|
||||||
|
(INSN) = (CURR), (CURR) = (INSN) ? PREV_INSN ((INSN)) : NULL)
|
||||||
|
|
||||||
|
/* Cycles through _all_ basic blocks, even the fake ones (entry and
|
||||||
|
exit block). */
|
||||||
|
|
||||||
|
#define FOR_ALL_BB(BB) \
|
||||||
|
for (BB = ENTRY_BLOCK_PTR; BB; BB = BB->next_bb)
|
||||||
|
|
||||||
|
#define FOR_ALL_BB_FN(BB, FN) \
|
||||||
|
for (BB = ENTRY_BLOCK_PTR_FOR_FUNCTION (FN); BB; BB = BB->next_bb)
|
||||||
|
|
||||||
|
|
||||||
|
/* Stuff for recording basic block info. */
|
||||||
|
|
||||||
|
#define BB_HEAD(B) (B)->il.x.head_
|
||||||
|
#define BB_END(B) (B)->il.x.rtl->end_
|
||||||
|
#define BB_HEADER(B) (B)->il.x.rtl->header_
|
||||||
|
#define BB_FOOTER(B) (B)->il.x.rtl->footer_
|
||||||
|
|
||||||
|
/* Special block numbers [markers] for entry and exit.
|
||||||
|
Neither of them is supposed to hold actual statements. */
|
||||||
|
#define ENTRY_BLOCK (0)
|
||||||
|
#define EXIT_BLOCK (1)
|
||||||
|
|
||||||
|
/* The two blocks that are always in the cfg. */
|
||||||
|
#define NUM_FIXED_BLOCKS (2)
|
||||||
|
|
||||||
|
#define set_block_for_insn(INSN, BB) (BLOCK_FOR_INSN (INSN) = BB)
|
||||||
|
|
||||||
|
extern void compute_bb_for_insn (void);
|
||||||
|
extern unsigned int free_bb_for_insn (void);
|
||||||
|
extern void update_bb_for_insn (basic_block);
|
||||||
|
|
||||||
|
extern void insert_insn_on_edge (rtx, edge);
|
||||||
|
basic_block split_edge_and_insert (edge, rtx);
|
||||||
|
|
||||||
|
extern void commit_one_edge_insertion (edge e);
|
||||||
|
extern void commit_edge_insertions (void);
|
||||||
|
|
||||||
|
extern edge unchecked_make_edge (basic_block, basic_block, int);
|
||||||
|
extern edge cached_make_edge (sbitmap, basic_block, basic_block, int);
|
||||||
|
extern edge make_edge (basic_block, basic_block, int);
|
||||||
|
extern edge make_single_succ_edge (basic_block, basic_block, int);
|
||||||
|
extern void remove_edge_raw (edge);
|
||||||
|
extern void redirect_edge_succ (edge, basic_block);
|
||||||
|
extern edge redirect_edge_succ_nodup (edge, basic_block);
|
||||||
|
extern void redirect_edge_pred (edge, basic_block);
|
||||||
|
extern basic_block create_basic_block_structure (rtx, rtx, rtx, basic_block);
|
||||||
|
extern void clear_bb_flags (void);
|
||||||
|
extern void dump_bb_info (FILE *, basic_block, int, int, bool, bool);
|
||||||
|
extern void dump_edge_info (FILE *, edge, int, int);
|
||||||
|
extern void brief_dump_cfg (FILE *, int);
|
||||||
|
extern void clear_edges (void);
|
||||||
|
extern void scale_bbs_frequencies_int (basic_block *, int, int, int);
|
||||||
|
extern void scale_bbs_frequencies_gcov_type (basic_block *, int, gcov_type,
|
||||||
|
gcov_type);
|
||||||
|
|
||||||
|
/* Structure to group all of the information to process IF-THEN and
|
||||||
|
IF-THEN-ELSE blocks for the conditional execution support. This
|
||||||
|
needs to be in a public file in case the IFCVT macros call
|
||||||
|
functions passing the ce_if_block data structure. */
|
||||||
|
|
||||||
|
typedef struct ce_if_block
|
||||||
|
{
|
||||||
|
basic_block test_bb; /* First test block. */
|
||||||
|
basic_block then_bb; /* THEN block. */
|
||||||
|
basic_block else_bb; /* ELSE block or NULL. */
|
||||||
|
basic_block join_bb; /* Join THEN/ELSE blocks. */
|
||||||
|
basic_block last_test_bb; /* Last bb to hold && or || tests. */
|
||||||
|
int num_multiple_test_blocks; /* # of && and || basic blocks. */
|
||||||
|
int num_and_and_blocks; /* # of && blocks. */
|
||||||
|
int num_or_or_blocks; /* # of || blocks. */
|
||||||
|
int num_multiple_test_insns; /* # of insns in && and || blocks. */
|
||||||
|
int and_and_p; /* Complex test is &&. */
|
||||||
|
int num_then_insns; /* # of insns in THEN block. */
|
||||||
|
int num_else_insns; /* # of insns in ELSE block. */
|
||||||
|
int pass; /* Pass number. */
|
||||||
|
} ce_if_block_t;
|
||||||
|
|
||||||
|
/* This structure maintains an edge list vector. */
|
||||||
|
/* FIXME: Make this a vec<edge>. */
|
||||||
|
struct edge_list
|
||||||
|
{
|
||||||
|
int num_edges;
|
||||||
|
edge *index_to_edge;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* The base value for branch probability notes and edge probabilities. */
|
||||||
|
#define REG_BR_PROB_BASE 10000
|
||||||
|
|
||||||
|
/* This is the value which indicates no edge is present. */
|
||||||
|
#define EDGE_INDEX_NO_EDGE -1
|
||||||
|
|
||||||
|
/* EDGE_INDEX returns an integer index for an edge, or EDGE_INDEX_NO_EDGE
|
||||||
|
if there is no edge between the 2 basic blocks. */
|
||||||
|
#define EDGE_INDEX(el, pred, succ) (find_edge_index ((el), (pred), (succ)))
|
||||||
|
|
||||||
|
/* INDEX_EDGE_PRED_BB and INDEX_EDGE_SUCC_BB return a pointer to the basic
|
||||||
|
block which is either the pred or succ end of the indexed edge. */
|
||||||
|
#define INDEX_EDGE_PRED_BB(el, index) ((el)->index_to_edge[(index)]->src)
|
||||||
|
#define INDEX_EDGE_SUCC_BB(el, index) ((el)->index_to_edge[(index)]->dest)
|
||||||
|
|
||||||
|
/* INDEX_EDGE returns a pointer to the edge. */
|
||||||
|
#define INDEX_EDGE(el, index) ((el)->index_to_edge[(index)])
|
||||||
|
|
||||||
|
/* Number of edges in the compressed edge list. */
|
||||||
|
#define NUM_EDGES(el) ((el)->num_edges)
|
||||||
|
|
||||||
|
/* BB is assumed to contain conditional jump. Return the fallthru edge. */
|
||||||
|
#define FALLTHRU_EDGE(bb) (EDGE_SUCC ((bb), 0)->flags & EDGE_FALLTHRU \
|
||||||
|
? EDGE_SUCC ((bb), 0) : EDGE_SUCC ((bb), 1))
|
||||||
|
|
||||||
|
/* BB is assumed to contain conditional jump. Return the branch edge. */
|
||||||
|
#define BRANCH_EDGE(bb) (EDGE_SUCC ((bb), 0)->flags & EDGE_FALLTHRU \
|
||||||
|
? EDGE_SUCC ((bb), 1) : EDGE_SUCC ((bb), 0))
|
||||||
|
|
||||||
|
#define RDIV(X,Y) (((X) + (Y) / 2) / (Y))
|
||||||
|
/* Return expected execution frequency of the edge E. */
|
||||||
|
#define EDGE_FREQUENCY(e) RDIV ((e)->src->frequency * (e)->probability, \
|
||||||
|
REG_BR_PROB_BASE)
|
||||||
|
|
||||||
|
/* Return nonzero if edge is critical. */
|
||||||
|
#define EDGE_CRITICAL_P(e) (EDGE_COUNT ((e)->src->succs) >= 2 \
|
||||||
|
&& EDGE_COUNT ((e)->dest->preds) >= 2)
|
||||||
|
|
||||||
|
#define EDGE_COUNT(ev) vec_safe_length (ev)
|
||||||
|
#define EDGE_I(ev,i) (*ev)[(i)]
|
||||||
|
#define EDGE_PRED(bb,i) (*(bb)->preds)[(i)]
|
||||||
|
#define EDGE_SUCC(bb,i) (*(bb)->succs)[(i)]
|
||||||
|
|
||||||
|
/* Returns true if BB has precisely one successor. */
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
single_succ_p (const_basic_block bb)
|
||||||
|
{
|
||||||
|
return EDGE_COUNT (bb->succs) == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns true if BB has precisely one predecessor. */
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
single_pred_p (const_basic_block bb)
|
||||||
|
{
|
||||||
|
return EDGE_COUNT (bb->preds) == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns the single successor edge of basic block BB. Aborts if
|
||||||
|
BB does not have exactly one successor. */
|
||||||
|
|
||||||
|
static inline edge
|
||||||
|
single_succ_edge (const_basic_block bb)
|
||||||
|
{
|
||||||
|
gcc_checking_assert (single_succ_p (bb));
|
||||||
|
return EDGE_SUCC (bb, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns the single predecessor edge of basic block BB. Aborts
|
||||||
|
if BB does not have exactly one predecessor. */
|
||||||
|
|
||||||
|
static inline edge
|
||||||
|
single_pred_edge (const_basic_block bb)
|
||||||
|
{
|
||||||
|
gcc_checking_assert (single_pred_p (bb));
|
||||||
|
return EDGE_PRED (bb, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns the single successor block of basic block BB. Aborts
|
||||||
|
if BB does not have exactly one successor. */
|
||||||
|
|
||||||
|
static inline basic_block
|
||||||
|
single_succ (const_basic_block bb)
|
||||||
|
{
|
||||||
|
return single_succ_edge (bb)->dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns the single predecessor block of basic block BB. Aborts
|
||||||
|
if BB does not have exactly one predecessor.*/
|
||||||
|
|
||||||
|
static inline basic_block
|
||||||
|
single_pred (const_basic_block bb)
|
||||||
|
{
|
||||||
|
return single_pred_edge (bb)->src;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Iterator object for edges. */
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned index;
|
||||||
|
vec<edge, va_gc> **container;
|
||||||
|
} edge_iterator;
|
||||||
|
|
||||||
|
static inline vec<edge, va_gc> *
|
||||||
|
ei_container (edge_iterator i)
|
||||||
|
{
|
||||||
|
gcc_checking_assert (i.container);
|
||||||
|
return *i.container;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ei_start(iter) ei_start_1 (&(iter))
|
||||||
|
#define ei_last(iter) ei_last_1 (&(iter))
|
||||||
|
|
||||||
|
/* Return an iterator pointing to the start of an edge vector. */
|
||||||
|
static inline edge_iterator
|
||||||
|
ei_start_1 (vec<edge, va_gc> **ev)
|
||||||
|
{
|
||||||
|
edge_iterator i;
|
||||||
|
|
||||||
|
i.index = 0;
|
||||||
|
i.container = ev;
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return an iterator pointing to the last element of an edge
|
||||||
|
vector. */
|
||||||
|
static inline edge_iterator
|
||||||
|
ei_last_1 (vec<edge, va_gc> **ev)
|
||||||
|
{
|
||||||
|
edge_iterator i;
|
||||||
|
|
||||||
|
i.index = EDGE_COUNT (*ev) - 1;
|
||||||
|
i.container = ev;
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Is the iterator `i' at the end of the sequence? */
|
||||||
|
static inline bool
|
||||||
|
ei_end_p (edge_iterator i)
|
||||||
|
{
|
||||||
|
return (i.index == EDGE_COUNT (ei_container (i)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Is the iterator `i' at one position before the end of the
|
||||||
|
sequence? */
|
||||||
|
static inline bool
|
||||||
|
ei_one_before_end_p (edge_iterator i)
|
||||||
|
{
|
||||||
|
return (i.index + 1 == EDGE_COUNT (ei_container (i)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Advance the iterator to the next element. */
|
||||||
|
static inline void
|
||||||
|
ei_next (edge_iterator *i)
|
||||||
|
{
|
||||||
|
gcc_checking_assert (i->index < EDGE_COUNT (ei_container (*i)));
|
||||||
|
i->index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Move the iterator to the previous element. */
|
||||||
|
static inline void
|
||||||
|
ei_prev (edge_iterator *i)
|
||||||
|
{
|
||||||
|
gcc_checking_assert (i->index > 0);
|
||||||
|
i->index--;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the edge pointed to by the iterator `i'. */
|
||||||
|
static inline edge
|
||||||
|
ei_edge (edge_iterator i)
|
||||||
|
{
|
||||||
|
return EDGE_I (ei_container (i), i.index);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return an edge pointed to by the iterator. Do it safely so that
|
||||||
|
NULL is returned when the iterator is pointing at the end of the
|
||||||
|
sequence. */
|
||||||
|
static inline edge
|
||||||
|
ei_safe_edge (edge_iterator i)
|
||||||
|
{
|
||||||
|
return !ei_end_p (i) ? ei_edge (i) : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return 1 if we should continue to iterate. Return 0 otherwise.
|
||||||
|
*Edge P is set to the next edge if we are to continue to iterate
|
||||||
|
and NULL otherwise. */
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
ei_cond (edge_iterator ei, edge *p)
|
||||||
|
{
|
||||||
|
if (!ei_end_p (ei))
|
||||||
|
{
|
||||||
|
*p = ei_edge (ei);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*p = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This macro serves as a convenient way to iterate each edge in a
|
||||||
|
vector of predecessor or successor edges. It must not be used when
|
||||||
|
an element might be removed during the traversal, otherwise
|
||||||
|
elements will be missed. Instead, use a for-loop like that shown
|
||||||
|
in the following pseudo-code:
|
||||||
|
|
||||||
|
FOR (ei = ei_start (bb->succs); (e = ei_safe_edge (ei)); )
|
||||||
|
{
|
||||||
|
IF (e != taken_edge)
|
||||||
|
remove_edge (e);
|
||||||
|
ELSE
|
||||||
|
ei_next (&ei);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define FOR_EACH_EDGE(EDGE,ITER,EDGE_VEC) \
|
||||||
|
for ((ITER) = ei_start ((EDGE_VEC)); \
|
||||||
|
ei_cond ((ITER), &(EDGE)); \
|
||||||
|
ei_next (&(ITER)))
|
||||||
|
|
||||||
|
#define CLEANUP_EXPENSIVE 1 /* Do relatively expensive optimizations
|
||||||
|
except for edge forwarding */
|
||||||
|
#define CLEANUP_CROSSJUMP 2 /* Do crossjumping. */
|
||||||
|
#define CLEANUP_POST_REGSTACK 4 /* We run after reg-stack and need
|
||||||
|
to care REG_DEAD notes. */
|
||||||
|
#define CLEANUP_THREADING 8 /* Do jump threading. */
|
||||||
|
#define CLEANUP_NO_INSN_DEL 16 /* Do not try to delete trivially dead
|
||||||
|
insns. */
|
||||||
|
#define CLEANUP_CFGLAYOUT 32 /* Do cleanup in cfglayout mode. */
|
||||||
|
#define CLEANUP_CFG_CHANGED 64 /* The caller changed the CFG. */
|
||||||
|
|
||||||
|
/* In cfganal.c */
|
||||||
|
extern void bitmap_intersection_of_succs (sbitmap, sbitmap *, basic_block);
|
||||||
|
extern void bitmap_intersection_of_preds (sbitmap, sbitmap *, basic_block);
|
||||||
|
extern void bitmap_union_of_succs (sbitmap, sbitmap *, basic_block);
|
||||||
|
extern void bitmap_union_of_preds (sbitmap, sbitmap *, basic_block);
|
||||||
|
|
||||||
|
/* In lcm.c */
|
||||||
|
extern struct edge_list *pre_edge_lcm (int, sbitmap *, sbitmap *,
|
||||||
|
sbitmap *, sbitmap *, sbitmap **,
|
||||||
|
sbitmap **);
|
||||||
|
extern struct edge_list *pre_edge_rev_lcm (int, sbitmap *,
|
||||||
|
sbitmap *, sbitmap *,
|
||||||
|
sbitmap *, sbitmap **,
|
||||||
|
sbitmap **);
|
||||||
|
extern void compute_available (sbitmap *, sbitmap *, sbitmap *, sbitmap *);
|
||||||
|
|
||||||
|
/* In predict.c */
|
||||||
|
extern bool maybe_hot_bb_p (struct function *, const_basic_block);
|
||||||
|
extern bool maybe_hot_edge_p (edge);
|
||||||
|
extern bool probably_never_executed_bb_p (struct function *, const_basic_block);
|
||||||
|
extern bool optimize_bb_for_size_p (const_basic_block);
|
||||||
|
extern bool optimize_bb_for_speed_p (const_basic_block);
|
||||||
|
extern bool optimize_edge_for_size_p (edge);
|
||||||
|
extern bool optimize_edge_for_speed_p (edge);
|
||||||
|
extern bool optimize_loop_for_size_p (struct loop *);
|
||||||
|
extern bool optimize_loop_for_speed_p (struct loop *);
|
||||||
|
extern bool optimize_loop_nest_for_size_p (struct loop *);
|
||||||
|
extern bool optimize_loop_nest_for_speed_p (struct loop *);
|
||||||
|
extern bool gimple_predicted_by_p (const_basic_block, enum br_predictor);
|
||||||
|
extern bool rtl_predicted_by_p (const_basic_block, enum br_predictor);
|
||||||
|
extern void gimple_predict_edge (edge, enum br_predictor, int);
|
||||||
|
extern void rtl_predict_edge (edge, enum br_predictor, int);
|
||||||
|
extern void predict_edge_def (edge, enum br_predictor, enum prediction);
|
||||||
|
extern void guess_outgoing_edge_probabilities (basic_block);
|
||||||
|
extern void remove_predictions_associated_with_edge (edge);
|
||||||
|
extern bool edge_probability_reliable_p (const_edge);
|
||||||
|
extern bool br_prob_note_reliable_p (const_rtx);
|
||||||
|
extern bool predictable_edge_p (edge);
|
||||||
|
|
||||||
|
/* In cfg.c */
|
||||||
|
extern void init_flow (struct function *);
|
||||||
|
extern void debug_bb (basic_block);
|
||||||
|
extern basic_block debug_bb_n (int);
|
||||||
|
extern void dump_flow_info (FILE *, int);
|
||||||
|
extern void expunge_block (basic_block);
|
||||||
|
extern void link_block (basic_block, basic_block);
|
||||||
|
extern void unlink_block (basic_block);
|
||||||
|
extern void compact_blocks (void);
|
||||||
|
extern basic_block alloc_block (void);
|
||||||
|
extern void alloc_aux_for_blocks (int);
|
||||||
|
extern void clear_aux_for_blocks (void);
|
||||||
|
extern void free_aux_for_blocks (void);
|
||||||
|
extern void alloc_aux_for_edge (edge, int);
|
||||||
|
extern void alloc_aux_for_edges (int);
|
||||||
|
extern void clear_aux_for_edges (void);
|
||||||
|
extern void free_aux_for_edges (void);
|
||||||
|
|
||||||
|
/* In cfganal.c */
|
||||||
|
extern void find_unreachable_blocks (void);
|
||||||
|
extern bool mark_dfs_back_edges (void);
|
||||||
|
struct edge_list * create_edge_list (void);
|
||||||
|
void free_edge_list (struct edge_list *);
|
||||||
|
void print_edge_list (FILE *, struct edge_list *);
|
||||||
|
void verify_edge_list (FILE *, struct edge_list *);
|
||||||
|
int find_edge_index (struct edge_list *, basic_block, basic_block);
|
||||||
|
edge find_edge (basic_block, basic_block);
|
||||||
|
extern void remove_fake_edges (void);
|
||||||
|
extern void remove_fake_exit_edges (void);
|
||||||
|
extern void add_noreturn_fake_exit_edges (void);
|
||||||
|
extern void connect_infinite_loops_to_exit (void);
|
||||||
|
extern int post_order_compute (int *, bool, bool);
|
||||||
|
extern basic_block dfs_find_deadend (basic_block);
|
||||||
|
extern int inverted_post_order_compute (int *);
|
||||||
|
extern int pre_and_rev_post_order_compute (int *, int *, bool);
|
||||||
|
extern int dfs_enumerate_from (basic_block, int,
|
||||||
|
bool (*)(const_basic_block, const void *),
|
||||||
|
basic_block *, int, const void *);
|
||||||
|
extern void compute_dominance_frontiers (struct bitmap_head_def *);
|
||||||
|
extern bitmap compute_idf (bitmap, struct bitmap_head_def *);
|
||||||
|
|
||||||
|
/* In cfgrtl.c */
|
||||||
|
extern rtx block_label (basic_block);
|
||||||
|
extern rtx bb_note (basic_block);
|
||||||
|
extern bool purge_all_dead_edges (void);
|
||||||
|
extern bool purge_dead_edges (basic_block);
|
||||||
|
extern bool fixup_abnormal_edges (void);
|
||||||
|
extern basic_block force_nonfallthru_and_redirect (edge, basic_block, rtx);
|
||||||
|
extern bool contains_no_active_insn_p (const_basic_block);
|
||||||
|
extern bool forwarder_block_p (const_basic_block);
|
||||||
|
extern bool can_fallthru (basic_block, basic_block);
|
||||||
|
|
||||||
|
/* In cfgbuild.c. */
|
||||||
|
extern void find_many_sub_basic_blocks (sbitmap);
|
||||||
|
extern void rtl_make_eh_edge (sbitmap, basic_block, rtx);
|
||||||
|
|
||||||
|
enum replace_direction { dir_none, dir_forward, dir_backward, dir_both };
|
||||||
|
|
||||||
|
/* In cfgcleanup.c. */
|
||||||
|
extern bool cleanup_cfg (int);
|
||||||
|
extern int flow_find_cross_jump (basic_block, basic_block, rtx *, rtx *,
|
||||||
|
enum replace_direction*);
|
||||||
|
extern int flow_find_head_matching_sequence (basic_block, basic_block,
|
||||||
|
rtx *, rtx *, int);
|
||||||
|
|
||||||
|
extern bool delete_unreachable_blocks (void);
|
||||||
|
|
||||||
|
extern void update_br_prob_note (basic_block);
|
||||||
|
extern bool inside_basic_block_p (const_rtx);
|
||||||
|
extern bool control_flow_insn_p (const_rtx);
|
||||||
|
extern rtx get_last_bb_insn (basic_block);
|
||||||
|
|
||||||
|
/* In dominance.c */
|
||||||
|
|
||||||
|
enum cdi_direction
|
||||||
|
{
|
||||||
|
CDI_DOMINATORS = 1,
|
||||||
|
CDI_POST_DOMINATORS = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
extern enum dom_state dom_info_state (enum cdi_direction);
|
||||||
|
extern void set_dom_info_availability (enum cdi_direction, enum dom_state);
|
||||||
|
extern bool dom_info_available_p (enum cdi_direction);
|
||||||
|
extern void calculate_dominance_info (enum cdi_direction);
|
||||||
|
extern void free_dominance_info (enum cdi_direction);
|
||||||
|
extern basic_block nearest_common_dominator (enum cdi_direction,
|
||||||
|
basic_block, basic_block);
|
||||||
|
extern basic_block nearest_common_dominator_for_set (enum cdi_direction,
|
||||||
|
bitmap);
|
||||||
|
extern void set_immediate_dominator (enum cdi_direction, basic_block,
|
||||||
|
basic_block);
|
||||||
|
extern basic_block get_immediate_dominator (enum cdi_direction, basic_block);
|
||||||
|
extern bool dominated_by_p (enum cdi_direction, const_basic_block, const_basic_block);
|
||||||
|
extern vec<basic_block> get_dominated_by (enum cdi_direction, basic_block);
|
||||||
|
extern vec<basic_block> get_dominated_by_region (enum cdi_direction,
|
||||||
|
basic_block *,
|
||||||
|
unsigned);
|
||||||
|
extern vec<basic_block> get_dominated_to_depth (enum cdi_direction,
|
||||||
|
basic_block, int);
|
||||||
|
extern vec<basic_block> get_all_dominated_blocks (enum cdi_direction,
|
||||||
|
basic_block);
|
||||||
|
extern void add_to_dominance_info (enum cdi_direction, basic_block);
|
||||||
|
extern void delete_from_dominance_info (enum cdi_direction, basic_block);
|
||||||
|
basic_block recompute_dominator (enum cdi_direction, basic_block);
|
||||||
|
extern void redirect_immediate_dominators (enum cdi_direction, basic_block,
|
||||||
|
basic_block);
|
||||||
|
extern void iterate_fix_dominators (enum cdi_direction,
|
||||||
|
vec<basic_block> , bool);
|
||||||
|
extern void verify_dominators (enum cdi_direction);
|
||||||
|
extern basic_block first_dom_son (enum cdi_direction, basic_block);
|
||||||
|
extern basic_block next_dom_son (enum cdi_direction, basic_block);
|
||||||
|
unsigned bb_dom_dfs_in (enum cdi_direction, basic_block);
|
||||||
|
unsigned bb_dom_dfs_out (enum cdi_direction, basic_block);
|
||||||
|
|
||||||
|
extern edge try_redirect_by_replacing_jump (edge, basic_block, bool);
|
||||||
|
extern void break_superblocks (void);
|
||||||
|
extern void relink_block_chain (bool);
|
||||||
|
extern void update_bb_profile_for_threading (basic_block, int, gcov_type, edge);
|
||||||
|
extern void init_rtl_bb_info (basic_block);
|
||||||
|
|
||||||
|
extern void initialize_original_copy_tables (void);
|
||||||
|
extern void free_original_copy_tables (void);
|
||||||
|
extern void set_bb_original (basic_block, basic_block);
|
||||||
|
extern basic_block get_bb_original (basic_block);
|
||||||
|
extern void set_bb_copy (basic_block, basic_block);
|
||||||
|
extern basic_block get_bb_copy (basic_block);
|
||||||
|
void set_loop_copy (struct loop *, struct loop *);
|
||||||
|
struct loop *get_loop_copy (struct loop *);
|
||||||
|
|
||||||
|
#include "cfghooks.h"
|
||||||
|
|
||||||
|
/* Return true when one of the predecessor edges of BB is marked with EDGE_EH. */
|
||||||
|
static inline bool
|
||||||
|
bb_has_eh_pred (basic_block bb)
|
||||||
|
{
|
||||||
|
edge e;
|
||||||
|
edge_iterator ei;
|
||||||
|
|
||||||
|
FOR_EACH_EDGE (e, ei, bb->preds)
|
||||||
|
{
|
||||||
|
if (e->flags & EDGE_EH)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return true when one of the predecessor edges of BB is marked with EDGE_ABNORMAL. */
|
||||||
|
static inline bool
|
||||||
|
bb_has_abnormal_pred (basic_block bb)
|
||||||
|
{
|
||||||
|
edge e;
|
||||||
|
edge_iterator ei;
|
||||||
|
|
||||||
|
FOR_EACH_EDGE (e, ei, bb->preds)
|
||||||
|
{
|
||||||
|
if (e->flags & EDGE_ABNORMAL)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the fallthru edge in EDGES if it exists, NULL otherwise. */
|
||||||
|
static inline edge
|
||||||
|
find_fallthru_edge (vec<edge, va_gc> *edges)
|
||||||
|
{
|
||||||
|
edge e;
|
||||||
|
edge_iterator ei;
|
||||||
|
|
||||||
|
FOR_EACH_EDGE (e, ei, edges)
|
||||||
|
if (e->flags & EDGE_FALLTHRU)
|
||||||
|
break;
|
||||||
|
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* In cfgloopmanip.c. */
|
||||||
|
extern edge mfb_kj_edge;
|
||||||
|
extern bool mfb_keep_just (edge);
|
||||||
|
|
||||||
|
/* In cfgexpand.c. */
|
||||||
|
extern void rtl_profile_for_bb (basic_block);
|
||||||
|
extern void rtl_profile_for_edge (edge);
|
||||||
|
extern void default_rtl_profile (void);
|
||||||
|
|
||||||
|
/* In profile.c. */
|
||||||
|
extern gcov_working_set_t *find_working_set(unsigned pct_times_10);
|
||||||
|
|
||||||
|
/* Check tha probability is sane. */
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
check_probability (int prob)
|
||||||
|
{
|
||||||
|
gcc_checking_assert (prob >= 0 && prob <= REG_BR_PROB_BASE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Given PROB1 and PROB2, return PROB1*PROB2/REG_BR_PROB_BASE.
|
||||||
|
Used to combine BB probabilities. */
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
combine_probabilities (int prob1, int prob2)
|
||||||
|
{
|
||||||
|
check_probability (prob1);
|
||||||
|
check_probability (prob2);
|
||||||
|
return RDIV (prob1 * prob2, REG_BR_PROB_BASE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Apply probability PROB on frequency or count FREQ. */
|
||||||
|
|
||||||
|
static inline gcov_type
|
||||||
|
apply_probability (gcov_type freq, int prob)
|
||||||
|
{
|
||||||
|
check_probability (prob);
|
||||||
|
return RDIV (freq * prob, REG_BR_PROB_BASE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return inverse probability for PROB. */
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
inverse_probability (int prob1)
|
||||||
|
{
|
||||||
|
check_probability (prob1);
|
||||||
|
return REG_BR_PROB_BASE - prob1;
|
||||||
|
}
|
||||||
|
#endif /* GCC_BASIC_BLOCK_H */
|
|
@ -0,0 +1,713 @@
|
||||||
|
/* Functions to support general ended bitmaps.
|
||||||
|
Copyright (C) 1997-2013 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free
|
||||||
|
Software Foundation; either version 3, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GCC; see the file COPYING3. If not see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#ifndef GCC_BITMAP_H
|
||||||
|
#define GCC_BITMAP_H
|
||||||
|
|
||||||
|
/* Implementation of sparse integer sets as a linked list.
|
||||||
|
|
||||||
|
This sparse set representation is suitable for sparse sets with an
|
||||||
|
unknown (a priori) universe. The set is represented as a double-linked
|
||||||
|
list of container nodes (struct bitmap_element_def). Each node consists
|
||||||
|
of an index for the first member that could be held in the container,
|
||||||
|
a small array of integers that represent the members in the container,
|
||||||
|
and pointers to the next and previous element in the linked list. The
|
||||||
|
elements in the list are sorted in ascending order, i.e. the head of
|
||||||
|
the list holds the element with the smallest member of the set.
|
||||||
|
|
||||||
|
For a given member I in the set:
|
||||||
|
- the element for I will have index is I / (bits per element)
|
||||||
|
- the position for I within element is I % (bits per element)
|
||||||
|
|
||||||
|
This representation is very space-efficient for large sparse sets, and
|
||||||
|
the size of the set can be changed dynamically without much overhead.
|
||||||
|
An important parameter is the number of bits per element. In this
|
||||||
|
implementation, there are 128 bits per element. This results in a
|
||||||
|
high storage overhead *per element*, but a small overall overhead if
|
||||||
|
the set is very sparse.
|
||||||
|
|
||||||
|
The downside is that many operations are relatively slow because the
|
||||||
|
linked list has to be traversed to test membership (i.e. member_p/
|
||||||
|
add_member/remove_member). To improve the performance of this set
|
||||||
|
representation, the last accessed element and its index are cached.
|
||||||
|
For membership tests on members close to recently accessed members,
|
||||||
|
the cached last element improves membership test to a constant-time
|
||||||
|
operation.
|
||||||
|
|
||||||
|
The following operations can always be performed in O(1) time:
|
||||||
|
|
||||||
|
* clear : bitmap_clear
|
||||||
|
* choose_one : (not implemented, but could be
|
||||||
|
implemented in constant time)
|
||||||
|
|
||||||
|
The following operations can be performed in O(E) time worst-case (with
|
||||||
|
E the number of elements in the linked list), but in O(1) time with a
|
||||||
|
suitable access patterns:
|
||||||
|
|
||||||
|
* member_p : bitmap_bit_p
|
||||||
|
* add_member : bitmap_set_bit
|
||||||
|
* remove_member : bitmap_clear_bit
|
||||||
|
|
||||||
|
The following operations can be performed in O(E) time:
|
||||||
|
|
||||||
|
* cardinality : bitmap_count_bits
|
||||||
|
* set_size : bitmap_last_set_bit (but this could
|
||||||
|
in constant time with a pointer to
|
||||||
|
the last element in the chain)
|
||||||
|
|
||||||
|
Additionally, the linked-list sparse set representation supports
|
||||||
|
enumeration of the members in O(E) time:
|
||||||
|
|
||||||
|
* forall : EXECUTE_IF_SET_IN_BITMAP
|
||||||
|
* set_copy : bitmap_copy
|
||||||
|
* set_intersection : bitmap_intersect_p /
|
||||||
|
bitmap_and / bitmap_and_into /
|
||||||
|
EXECUTE_IF_AND_IN_BITMAP
|
||||||
|
* set_union : bitmap_ior / bitmap_ior_into
|
||||||
|
* set_difference : bitmap_intersect_compl_p /
|
||||||
|
bitmap_and_comp / bitmap_and_comp_into /
|
||||||
|
EXECUTE_IF_AND_COMPL_IN_BITMAP
|
||||||
|
* set_disjuction : bitmap_xor_comp / bitmap_xor_comp_into
|
||||||
|
* set_compare : bitmap_equal_p
|
||||||
|
|
||||||
|
Some operations on 3 sets that occur frequently in in data flow problems
|
||||||
|
are also implemented:
|
||||||
|
|
||||||
|
* A | (B & C) : bitmap_ior_and_into
|
||||||
|
* A | (B & ~C) : bitmap_ior_and_compl /
|
||||||
|
bitmap_ior_and_compl_into
|
||||||
|
|
||||||
|
The storage requirements for linked-list sparse sets are O(E), with E->N
|
||||||
|
in the worst case (a sparse set with large distances between the values
|
||||||
|
of the set members).
|
||||||
|
|
||||||
|
The linked-list set representation works well for problems involving very
|
||||||
|
sparse sets. The canonical example in GCC is, of course, the "set of
|
||||||
|
sets" for some CFG-based data flow problems (liveness analysis, dominance
|
||||||
|
frontiers, etc.).
|
||||||
|
|
||||||
|
This representation also works well for data flow problems where the size
|
||||||
|
of the set may grow dynamically, but care must be taken that the member_p,
|
||||||
|
add_member, and remove_member operations occur with a suitable access
|
||||||
|
pattern.
|
||||||
|
|
||||||
|
For random-access sets with a known, relatively small universe size, the
|
||||||
|
SparseSet or simple bitmap representations may be more efficient than a
|
||||||
|
linked-list set. For random-access sets of unknown universe, a hash table
|
||||||
|
or a balanced binary tree representation is likely to be a more suitable
|
||||||
|
choice.
|
||||||
|
|
||||||
|
Traversing linked lists is usually cache-unfriendly, even with the last
|
||||||
|
accessed element cached.
|
||||||
|
|
||||||
|
Cache performance can be improved by keeping the elements in the set
|
||||||
|
grouped together in memory, using a dedicated obstack for a set (or group
|
||||||
|
of related sets). Elements allocated on obstacks are released to a
|
||||||
|
free-list and taken off the free list. If multiple sets are allocated on
|
||||||
|
the same obstack, elements freed from one set may be re-used for one of
|
||||||
|
the other sets. This usually helps avoid cache misses.
|
||||||
|
|
||||||
|
A single free-list is used for all sets allocated in GGC space. This is
|
||||||
|
bad for persistent sets, so persistent sets should be allocated on an
|
||||||
|
obstack whenever possible. */
|
||||||
|
|
||||||
|
#include "hashtab.h"
|
||||||
|
#include "statistics.h"
|
||||||
|
#include "obstack.h"
|
||||||
|
|
||||||
|
/* Fundamental storage type for bitmap. */
|
||||||
|
|
||||||
|
typedef unsigned long BITMAP_WORD;
|
||||||
|
/* BITMAP_WORD_BITS needs to be unsigned, but cannot contain casts as
|
||||||
|
it is used in preprocessor directives -- hence the 1u. */
|
||||||
|
#define BITMAP_WORD_BITS (CHAR_BIT * SIZEOF_LONG * 1u)
|
||||||
|
|
||||||
|
/* Number of words to use for each element in the linked list. */
|
||||||
|
|
||||||
|
#ifndef BITMAP_ELEMENT_WORDS
|
||||||
|
#define BITMAP_ELEMENT_WORDS ((128 + BITMAP_WORD_BITS - 1) / BITMAP_WORD_BITS)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Number of bits in each actual element of a bitmap. */
|
||||||
|
|
||||||
|
#define BITMAP_ELEMENT_ALL_BITS (BITMAP_ELEMENT_WORDS * BITMAP_WORD_BITS)
|
||||||
|
|
||||||
|
/* Obstack for allocating bitmaps and elements from. */
|
||||||
|
typedef struct GTY (()) bitmap_obstack {
|
||||||
|
struct bitmap_element_def *elements;
|
||||||
|
struct bitmap_head_def *heads;
|
||||||
|
struct obstack GTY ((skip)) obstack;
|
||||||
|
} bitmap_obstack;
|
||||||
|
|
||||||
|
/* Bitmap set element. We use a linked list to hold only the bits that
|
||||||
|
are set. This allows for use to grow the bitset dynamically without
|
||||||
|
having to realloc and copy a giant bit array.
|
||||||
|
|
||||||
|
The free list is implemented as a list of lists. There is one
|
||||||
|
outer list connected together by prev fields. Each element of that
|
||||||
|
outer is an inner list (that may consist only of the outer list
|
||||||
|
element) that are connected by the next fields. The prev pointer
|
||||||
|
is undefined for interior elements. This allows
|
||||||
|
bitmap_elt_clear_from to be implemented in unit time rather than
|
||||||
|
linear in the number of elements to be freed. */
|
||||||
|
|
||||||
|
typedef struct GTY((chain_next ("%h.next"), chain_prev ("%h.prev"))) bitmap_element_def {
|
||||||
|
struct bitmap_element_def *next; /* Next element. */
|
||||||
|
struct bitmap_element_def *prev; /* Previous element. */
|
||||||
|
unsigned int indx; /* regno/BITMAP_ELEMENT_ALL_BITS. */
|
||||||
|
BITMAP_WORD bits[BITMAP_ELEMENT_WORDS]; /* Bits that are set. */
|
||||||
|
} bitmap_element;
|
||||||
|
|
||||||
|
/* Head of bitmap linked list. The 'current' member points to something
|
||||||
|
already pointed to by the chain started by first, so GTY((skip)) it. */
|
||||||
|
|
||||||
|
typedef struct GTY(()) bitmap_head_def {
|
||||||
|
unsigned int indx; /* Index of last element looked at. */
|
||||||
|
unsigned int descriptor_id; /* Unique identifier for the allocation
|
||||||
|
site of this bitmap, for detailed
|
||||||
|
statistics gathering. */
|
||||||
|
bitmap_element *first; /* First element in linked list. */
|
||||||
|
bitmap_element * GTY((skip(""))) current; /* Last element looked at. */
|
||||||
|
bitmap_obstack *obstack; /* Obstack to allocate elements from.
|
||||||
|
If NULL, then use GGC allocation. */
|
||||||
|
} bitmap_head;
|
||||||
|
|
||||||
|
/* Global data */
|
||||||
|
extern bitmap_element bitmap_zero_bits; /* Zero bitmap element */
|
||||||
|
extern bitmap_obstack bitmap_default_obstack; /* Default bitmap obstack */
|
||||||
|
|
||||||
|
/* Clear a bitmap by freeing up the linked list. */
|
||||||
|
extern void bitmap_clear (bitmap);
|
||||||
|
|
||||||
|
/* Copy a bitmap to another bitmap. */
|
||||||
|
extern void bitmap_copy (bitmap, const_bitmap);
|
||||||
|
|
||||||
|
/* True if two bitmaps are identical. */
|
||||||
|
extern bool bitmap_equal_p (const_bitmap, const_bitmap);
|
||||||
|
|
||||||
|
/* True if the bitmaps intersect (their AND is non-empty). */
|
||||||
|
extern bool bitmap_intersect_p (const_bitmap, const_bitmap);
|
||||||
|
|
||||||
|
/* True if the complement of the second intersects the first (their
|
||||||
|
AND_COMPL is non-empty). */
|
||||||
|
extern bool bitmap_intersect_compl_p (const_bitmap, const_bitmap);
|
||||||
|
|
||||||
|
/* True if MAP is an empty bitmap. */
|
||||||
|
inline bool bitmap_empty_p (const_bitmap map)
|
||||||
|
{
|
||||||
|
return !map->first;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* True if the bitmap has only a single bit set. */
|
||||||
|
extern bool bitmap_single_bit_set_p (const_bitmap);
|
||||||
|
|
||||||
|
/* Count the number of bits set in the bitmap. */
|
||||||
|
extern unsigned long bitmap_count_bits (const_bitmap);
|
||||||
|
|
||||||
|
/* Boolean operations on bitmaps. The _into variants are two operand
|
||||||
|
versions that modify the first source operand. The other variants
|
||||||
|
are three operand versions that to not destroy the source bitmaps.
|
||||||
|
The operations supported are &, & ~, |, ^. */
|
||||||
|
extern void bitmap_and (bitmap, const_bitmap, const_bitmap);
|
||||||
|
extern bool bitmap_and_into (bitmap, const_bitmap);
|
||||||
|
extern bool bitmap_and_compl (bitmap, const_bitmap, const_bitmap);
|
||||||
|
extern bool bitmap_and_compl_into (bitmap, const_bitmap);
|
||||||
|
#define bitmap_compl_and(DST, A, B) bitmap_and_compl (DST, B, A)
|
||||||
|
extern void bitmap_compl_and_into (bitmap, const_bitmap);
|
||||||
|
extern void bitmap_clear_range (bitmap, unsigned int, unsigned int);
|
||||||
|
extern void bitmap_set_range (bitmap, unsigned int, unsigned int);
|
||||||
|
extern bool bitmap_ior (bitmap, const_bitmap, const_bitmap);
|
||||||
|
extern bool bitmap_ior_into (bitmap, const_bitmap);
|
||||||
|
extern void bitmap_xor (bitmap, const_bitmap, const_bitmap);
|
||||||
|
extern void bitmap_xor_into (bitmap, const_bitmap);
|
||||||
|
|
||||||
|
/* DST = A | (B & C). Return true if DST changes. */
|
||||||
|
extern bool bitmap_ior_and_into (bitmap DST, const_bitmap B, const_bitmap C);
|
||||||
|
/* DST = A | (B & ~C). Return true if DST changes. */
|
||||||
|
extern bool bitmap_ior_and_compl (bitmap DST, const_bitmap A,
|
||||||
|
const_bitmap B, const_bitmap C);
|
||||||
|
/* A |= (B & ~C). Return true if A changes. */
|
||||||
|
extern bool bitmap_ior_and_compl_into (bitmap A,
|
||||||
|
const_bitmap B, const_bitmap C);
|
||||||
|
|
||||||
|
/* Clear a single bit in a bitmap. Return true if the bit changed. */
|
||||||
|
extern bool bitmap_clear_bit (bitmap, int);
|
||||||
|
|
||||||
|
/* Set a single bit in a bitmap. Return true if the bit changed. */
|
||||||
|
extern bool bitmap_set_bit (bitmap, int);
|
||||||
|
|
||||||
|
/* Return true if a register is set in a register set. */
|
||||||
|
extern int bitmap_bit_p (bitmap, int);
|
||||||
|
|
||||||
|
/* Debug functions to print a bitmap linked list. */
|
||||||
|
extern void debug_bitmap (const_bitmap);
|
||||||
|
extern void debug_bitmap_file (FILE *, const_bitmap);
|
||||||
|
|
||||||
|
/* Print a bitmap. */
|
||||||
|
extern void bitmap_print (FILE *, const_bitmap, const char *, const char *);
|
||||||
|
|
||||||
|
/* Initialize and release a bitmap obstack. */
|
||||||
|
extern void bitmap_obstack_initialize (bitmap_obstack *);
|
||||||
|
extern void bitmap_obstack_release (bitmap_obstack *);
|
||||||
|
extern void bitmap_register (bitmap MEM_STAT_DECL);
|
||||||
|
extern void dump_bitmap_statistics (void);
|
||||||
|
|
||||||
|
/* Initialize a bitmap header. OBSTACK indicates the bitmap obstack
|
||||||
|
to allocate from, NULL for GC'd bitmap. */
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
bitmap_initialize_stat (bitmap head, bitmap_obstack *obstack MEM_STAT_DECL)
|
||||||
|
{
|
||||||
|
head->first = head->current = NULL;
|
||||||
|
head->obstack = obstack;
|
||||||
|
if (GATHER_STATISTICS)
|
||||||
|
bitmap_register (head PASS_MEM_STAT);
|
||||||
|
}
|
||||||
|
#define bitmap_initialize(h,o) bitmap_initialize_stat (h,o MEM_STAT_INFO)
|
||||||
|
|
||||||
|
/* Allocate and free bitmaps from obstack, malloc and gc'd memory. */
|
||||||
|
extern bitmap bitmap_obstack_alloc_stat (bitmap_obstack *obstack MEM_STAT_DECL);
|
||||||
|
#define bitmap_obstack_alloc(t) bitmap_obstack_alloc_stat (t MEM_STAT_INFO)
|
||||||
|
extern bitmap bitmap_gc_alloc_stat (ALONE_MEM_STAT_DECL);
|
||||||
|
#define bitmap_gc_alloc() bitmap_gc_alloc_stat (ALONE_MEM_STAT_INFO)
|
||||||
|
extern void bitmap_obstack_free (bitmap);
|
||||||
|
|
||||||
|
/* A few compatibility/functions macros for compatibility with sbitmaps */
|
||||||
|
inline void dump_bitmap (FILE *file, const_bitmap map)
|
||||||
|
{
|
||||||
|
bitmap_print (file, map, "", "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
extern unsigned bitmap_first_set_bit (const_bitmap);
|
||||||
|
extern unsigned bitmap_last_set_bit (const_bitmap);
|
||||||
|
|
||||||
|
/* Compute bitmap hash (for purposes of hashing etc.) */
|
||||||
|
extern hashval_t bitmap_hash(const_bitmap);
|
||||||
|
|
||||||
|
/* Allocate a bitmap from a bit obstack. */
|
||||||
|
#define BITMAP_ALLOC(OBSTACK) bitmap_obstack_alloc (OBSTACK)
|
||||||
|
|
||||||
|
/* Allocate a gc'd bitmap. */
|
||||||
|
#define BITMAP_GGC_ALLOC() bitmap_gc_alloc ()
|
||||||
|
|
||||||
|
/* Do any cleanup needed on a bitmap when it is no longer used. */
|
||||||
|
#define BITMAP_FREE(BITMAP) \
|
||||||
|
((void) (bitmap_obstack_free ((bitmap) BITMAP), (BITMAP) = (bitmap) NULL))
|
||||||
|
|
||||||
|
/* Iterator for bitmaps. */
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
/* Pointer to the current bitmap element. */
|
||||||
|
bitmap_element *elt1;
|
||||||
|
|
||||||
|
/* Pointer to 2nd bitmap element when two are involved. */
|
||||||
|
bitmap_element *elt2;
|
||||||
|
|
||||||
|
/* Word within the current element. */
|
||||||
|
unsigned word_no;
|
||||||
|
|
||||||
|
/* Contents of the actually processed word. When finding next bit
|
||||||
|
it is shifted right, so that the actual bit is always the least
|
||||||
|
significant bit of ACTUAL. */
|
||||||
|
BITMAP_WORD bits;
|
||||||
|
} bitmap_iterator;
|
||||||
|
|
||||||
|
/* Initialize a single bitmap iterator. START_BIT is the first bit to
|
||||||
|
iterate from. */
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
bmp_iter_set_init (bitmap_iterator *bi, const_bitmap map,
|
||||||
|
unsigned start_bit, unsigned *bit_no)
|
||||||
|
{
|
||||||
|
bi->elt1 = map->first;
|
||||||
|
bi->elt2 = NULL;
|
||||||
|
|
||||||
|
/* Advance elt1 until it is not before the block containing start_bit. */
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
if (!bi->elt1)
|
||||||
|
{
|
||||||
|
bi->elt1 = &bitmap_zero_bits;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bi->elt1->indx >= start_bit / BITMAP_ELEMENT_ALL_BITS)
|
||||||
|
break;
|
||||||
|
bi->elt1 = bi->elt1->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We might have gone past the start bit, so reinitialize it. */
|
||||||
|
if (bi->elt1->indx != start_bit / BITMAP_ELEMENT_ALL_BITS)
|
||||||
|
start_bit = bi->elt1->indx * BITMAP_ELEMENT_ALL_BITS;
|
||||||
|
|
||||||
|
/* Initialize for what is now start_bit. */
|
||||||
|
bi->word_no = start_bit / BITMAP_WORD_BITS % BITMAP_ELEMENT_WORDS;
|
||||||
|
bi->bits = bi->elt1->bits[bi->word_no];
|
||||||
|
bi->bits >>= start_bit % BITMAP_WORD_BITS;
|
||||||
|
|
||||||
|
/* If this word is zero, we must make sure we're not pointing at the
|
||||||
|
first bit, otherwise our incrementing to the next word boundary
|
||||||
|
will fail. It won't matter if this increment moves us into the
|
||||||
|
next word. */
|
||||||
|
start_bit += !bi->bits;
|
||||||
|
|
||||||
|
*bit_no = start_bit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize an iterator to iterate over the intersection of two
|
||||||
|
bitmaps. START_BIT is the bit to commence from. */
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
bmp_iter_and_init (bitmap_iterator *bi, const_bitmap map1, const_bitmap map2,
|
||||||
|
unsigned start_bit, unsigned *bit_no)
|
||||||
|
{
|
||||||
|
bi->elt1 = map1->first;
|
||||||
|
bi->elt2 = map2->first;
|
||||||
|
|
||||||
|
/* Advance elt1 until it is not before the block containing
|
||||||
|
start_bit. */
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
if (!bi->elt1)
|
||||||
|
{
|
||||||
|
bi->elt2 = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bi->elt1->indx >= start_bit / BITMAP_ELEMENT_ALL_BITS)
|
||||||
|
break;
|
||||||
|
bi->elt1 = bi->elt1->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Advance elt2 until it is not before elt1. */
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
if (!bi->elt2)
|
||||||
|
{
|
||||||
|
bi->elt1 = bi->elt2 = &bitmap_zero_bits;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bi->elt2->indx >= bi->elt1->indx)
|
||||||
|
break;
|
||||||
|
bi->elt2 = bi->elt2->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we're at the same index, then we have some intersecting bits. */
|
||||||
|
if (bi->elt1->indx == bi->elt2->indx)
|
||||||
|
{
|
||||||
|
/* We might have advanced beyond the start_bit, so reinitialize
|
||||||
|
for that. */
|
||||||
|
if (bi->elt1->indx != start_bit / BITMAP_ELEMENT_ALL_BITS)
|
||||||
|
start_bit = bi->elt1->indx * BITMAP_ELEMENT_ALL_BITS;
|
||||||
|
|
||||||
|
bi->word_no = start_bit / BITMAP_WORD_BITS % BITMAP_ELEMENT_WORDS;
|
||||||
|
bi->bits = bi->elt1->bits[bi->word_no] & bi->elt2->bits[bi->word_no];
|
||||||
|
bi->bits >>= start_bit % BITMAP_WORD_BITS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Otherwise we must immediately advance elt1, so initialize for
|
||||||
|
that. */
|
||||||
|
bi->word_no = BITMAP_ELEMENT_WORDS - 1;
|
||||||
|
bi->bits = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If this word is zero, we must make sure we're not pointing at the
|
||||||
|
first bit, otherwise our incrementing to the next word boundary
|
||||||
|
will fail. It won't matter if this increment moves us into the
|
||||||
|
next word. */
|
||||||
|
start_bit += !bi->bits;
|
||||||
|
|
||||||
|
*bit_no = start_bit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize an iterator to iterate over the bits in MAP1 & ~MAP2.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
bmp_iter_and_compl_init (bitmap_iterator *bi,
|
||||||
|
const_bitmap map1, const_bitmap map2,
|
||||||
|
unsigned start_bit, unsigned *bit_no)
|
||||||
|
{
|
||||||
|
bi->elt1 = map1->first;
|
||||||
|
bi->elt2 = map2->first;
|
||||||
|
|
||||||
|
/* Advance elt1 until it is not before the block containing start_bit. */
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
if (!bi->elt1)
|
||||||
|
{
|
||||||
|
bi->elt1 = &bitmap_zero_bits;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bi->elt1->indx >= start_bit / BITMAP_ELEMENT_ALL_BITS)
|
||||||
|
break;
|
||||||
|
bi->elt1 = bi->elt1->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Advance elt2 until it is not before elt1. */
|
||||||
|
while (bi->elt2 && bi->elt2->indx < bi->elt1->indx)
|
||||||
|
bi->elt2 = bi->elt2->next;
|
||||||
|
|
||||||
|
/* We might have advanced beyond the start_bit, so reinitialize for
|
||||||
|
that. */
|
||||||
|
if (bi->elt1->indx != start_bit / BITMAP_ELEMENT_ALL_BITS)
|
||||||
|
start_bit = bi->elt1->indx * BITMAP_ELEMENT_ALL_BITS;
|
||||||
|
|
||||||
|
bi->word_no = start_bit / BITMAP_WORD_BITS % BITMAP_ELEMENT_WORDS;
|
||||||
|
bi->bits = bi->elt1->bits[bi->word_no];
|
||||||
|
if (bi->elt2 && bi->elt1->indx == bi->elt2->indx)
|
||||||
|
bi->bits &= ~bi->elt2->bits[bi->word_no];
|
||||||
|
bi->bits >>= start_bit % BITMAP_WORD_BITS;
|
||||||
|
|
||||||
|
/* If this word is zero, we must make sure we're not pointing at the
|
||||||
|
first bit, otherwise our incrementing to the next word boundary
|
||||||
|
will fail. It won't matter if this increment moves us into the
|
||||||
|
next word. */
|
||||||
|
start_bit += !bi->bits;
|
||||||
|
|
||||||
|
*bit_no = start_bit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Advance to the next bit in BI. We don't advance to the next
|
||||||
|
nonzero bit yet. */
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
bmp_iter_next (bitmap_iterator *bi, unsigned *bit_no)
|
||||||
|
{
|
||||||
|
bi->bits >>= 1;
|
||||||
|
*bit_no += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Advance to first set bit in BI. */
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
bmp_iter_next_bit (bitmap_iterator * bi, unsigned *bit_no)
|
||||||
|
{
|
||||||
|
#if (GCC_VERSION >= 3004)
|
||||||
|
{
|
||||||
|
unsigned int n = __builtin_ctzl (bi->bits);
|
||||||
|
gcc_assert (sizeof (unsigned long) == sizeof (BITMAP_WORD));
|
||||||
|
bi->bits >>= n;
|
||||||
|
*bit_no += n;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
while (!(bi->bits & 1))
|
||||||
|
{
|
||||||
|
bi->bits >>= 1;
|
||||||
|
*bit_no += 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Advance to the next nonzero bit of a single bitmap, we will have
|
||||||
|
already advanced past the just iterated bit. Return true if there
|
||||||
|
is a bit to iterate. */
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
bmp_iter_set (bitmap_iterator *bi, unsigned *bit_no)
|
||||||
|
{
|
||||||
|
/* If our current word is nonzero, it contains the bit we want. */
|
||||||
|
if (bi->bits)
|
||||||
|
{
|
||||||
|
next_bit:
|
||||||
|
bmp_iter_next_bit (bi, bit_no);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Round up to the word boundary. We might have just iterated past
|
||||||
|
the end of the last word, hence the -1. It is not possible for
|
||||||
|
bit_no to point at the beginning of the now last word. */
|
||||||
|
*bit_no = ((*bit_no + BITMAP_WORD_BITS - 1)
|
||||||
|
/ BITMAP_WORD_BITS * BITMAP_WORD_BITS);
|
||||||
|
bi->word_no++;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
/* Find the next nonzero word in this elt. */
|
||||||
|
while (bi->word_no != BITMAP_ELEMENT_WORDS)
|
||||||
|
{
|
||||||
|
bi->bits = bi->elt1->bits[bi->word_no];
|
||||||
|
if (bi->bits)
|
||||||
|
goto next_bit;
|
||||||
|
*bit_no += BITMAP_WORD_BITS;
|
||||||
|
bi->word_no++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Advance to the next element. */
|
||||||
|
bi->elt1 = bi->elt1->next;
|
||||||
|
if (!bi->elt1)
|
||||||
|
return false;
|
||||||
|
*bit_no = bi->elt1->indx * BITMAP_ELEMENT_ALL_BITS;
|
||||||
|
bi->word_no = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Advance to the next nonzero bit of an intersecting pair of
|
||||||
|
bitmaps. We will have already advanced past the just iterated bit.
|
||||||
|
Return true if there is a bit to iterate. */
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
bmp_iter_and (bitmap_iterator *bi, unsigned *bit_no)
|
||||||
|
{
|
||||||
|
/* If our current word is nonzero, it contains the bit we want. */
|
||||||
|
if (bi->bits)
|
||||||
|
{
|
||||||
|
next_bit:
|
||||||
|
bmp_iter_next_bit (bi, bit_no);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Round up to the word boundary. We might have just iterated past
|
||||||
|
the end of the last word, hence the -1. It is not possible for
|
||||||
|
bit_no to point at the beginning of the now last word. */
|
||||||
|
*bit_no = ((*bit_no + BITMAP_WORD_BITS - 1)
|
||||||
|
/ BITMAP_WORD_BITS * BITMAP_WORD_BITS);
|
||||||
|
bi->word_no++;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
/* Find the next nonzero word in this elt. */
|
||||||
|
while (bi->word_no != BITMAP_ELEMENT_WORDS)
|
||||||
|
{
|
||||||
|
bi->bits = bi->elt1->bits[bi->word_no] & bi->elt2->bits[bi->word_no];
|
||||||
|
if (bi->bits)
|
||||||
|
goto next_bit;
|
||||||
|
*bit_no += BITMAP_WORD_BITS;
|
||||||
|
bi->word_no++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Advance to the next identical element. */
|
||||||
|
do
|
||||||
|
{
|
||||||
|
/* Advance elt1 while it is less than elt2. We always want
|
||||||
|
to advance one elt. */
|
||||||
|
do
|
||||||
|
{
|
||||||
|
bi->elt1 = bi->elt1->next;
|
||||||
|
if (!bi->elt1)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
while (bi->elt1->indx < bi->elt2->indx);
|
||||||
|
|
||||||
|
/* Advance elt2 to be no less than elt1. This might not
|
||||||
|
advance. */
|
||||||
|
while (bi->elt2->indx < bi->elt1->indx)
|
||||||
|
{
|
||||||
|
bi->elt2 = bi->elt2->next;
|
||||||
|
if (!bi->elt2)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (bi->elt1->indx != bi->elt2->indx);
|
||||||
|
|
||||||
|
*bit_no = bi->elt1->indx * BITMAP_ELEMENT_ALL_BITS;
|
||||||
|
bi->word_no = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Advance to the next nonzero bit in the intersection of
|
||||||
|
complemented bitmaps. We will have already advanced past the just
|
||||||
|
iterated bit. */
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
bmp_iter_and_compl (bitmap_iterator *bi, unsigned *bit_no)
|
||||||
|
{
|
||||||
|
/* If our current word is nonzero, it contains the bit we want. */
|
||||||
|
if (bi->bits)
|
||||||
|
{
|
||||||
|
next_bit:
|
||||||
|
bmp_iter_next_bit (bi, bit_no);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Round up to the word boundary. We might have just iterated past
|
||||||
|
the end of the last word, hence the -1. It is not possible for
|
||||||
|
bit_no to point at the beginning of the now last word. */
|
||||||
|
*bit_no = ((*bit_no + BITMAP_WORD_BITS - 1)
|
||||||
|
/ BITMAP_WORD_BITS * BITMAP_WORD_BITS);
|
||||||
|
bi->word_no++;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
/* Find the next nonzero word in this elt. */
|
||||||
|
while (bi->word_no != BITMAP_ELEMENT_WORDS)
|
||||||
|
{
|
||||||
|
bi->bits = bi->elt1->bits[bi->word_no];
|
||||||
|
if (bi->elt2 && bi->elt2->indx == bi->elt1->indx)
|
||||||
|
bi->bits &= ~bi->elt2->bits[bi->word_no];
|
||||||
|
if (bi->bits)
|
||||||
|
goto next_bit;
|
||||||
|
*bit_no += BITMAP_WORD_BITS;
|
||||||
|
bi->word_no++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Advance to the next element of elt1. */
|
||||||
|
bi->elt1 = bi->elt1->next;
|
||||||
|
if (!bi->elt1)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/* Advance elt2 until it is no less than elt1. */
|
||||||
|
while (bi->elt2 && bi->elt2->indx < bi->elt1->indx)
|
||||||
|
bi->elt2 = bi->elt2->next;
|
||||||
|
|
||||||
|
*bit_no = bi->elt1->indx * BITMAP_ELEMENT_ALL_BITS;
|
||||||
|
bi->word_no = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Loop over all bits set in BITMAP, starting with MIN and setting
|
||||||
|
BITNUM to the bit number. ITER is a bitmap iterator. BITNUM
|
||||||
|
should be treated as a read-only variable as it contains loop
|
||||||
|
state. */
|
||||||
|
|
||||||
|
#ifndef EXECUTE_IF_SET_IN_BITMAP
|
||||||
|
/* See sbitmap.h for the other definition of EXECUTE_IF_SET_IN_BITMAP. */
|
||||||
|
#define EXECUTE_IF_SET_IN_BITMAP(BITMAP, MIN, BITNUM, ITER) \
|
||||||
|
for (bmp_iter_set_init (&(ITER), (BITMAP), (MIN), &(BITNUM)); \
|
||||||
|
bmp_iter_set (&(ITER), &(BITNUM)); \
|
||||||
|
bmp_iter_next (&(ITER), &(BITNUM)))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Loop over all the bits set in BITMAP1 & BITMAP2, starting with MIN
|
||||||
|
and setting BITNUM to the bit number. ITER is a bitmap iterator.
|
||||||
|
BITNUM should be treated as a read-only variable as it contains
|
||||||
|
loop state. */
|
||||||
|
|
||||||
|
#define EXECUTE_IF_AND_IN_BITMAP(BITMAP1, BITMAP2, MIN, BITNUM, ITER) \
|
||||||
|
for (bmp_iter_and_init (&(ITER), (BITMAP1), (BITMAP2), (MIN), \
|
||||||
|
&(BITNUM)); \
|
||||||
|
bmp_iter_and (&(ITER), &(BITNUM)); \
|
||||||
|
bmp_iter_next (&(ITER), &(BITNUM)))
|
||||||
|
|
||||||
|
/* Loop over all the bits set in BITMAP1 & ~BITMAP2, starting with MIN
|
||||||
|
and setting BITNUM to the bit number. ITER is a bitmap iterator.
|
||||||
|
BITNUM should be treated as a read-only variable as it contains
|
||||||
|
loop state. */
|
||||||
|
|
||||||
|
#define EXECUTE_IF_AND_COMPL_IN_BITMAP(BITMAP1, BITMAP2, MIN, BITNUM, ITER) \
|
||||||
|
for (bmp_iter_and_compl_init (&(ITER), (BITMAP1), (BITMAP2), (MIN), \
|
||||||
|
&(BITNUM)); \
|
||||||
|
bmp_iter_and_compl (&(ITER), &(BITNUM)); \
|
||||||
|
bmp_iter_next (&(ITER), &(BITNUM)))
|
||||||
|
|
||||||
|
#endif /* GCC_BITMAP_H */
|
|
@ -0,0 +1,842 @@
|
||||||
|
/* This file contains the definitions and documentation for the
|
||||||
|
builtins used in the GNU compiler.
|
||||||
|
Copyright (C) 2000-2013 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free
|
||||||
|
Software Foundation; either version 3, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GCC; see the file COPYING3. If not see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
/* Before including this file, you should define a macro:
|
||||||
|
|
||||||
|
DEF_BUILTIN (ENUM, NAME, CLASS, TYPE, LIBTYPE, BOTH_P,
|
||||||
|
FALLBACK_P, NONANSI_P, ATTRS, IMPLICIT, COND)
|
||||||
|
|
||||||
|
This macro will be called once for each builtin function. The
|
||||||
|
ENUM will be of type `enum built_in_function', and will indicate
|
||||||
|
which builtin function is being processed. The NAME of the builtin
|
||||||
|
function (which will always start with `__builtin_') is a string
|
||||||
|
literal. The CLASS is of type `enum built_in_class' and indicates
|
||||||
|
what kind of builtin is being processed.
|
||||||
|
|
||||||
|
Some builtins are actually two separate functions. For example,
|
||||||
|
for `strcmp' there are two builtin functions; `__builtin_strcmp'
|
||||||
|
and `strcmp' itself. Both behave identically. Other builtins
|
||||||
|
define only the `__builtin' variant. If BOTH_P is TRUE, then this
|
||||||
|
builtin has both variants; otherwise, it is has only the first
|
||||||
|
variant.
|
||||||
|
|
||||||
|
TYPE indicates the type of the function. The symbols correspond to
|
||||||
|
enumerals from builtin-types.def. If BOTH_P is true, then LIBTYPE
|
||||||
|
is the type of the non-`__builtin_' variant. Otherwise, LIBTYPE
|
||||||
|
should be ignored.
|
||||||
|
|
||||||
|
If FALLBACK_P is true then, if for some reason, the compiler cannot
|
||||||
|
expand the builtin function directly, it will call the
|
||||||
|
corresponding library function (which does not have the
|
||||||
|
`__builtin_' prefix.
|
||||||
|
|
||||||
|
If NONANSI_P is true, then the non-`__builtin_' variant is not an
|
||||||
|
ANSI/ISO library function, and so we should pretend it does not
|
||||||
|
exist when compiling in ANSI conformant mode.
|
||||||
|
|
||||||
|
ATTRs is an attribute list as defined in builtin-attrs.def that
|
||||||
|
describes the attributes of this builtin function.
|
||||||
|
|
||||||
|
IMPLICIT specifies condition when the builtin can be produced by
|
||||||
|
compiler. For instance C90 reserves floorf function, but does not
|
||||||
|
define it's meaning. When user uses floorf we may assume that the
|
||||||
|
floorf has the meaning we expect, but we can't produce floorf by
|
||||||
|
simplifying floor((double)float) since the runtime need not implement
|
||||||
|
it.
|
||||||
|
|
||||||
|
The builtins is registered only if COND is true. */
|
||||||
|
|
||||||
|
/* A GCC builtin (like __builtin_saveregs) is provided by the
|
||||||
|
compiler, but does not correspond to a function in the standard
|
||||||
|
library. */
|
||||||
|
#undef DEF_GCC_BUILTIN
|
||||||
|
#define DEF_GCC_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
|
||||||
|
DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, BT_LAST, \
|
||||||
|
false, false, false, ATTRS, true, true)
|
||||||
|
|
||||||
|
/* Like DEF_GCC_BUILTIN, except we don't prepend "__builtin_". */
|
||||||
|
#undef DEF_SYNC_BUILTIN
|
||||||
|
#define DEF_SYNC_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
|
||||||
|
DEF_BUILTIN (ENUM, NAME, BUILT_IN_NORMAL, TYPE, BT_LAST, \
|
||||||
|
false, false, false, ATTRS, true, true)
|
||||||
|
|
||||||
|
/* A library builtin (like __builtin_strchr) is a builtin equivalent
|
||||||
|
of an ANSI/ISO standard library function. In addition to the
|
||||||
|
`__builtin' version, we will create an ordinary version (e.g,
|
||||||
|
`strchr') as well. If we cannot compute the answer using the
|
||||||
|
builtin function, we will fall back to the standard library
|
||||||
|
version. */
|
||||||
|
#undef DEF_LIB_BUILTIN
|
||||||
|
#define DEF_LIB_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
|
||||||
|
DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
|
||||||
|
true, true, false, ATTRS, true, true)
|
||||||
|
|
||||||
|
/* Like DEF_LIB_BUILTIN, except that the function is not one that is
|
||||||
|
specified by ANSI/ISO C. So, when we're being fully conformant we
|
||||||
|
ignore the version of these builtins that does not begin with
|
||||||
|
__builtin. */
|
||||||
|
#undef DEF_EXT_LIB_BUILTIN
|
||||||
|
#define DEF_EXT_LIB_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
|
||||||
|
DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
|
||||||
|
true, true, true, ATTRS, false, true)
|
||||||
|
|
||||||
|
/* Like DEF_LIB_BUILTIN, except that the function is only a part of
|
||||||
|
the standard in C94 or above. */
|
||||||
|
#undef DEF_C94_BUILTIN
|
||||||
|
#define DEF_C94_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
|
||||||
|
DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
|
||||||
|
true, true, !flag_isoc94, ATTRS, TARGET_C99_FUNCTIONS, true)
|
||||||
|
|
||||||
|
/* Like DEF_LIB_BUILTIN, except that the function is only a part of
|
||||||
|
the standard in C99 or above. */
|
||||||
|
#undef DEF_C99_BUILTIN
|
||||||
|
#define DEF_C99_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
|
||||||
|
DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
|
||||||
|
true, true, !flag_isoc99, ATTRS, TARGET_C99_FUNCTIONS, true)
|
||||||
|
|
||||||
|
/* Builtin that is specified by C99 and C90 reserve the name for future use.
|
||||||
|
We can still recognize the builtin in C90 mode but we can't produce it
|
||||||
|
implicitly. */
|
||||||
|
#undef DEF_C99_C90RES_BUILTIN
|
||||||
|
#define DEF_C99_C90RES_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
|
||||||
|
DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
|
||||||
|
true, true, !flag_isoc99, ATTRS, TARGET_C99_FUNCTIONS, true)
|
||||||
|
|
||||||
|
/* Builtin that C99 reserve the name for future use. We can still recognize
|
||||||
|
the builtin in C99 mode but we can't produce it implicitly. */
|
||||||
|
#undef DEF_EXT_C99RES_BUILTIN
|
||||||
|
#define DEF_EXT_C99RES_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
|
||||||
|
DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
|
||||||
|
true, true, true, ATTRS, false, true)
|
||||||
|
|
||||||
|
/* Allocate the enum and the name for a builtin, but do not actually
|
||||||
|
define it here at all. */
|
||||||
|
#undef DEF_BUILTIN_STUB
|
||||||
|
#define DEF_BUILTIN_STUB(ENUM, NAME) \
|
||||||
|
DEF_BUILTIN (ENUM, NAME, BUILT_IN_NORMAL, BT_LAST, BT_LAST, false, false, \
|
||||||
|
false, ATTR_LAST, false, false)
|
||||||
|
|
||||||
|
/* Builtin used by the implementation of GNU OpenMP. None of these are
|
||||||
|
actually implemented in the compiler; they're all in libgomp. */
|
||||||
|
#undef DEF_GOMP_BUILTIN
|
||||||
|
#define DEF_GOMP_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
|
||||||
|
DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
|
||||||
|
false, true, true, ATTRS, false, \
|
||||||
|
(flag_openmp || flag_tree_parallelize_loops))
|
||||||
|
|
||||||
|
/* Builtin used by the implementation of GNU TM. These
|
||||||
|
functions are mapped to the actual implementation of the STM library. */
|
||||||
|
#undef DEF_TM_BUILTIN
|
||||||
|
#define DEF_TM_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
|
||||||
|
DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
|
||||||
|
true, true, true, ATTRS, false, flag_tm)
|
||||||
|
|
||||||
|
/* Builtin used by the implementation of libsanitizer. These
|
||||||
|
functions are mapped to the actual implementation of the
|
||||||
|
libtsan library. */
|
||||||
|
#undef DEF_SANITIZER_BUILTIN
|
||||||
|
#define DEF_SANITIZER_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
|
||||||
|
DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
|
||||||
|
true, true, true, ATTRS, true, \
|
||||||
|
(flag_asan || flag_tsan))
|
||||||
|
|
||||||
|
/* Define an attribute list for math functions that are normally
|
||||||
|
"impure" because some of them may write into global memory for
|
||||||
|
`errno'. If !flag_errno_math they are instead "const". */
|
||||||
|
#undef ATTR_MATHFN_ERRNO
|
||||||
|
#define ATTR_MATHFN_ERRNO (flag_errno_math ? \
|
||||||
|
ATTR_NOTHROW_LEAF_LIST : ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
|
||||||
|
/* Define an attribute list for math functions that are normally
|
||||||
|
"const" but if flag_rounding_math is set they are instead "pure".
|
||||||
|
This distinction accounts for the fact that some math functions
|
||||||
|
check the rounding mode which is akin to examining global
|
||||||
|
memory. */
|
||||||
|
#undef ATTR_MATHFN_FPROUNDING
|
||||||
|
#define ATTR_MATHFN_FPROUNDING (flag_rounding_math ? \
|
||||||
|
ATTR_PURE_NOTHROW_LEAF_LIST : ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
|
||||||
|
/* Define an attribute list for math functions that are normally
|
||||||
|
"impure" because some of them may write into global memory for
|
||||||
|
`errno'. If !flag_errno_math, we can possibly use "pure" or
|
||||||
|
"const" depending on whether we care about FP rounding. */
|
||||||
|
#undef ATTR_MATHFN_FPROUNDING_ERRNO
|
||||||
|
#define ATTR_MATHFN_FPROUNDING_ERRNO (flag_errno_math ? \
|
||||||
|
ATTR_NOTHROW_LEAF_LIST : ATTR_MATHFN_FPROUNDING)
|
||||||
|
|
||||||
|
/* Define an attribute list for math functions that need to mind FP
|
||||||
|
rounding, but because they store into memory they are never "const"
|
||||||
|
or "pure". Use of this macro is mainly for documentation and
|
||||||
|
maintenance purposes. */
|
||||||
|
#undef ATTR_MATHFN_FPROUNDING_STORE
|
||||||
|
#define ATTR_MATHFN_FPROUNDING_STORE ATTR_NOTHROW_LEAF_LIST
|
||||||
|
|
||||||
|
/* Make sure 0 is not a legitimate builtin. */
|
||||||
|
DEF_BUILTIN_STUB(BUILT_IN_NONE, (const char *)0)
|
||||||
|
|
||||||
|
/* Category: math builtins. */
|
||||||
|
DEF_LIB_BUILTIN (BUILT_IN_ACOS, "acos", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_C90RES_BUILTIN (BUILT_IN_ACOSF, "acosf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_ACOSH, "acosh", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_ACOSHF, "acoshf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_ACOSHL, "acoshl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_C90RES_BUILTIN (BUILT_IN_ACOSL, "acosl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_LIB_BUILTIN (BUILT_IN_ASIN, "asin", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_C90RES_BUILTIN (BUILT_IN_ASINF, "asinf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_ASINH, "asinh", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_ASINHF, "asinhf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_ASINHL, "asinhl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_C99_C90RES_BUILTIN (BUILT_IN_ASINL, "asinl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_LIB_BUILTIN (BUILT_IN_ATAN, "atan", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_LIB_BUILTIN (BUILT_IN_ATAN2, "atan2", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_C90RES_BUILTIN (BUILT_IN_ATAN2F, "atan2f", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_C90RES_BUILTIN (BUILT_IN_ATAN2L, "atan2l", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_C90RES_BUILTIN (BUILT_IN_ATANF, "atanf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_ATANH, "atanh", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_ATANHF, "atanhf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_ATANHL, "atanhl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_C90RES_BUILTIN (BUILT_IN_ATANL, "atanl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_CBRT, "cbrt", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_CBRTF, "cbrtf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_CBRTL, "cbrtl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_LIB_BUILTIN (BUILT_IN_CEIL, "ceil", BT_FN_DOUBLE_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_C99_C90RES_BUILTIN (BUILT_IN_CEILF, "ceilf", BT_FN_FLOAT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_C99_C90RES_BUILTIN (BUILT_IN_CEILL, "ceill", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_COPYSIGN, "copysign", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_COPYSIGNF, "copysignf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_COPYSIGNL, "copysignl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_LIB_BUILTIN (BUILT_IN_COS, "cos", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_C99_C90RES_BUILTIN (BUILT_IN_COSF, "cosf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_LIB_BUILTIN (BUILT_IN_COSH, "cosh", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_C90RES_BUILTIN (BUILT_IN_COSHF, "coshf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_C90RES_BUILTIN (BUILT_IN_COSHL, "coshl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_C90RES_BUILTIN (BUILT_IN_COSL, "cosl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_DREM, "drem", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_DREMF, "dremf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_DREML, "dreml", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_ERF, "erf", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_ERFC, "erfc", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_ERFCF, "erfcf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_ERFCL, "erfcl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_ERFF, "erff", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_ERFL, "erfl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_LIB_BUILTIN (BUILT_IN_EXP, "exp", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_EXP10, "exp10", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_EXP10F, "exp10f", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_EXP10L, "exp10l", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_EXP2, "exp2", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_EXP2F, "exp2f", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_EXP2L, "exp2l", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_C90RES_BUILTIN (BUILT_IN_EXPF, "expf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_C90RES_BUILTIN (BUILT_IN_EXPL, "expl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_EXPM1, "expm1", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_EXPM1F, "expm1f", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_EXPM1L, "expm1l", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_LIB_BUILTIN (BUILT_IN_FABS, "fabs", BT_FN_DOUBLE_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_C99_C90RES_BUILTIN (BUILT_IN_FABSF, "fabsf", BT_FN_FLOAT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_C99_C90RES_BUILTIN (BUILT_IN_FABSL, "fabsl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_FABSD32, "fabsd32", BT_FN_DFLOAT32_DFLOAT32, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_FABSD64, "fabsd64", BT_FN_DFLOAT64_DFLOAT64, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_FABSD128, "fabsd128", BT_FN_DFLOAT128_DFLOAT128, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_FDIM, "fdim", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_FDIMF, "fdimf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_FDIML, "fdiml", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_LIB_BUILTIN (BUILT_IN_FLOOR, "floor", BT_FN_DOUBLE_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_C99_C90RES_BUILTIN (BUILT_IN_FLOORF, "floorf", BT_FN_FLOAT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_C99_C90RES_BUILTIN (BUILT_IN_FLOORL, "floorl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_FMA, "fma", BT_FN_DOUBLE_DOUBLE_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_FMAF, "fmaf", BT_FN_FLOAT_FLOAT_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_FMAL, "fmal", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_FMAX, "fmax", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_FMAXF, "fmaxf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_FMAXL, "fmaxl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_FMIN, "fmin", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_FMINF, "fminf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_FMINL, "fminl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_LIB_BUILTIN (BUILT_IN_FMOD, "fmod", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_C90RES_BUILTIN (BUILT_IN_FMODF, "fmodf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_C90RES_BUILTIN (BUILT_IN_FMODL, "fmodl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_LIB_BUILTIN (BUILT_IN_FREXP, "frexp", BT_FN_DOUBLE_DOUBLE_INTPTR, ATTR_MATHFN_FPROUNDING_STORE)
|
||||||
|
DEF_C99_C90RES_BUILTIN (BUILT_IN_FREXPF, "frexpf", BT_FN_FLOAT_FLOAT_INTPTR, ATTR_MATHFN_FPROUNDING_STORE)
|
||||||
|
DEF_C99_C90RES_BUILTIN (BUILT_IN_FREXPL, "frexpl", BT_FN_LONGDOUBLE_LONGDOUBLE_INTPTR, ATTR_MATHFN_FPROUNDING_STORE)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_GAMMA, "gamma", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_STORE)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_GAMMAF, "gammaf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_STORE)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_GAMMAL, "gammal", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_STORE)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_GAMMA_R, "gamma_r", BT_FN_DOUBLE_DOUBLE_INTPTR, ATTR_MATHFN_FPROUNDING_STORE)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_GAMMAF_R, "gammaf_r", BT_FN_FLOAT_FLOAT_INTPTR, ATTR_MATHFN_FPROUNDING_STORE)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_GAMMAL_R, "gammal_r", BT_FN_LONGDOUBLE_LONGDOUBLE_INTPTR, ATTR_MATHFN_FPROUNDING_STORE)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_HUGE_VAL, "huge_val", BT_FN_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_HUGE_VALF, "huge_valf", BT_FN_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_HUGE_VALL, "huge_vall", BT_FN_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_HYPOT, "hypot", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_HYPOTF, "hypotf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_HYPOTL, "hypotl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_ICEIL, "iceil", BT_FN_INT_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_ICEILF, "iceilf", BT_FN_INT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_ICEILL, "iceill", BT_FN_INT_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_IFLOOR, "ifloor", BT_FN_INT_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_IFLOORF, "ifloorf", BT_FN_INT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_IFLOORL, "ifloorl", BT_FN_INT_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_ILOGB, "ilogb", BT_FN_INT_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_ILOGBF, "ilogbf", BT_FN_INT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_ILOGBL, "ilogbl", BT_FN_INT_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_INF, "inf", BT_FN_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_INFF, "inff", BT_FN_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_INFL, "infl", BT_FN_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_INFD32, "infd32", BT_FN_DFLOAT32, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_INFD64, "infd64", BT_FN_DFLOAT64, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_INFD128, "infd128", BT_FN_DFLOAT128, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_IRINT, "irint", BT_FN_INT_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_IRINTF, "irintf", BT_FN_INT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_IRINTL, "irintl", BT_FN_INT_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_IROUND, "iround", BT_FN_INT_DOUBLE, ATTR_MATHFN_ERRNO)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_IROUNDF, "iroundf", BT_FN_INT_FLOAT, ATTR_MATHFN_ERRNO)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_IROUNDL, "iroundl", BT_FN_INT_LONGDOUBLE, ATTR_MATHFN_ERRNO)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_J0, "j0", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_J0F, "j0f", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_J0L, "j0l", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_J1, "j1", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_J1F, "j1f", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_J1L, "j1l", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_JN, "jn", BT_FN_DOUBLE_INT_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_JNF, "jnf", BT_FN_FLOAT_INT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_JNL, "jnl", BT_FN_LONGDOUBLE_INT_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_LCEIL, "lceil", BT_FN_LONG_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_LCEILF, "lceilf", BT_FN_LONG_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_LCEILL, "lceill", BT_FN_LONG_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_LIB_BUILTIN (BUILT_IN_LDEXP, "ldexp", BT_FN_DOUBLE_DOUBLE_INT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_C90RES_BUILTIN (BUILT_IN_LDEXPF, "ldexpf", BT_FN_FLOAT_FLOAT_INT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_C90RES_BUILTIN (BUILT_IN_LDEXPL, "ldexpl", BT_FN_LONGDOUBLE_LONGDOUBLE_INT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_LFLOOR, "lfloor", BT_FN_LONG_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_LFLOORF, "lfloorf", BT_FN_LONG_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_LFLOORL, "lfloorl", BT_FN_LONG_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_LGAMMA, "lgamma", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_STORE)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_LGAMMAF, "lgammaf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_STORE)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_LGAMMAL, "lgammal", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_STORE)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_LGAMMA_R, "lgamma_r", BT_FN_DOUBLE_DOUBLE_INTPTR, ATTR_MATHFN_FPROUNDING_STORE)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_LGAMMAF_R, "lgammaf_r", BT_FN_FLOAT_FLOAT_INTPTR, ATTR_MATHFN_FPROUNDING_STORE)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_LGAMMAL_R, "lgammal_r", BT_FN_LONGDOUBLE_LONGDOUBLE_INTPTR, ATTR_MATHFN_FPROUNDING_STORE)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_LLCEIL, "llceil", BT_FN_LONGLONG_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_LLCEILF, "llceilf", BT_FN_LONGLONG_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_LLCEILL, "llceill", BT_FN_LONGLONG_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_LLFLOOR, "llfloor", BT_FN_LONGLONG_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_LLFLOORF, "llfloorf", BT_FN_LONGLONG_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_LLFLOORL, "llfloorl", BT_FN_LONGLONG_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_LLRINT, "llrint", BT_FN_LONGLONG_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_LLRINTF, "llrintf", BT_FN_LONGLONG_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_LLRINTL, "llrintl", BT_FN_LONGLONG_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_LLROUND, "llround", BT_FN_LONGLONG_DOUBLE, ATTR_MATHFN_ERRNO)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_LLROUNDF, "llroundf", BT_FN_LONGLONG_FLOAT, ATTR_MATHFN_ERRNO)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_LLROUNDL, "llroundl", BT_FN_LONGLONG_LONGDOUBLE, ATTR_MATHFN_ERRNO)
|
||||||
|
DEF_LIB_BUILTIN (BUILT_IN_LOG, "log", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_LIB_BUILTIN (BUILT_IN_LOG10, "log10", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_C90RES_BUILTIN (BUILT_IN_LOG10F, "log10f", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_C90RES_BUILTIN (BUILT_IN_LOG10L, "log10l", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_LOG1P, "log1p", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_LOG1PF, "log1pf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_LOG1PL, "log1pl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_LOG2, "log2", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_LOG2F, "log2f", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_LOG2L, "log2l", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_LOGB, "logb", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_LOGBF, "logbf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_LOGBL, "logbl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_C90RES_BUILTIN (BUILT_IN_LOGF, "logf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_C90RES_BUILTIN (BUILT_IN_LOGL, "logl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_LRINT, "lrint", BT_FN_LONG_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_LRINTF, "lrintf", BT_FN_LONG_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_LRINTL, "lrintl", BT_FN_LONG_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_LROUND, "lround", BT_FN_LONG_DOUBLE, ATTR_MATHFN_ERRNO)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_LROUNDF, "lroundf", BT_FN_LONG_FLOAT, ATTR_MATHFN_ERRNO)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_LROUNDL, "lroundl", BT_FN_LONG_LONGDOUBLE, ATTR_MATHFN_ERRNO)
|
||||||
|
DEF_LIB_BUILTIN (BUILT_IN_MODF, "modf", BT_FN_DOUBLE_DOUBLE_DOUBLEPTR, ATTR_MATHFN_FPROUNDING_STORE)
|
||||||
|
DEF_C99_C90RES_BUILTIN (BUILT_IN_MODFF, "modff", BT_FN_FLOAT_FLOAT_FLOATPTR, ATTR_MATHFN_FPROUNDING_STORE)
|
||||||
|
DEF_C99_C90RES_BUILTIN (BUILT_IN_MODFL, "modfl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLEPTR, ATTR_MATHFN_FPROUNDING_STORE)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_NAN, "nan", BT_FN_DOUBLE_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_NANF, "nanf", BT_FN_FLOAT_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_NANL, "nanl", BT_FN_LONGDOUBLE_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_NAND32, "nand32", BT_FN_DFLOAT32_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_NAND64, "nand64", BT_FN_DFLOAT64_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_NAND128, "nand128", BT_FN_DFLOAT128_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_NANS, "nans", BT_FN_DOUBLE_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_NANSF, "nansf", BT_FN_FLOAT_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_NANSL, "nansl", BT_FN_LONGDOUBLE_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_NEARBYINT, "nearbyint", BT_FN_DOUBLE_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_NEARBYINTF, "nearbyintf", BT_FN_FLOAT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_NEARBYINTL, "nearbyintl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_NEXTAFTER, "nextafter", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_NEXTAFTERF, "nextafterf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_NEXTAFTERL, "nextafterl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_NEXTTOWARD, "nexttoward", BT_FN_DOUBLE_DOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_NEXTTOWARDF, "nexttowardf", BT_FN_FLOAT_FLOAT_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_NEXTTOWARDL, "nexttowardl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_LIB_BUILTIN (BUILT_IN_POW, "pow", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_POW10, "pow10", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_POW10F, "pow10f", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_POW10L, "pow10l", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_C90RES_BUILTIN (BUILT_IN_POWF, "powf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_POWI, "powi", BT_FN_DOUBLE_DOUBLE_INT, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_POWIF, "powif", BT_FN_FLOAT_FLOAT_INT, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_POWIL, "powil", BT_FN_LONGDOUBLE_LONGDOUBLE_INT, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_C99_C90RES_BUILTIN (BUILT_IN_POWL, "powl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_REMAINDER, "remainder", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_REMAINDERF, "remainderf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_REMAINDERL, "remainderl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_REMQUO, "remquo", BT_FN_DOUBLE_DOUBLE_DOUBLE_INTPTR, ATTR_MATHFN_FPROUNDING_STORE)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_REMQUOF, "remquof", BT_FN_FLOAT_FLOAT_FLOAT_INTPTR, ATTR_MATHFN_FPROUNDING_STORE)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_REMQUOL, "remquol", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE_INTPTR, ATTR_MATHFN_FPROUNDING_STORE)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_RINT, "rint", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_RINTF, "rintf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_RINTL, "rintl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_ROUND, "round", BT_FN_DOUBLE_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_ROUNDF, "roundf", BT_FN_FLOAT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_ROUNDL, "roundl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_SCALB, "scalb", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_SCALBF, "scalbf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_SCALBL, "scalbl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_SCALBLN, "scalbln", BT_FN_DOUBLE_DOUBLE_LONG, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_SCALBLNF, "scalblnf", BT_FN_FLOAT_FLOAT_LONG, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_SCALBLNL, "scalblnl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONG, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_SCALBN, "scalbn", BT_FN_DOUBLE_DOUBLE_INT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_SCALBNF, "scalbnf", BT_FN_FLOAT_FLOAT_INT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_SCALBNL, "scalbnl", BT_FN_LONGDOUBLE_LONGDOUBLE_INT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_SIGNBIT, "signbit", BT_FN_INT_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_SIGNBITF, "signbitf", BT_FN_INT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_SIGNBITL, "signbitl", BT_FN_INT_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_SIGNBITD32, "signbitd32", BT_FN_INT_DFLOAT32, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_SIGNBITD64, "signbitd64", BT_FN_INT_DFLOAT64, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_SIGNBITD128, "signbitd128", BT_FN_INT_DFLOAT128, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_SIGNIFICAND, "significand", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_SIGNIFICANDF, "significandf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_SIGNIFICANDL, "significandl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_LIB_BUILTIN (BUILT_IN_SIN, "sin", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_SINCOS, "sincos", BT_FN_VOID_DOUBLE_DOUBLEPTR_DOUBLEPTR, ATTR_MATHFN_FPROUNDING_STORE)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_SINCOSF, "sincosf", BT_FN_VOID_FLOAT_FLOATPTR_FLOATPTR, ATTR_MATHFN_FPROUNDING_STORE)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_SINCOSL, "sincosl", BT_FN_VOID_LONGDOUBLE_LONGDOUBLEPTR_LONGDOUBLEPTR, ATTR_MATHFN_FPROUNDING_STORE)
|
||||||
|
DEF_C99_C90RES_BUILTIN (BUILT_IN_SINF, "sinf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_LIB_BUILTIN (BUILT_IN_SINH, "sinh", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_C90RES_BUILTIN (BUILT_IN_SINHF, "sinhf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_C90RES_BUILTIN (BUILT_IN_SINHL, "sinhl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_C90RES_BUILTIN (BUILT_IN_SINL, "sinl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_LIB_BUILTIN (BUILT_IN_SQRT, "sqrt", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_C90RES_BUILTIN (BUILT_IN_SQRTF, "sqrtf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_C90RES_BUILTIN (BUILT_IN_SQRTL, "sqrtl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_LIB_BUILTIN (BUILT_IN_TAN, "tan", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_C99_C90RES_BUILTIN (BUILT_IN_TANF, "tanf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_LIB_BUILTIN (BUILT_IN_TANH, "tanh", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_C99_C90RES_BUILTIN (BUILT_IN_TANHF, "tanhf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_C99_C90RES_BUILTIN (BUILT_IN_TANHL, "tanhl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_C99_C90RES_BUILTIN (BUILT_IN_TANL, "tanl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_TGAMMA, "tgamma", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_TGAMMAF, "tgammaf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_TGAMMAL, "tgammal", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_TRUNC, "trunc", BT_FN_DOUBLE_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_TRUNCF, "truncf", BT_FN_FLOAT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_TRUNCL, "truncl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_Y0, "y0", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_Y0F, "y0f", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_Y0L, "y0l", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_Y1, "y1", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_Y1F, "y1f", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_Y1L, "y1l", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_YN, "yn", BT_FN_DOUBLE_INT_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_YNF, "ynf", BT_FN_FLOAT_INT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_YNL, "ynl", BT_FN_LONGDOUBLE_INT_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||||
|
|
||||||
|
/* Category: _Complex math builtins. */
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_CABS, "cabs", BT_FN_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_CABSF, "cabsf", BT_FN_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_CABSL, "cabsl", BT_FN_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_CACOS, "cacos", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_CACOSF, "cacosf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_CACOSH, "cacosh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_CACOSHF, "cacoshf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_CACOSHL, "cacoshl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_CACOSL, "cacosl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_CARG, "carg", BT_FN_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_CARGF, "cargf", BT_FN_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_CARGL, "cargl", BT_FN_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_CASIN, "casin", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_CASINF, "casinf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_CASINH, "casinh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_CASINHF, "casinhf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_CASINHL, "casinhl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_CASINL, "casinl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_CATAN, "catan", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_CATANF, "catanf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_CATANH, "catanh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_CATANHF, "catanhf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_CATANHL, "catanhl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_CATANL, "catanl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_CCOS, "ccos", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_CCOSF, "ccosf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_CCOSH, "ccosh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_CCOSHF, "ccoshf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_CCOSHL, "ccoshl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_CCOSL, "ccosl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_CEXP, "cexp", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_CEXPF, "cexpf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_CEXPL, "cexpl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_CEXPI, "cexpi", BT_FN_COMPLEX_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_CEXPIF, "cexpif", BT_FN_COMPLEX_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_CEXPIL, "cexpil", BT_FN_COMPLEX_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_CIMAG, "cimag", BT_FN_DOUBLE_COMPLEX_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_CIMAGF, "cimagf", BT_FN_FLOAT_COMPLEX_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_CIMAGL, "cimagl", BT_FN_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_CLOG, "clog", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_CLOGF, "clogf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_CLOGL, "clogl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_EXT_C99RES_BUILTIN (BUILT_IN_CLOG10, "clog10", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_EXT_C99RES_BUILTIN (BUILT_IN_CLOG10F, "clog10f", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_EXT_C99RES_BUILTIN (BUILT_IN_CLOG10L, "clog10l", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_CONJ, "conj", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_CONJF, "conjf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_CONJL, "conjl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_CPOW, "cpow", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_CPOWF, "cpowf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_CPOWL, "cpowl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_CPROJ, "cproj", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_CPROJF, "cprojf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_CPROJL, "cprojl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_CREAL, "creal", BT_FN_DOUBLE_COMPLEX_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_CREALF, "crealf", BT_FN_FLOAT_COMPLEX_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_CREALL, "creall", BT_FN_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_CSIN, "csin", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_CSINF, "csinf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_CSINH, "csinh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_CSINHF, "csinhf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_CSINHL, "csinhl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_CSINL, "csinl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_CSQRT, "csqrt", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_CSQRTF, "csqrtf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_CSQRTL, "csqrtl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_CTAN, "ctan", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_CTANF, "ctanf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_CTANH, "ctanh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_CTANHF, "ctanhf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_CTANHL, "ctanhl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_CTANL, "ctanl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||||
|
|
||||||
|
/* Category: string/memory builtins. */
|
||||||
|
/* bcmp, bcopy and bzero have traditionally accepted NULL pointers
|
||||||
|
when the length parameter is zero, so don't apply attribute "nonnull". */
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_BCMP, "bcmp", BT_FN_INT_CONST_PTR_CONST_PTR_SIZE, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_BCOPY, "bcopy", BT_FN_VOID_CONST_PTR_PTR_SIZE, ATTR_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_BZERO, "bzero", BT_FN_VOID_PTR_SIZE, ATTR_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_INDEX, "index", BT_FN_STRING_CONST_STRING_INT, ATTR_PURE_NOTHROW_NONNULL_LEAF)
|
||||||
|
DEF_LIB_BUILTIN (BUILT_IN_MEMCHR, "memchr", BT_FN_PTR_CONST_PTR_INT_SIZE, ATTR_PURE_NOTHROW_NONNULL_LEAF)
|
||||||
|
DEF_LIB_BUILTIN (BUILT_IN_MEMCMP, "memcmp", BT_FN_INT_CONST_PTR_CONST_PTR_SIZE, ATTR_PURE_NOTHROW_NONNULL_LEAF)
|
||||||
|
DEF_LIB_BUILTIN (BUILT_IN_MEMCPY, "memcpy", BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF)
|
||||||
|
DEF_LIB_BUILTIN (BUILT_IN_MEMMOVE, "memmove", BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_MEMPCPY, "mempcpy", BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_NOTHROW_NONNULL_LEAF)
|
||||||
|
DEF_LIB_BUILTIN (BUILT_IN_MEMSET, "memset", BT_FN_PTR_PTR_INT_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_RINDEX, "rindex", BT_FN_STRING_CONST_STRING_INT, ATTR_PURE_NOTHROW_NONNULL_LEAF)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_STPCPY, "stpcpy", BT_FN_STRING_STRING_CONST_STRING, ATTR_NOTHROW_NONNULL_LEAF)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_STPNCPY, "stpncpy", BT_FN_STRING_STRING_CONST_STRING_SIZE, ATTR_NOTHROW_NONNULL_LEAF)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_STRCASECMP, "strcasecmp", BT_FN_INT_CONST_STRING_CONST_STRING, ATTR_PURE_NOTHROW_NONNULL_LEAF)
|
||||||
|
DEF_LIB_BUILTIN (BUILT_IN_STRCAT, "strcat", BT_FN_STRING_STRING_CONST_STRING, ATTR_NOTHROW_NONNULL_LEAF)
|
||||||
|
DEF_LIB_BUILTIN (BUILT_IN_STRCHR, "strchr", BT_FN_STRING_CONST_STRING_INT, ATTR_PURE_NOTHROW_NONNULL_LEAF)
|
||||||
|
DEF_LIB_BUILTIN (BUILT_IN_STRCMP, "strcmp", BT_FN_INT_CONST_STRING_CONST_STRING, ATTR_PURE_NOTHROW_NONNULL_LEAF)
|
||||||
|
DEF_LIB_BUILTIN (BUILT_IN_STRCPY, "strcpy", BT_FN_STRING_STRING_CONST_STRING, ATTR_RET1_NOTHROW_NONNULL_LEAF)
|
||||||
|
DEF_LIB_BUILTIN (BUILT_IN_STRCSPN, "strcspn", BT_FN_SIZE_CONST_STRING_CONST_STRING, ATTR_PURE_NOTHROW_NONNULL_LEAF)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_STRDUP, "strdup", BT_FN_STRING_CONST_STRING, ATTR_MALLOC_NOTHROW_NONNULL_LEAF)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_STRNDUP, "strndup", BT_FN_STRING_CONST_STRING_SIZE, ATTR_MALLOC_NOTHROW_NONNULL_LEAF)
|
||||||
|
DEF_LIB_BUILTIN (BUILT_IN_STRLEN, "strlen", BT_FN_SIZE_CONST_STRING, ATTR_PURE_NOTHROW_NONNULL_LEAF)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_STRNCASECMP, "strncasecmp", BT_FN_INT_CONST_STRING_CONST_STRING_SIZE, ATTR_PURE_NOTHROW_NONNULL_LEAF)
|
||||||
|
DEF_LIB_BUILTIN (BUILT_IN_STRNCAT, "strncat", BT_FN_STRING_STRING_CONST_STRING_SIZE, ATTR_NOTHROW_NONNULL_LEAF)
|
||||||
|
DEF_LIB_BUILTIN (BUILT_IN_STRNCMP, "strncmp", BT_FN_INT_CONST_STRING_CONST_STRING_SIZE, ATTR_PURE_NOTHROW_NONNULL_LEAF)
|
||||||
|
DEF_LIB_BUILTIN (BUILT_IN_STRNCPY, "strncpy", BT_FN_STRING_STRING_CONST_STRING_SIZE, ATTR_NOTHROW_NONNULL_LEAF)
|
||||||
|
DEF_LIB_BUILTIN (BUILT_IN_STRPBRK, "strpbrk", BT_FN_STRING_CONST_STRING_CONST_STRING, ATTR_PURE_NOTHROW_NONNULL_LEAF)
|
||||||
|
DEF_LIB_BUILTIN (BUILT_IN_STRRCHR, "strrchr", BT_FN_STRING_CONST_STRING_INT, ATTR_PURE_NOTHROW_NONNULL_LEAF)
|
||||||
|
DEF_LIB_BUILTIN (BUILT_IN_STRSPN, "strspn", BT_FN_SIZE_CONST_STRING_CONST_STRING, ATTR_PURE_NOTHROW_NONNULL_LEAF)
|
||||||
|
DEF_LIB_BUILTIN (BUILT_IN_STRSTR, "strstr", BT_FN_STRING_CONST_STRING_CONST_STRING, ATTR_PURE_NOTHROW_NONNULL_LEAF)
|
||||||
|
|
||||||
|
/* Category: stdio builtins. */
|
||||||
|
DEF_LIB_BUILTIN (BUILT_IN_FPRINTF, "fprintf", BT_FN_INT_FILEPTR_CONST_STRING_VAR, ATTR_FORMAT_PRINTF_2_3)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_FPRINTF_UNLOCKED, "fprintf_unlocked", BT_FN_INT_FILEPTR_CONST_STRING_VAR, ATTR_FORMAT_PRINTF_2_3)
|
||||||
|
DEF_LIB_BUILTIN (BUILT_IN_PUTC, "putc", BT_FN_INT_INT_FILEPTR, ATTR_NONNULL_LIST)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_PUTC_UNLOCKED, "putc_unlocked", BT_FN_INT_INT_FILEPTR, ATTR_NONNULL_LIST)
|
||||||
|
DEF_LIB_BUILTIN (BUILT_IN_FPUTC, "fputc", BT_FN_INT_INT_FILEPTR, ATTR_NONNULL_LIST)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_FPUTC_UNLOCKED, "fputc_unlocked", BT_FN_INT_INT_FILEPTR, ATTR_NONNULL_LIST)
|
||||||
|
DEF_LIB_BUILTIN (BUILT_IN_FPUTS, "fputs", BT_FN_INT_CONST_STRING_FILEPTR, ATTR_NONNULL_LIST)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_FPUTS_UNLOCKED, "fputs_unlocked", BT_FN_INT_CONST_STRING_FILEPTR, ATTR_NONNULL_LIST)
|
||||||
|
DEF_LIB_BUILTIN (BUILT_IN_FSCANF, "fscanf", BT_FN_INT_FILEPTR_CONST_STRING_VAR, ATTR_FORMAT_SCANF_2_3)
|
||||||
|
DEF_LIB_BUILTIN (BUILT_IN_FWRITE, "fwrite", BT_FN_SIZE_CONST_PTR_SIZE_SIZE_FILEPTR, ATTR_NONNULL_LIST)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_FWRITE_UNLOCKED, "fwrite_unlocked", BT_FN_SIZE_CONST_PTR_SIZE_SIZE_FILEPTR, ATTR_NONNULL_LIST)
|
||||||
|
DEF_LIB_BUILTIN (BUILT_IN_PRINTF, "printf", BT_FN_INT_CONST_STRING_VAR, ATTR_FORMAT_PRINTF_1_2)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_PRINTF_UNLOCKED, "printf_unlocked", BT_FN_INT_CONST_STRING_VAR, ATTR_FORMAT_PRINTF_1_2)
|
||||||
|
DEF_LIB_BUILTIN (BUILT_IN_PUTCHAR, "putchar", BT_FN_INT_INT, ATTR_NULL)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_PUTCHAR_UNLOCKED, "putchar_unlocked", BT_FN_INT_INT, ATTR_NULL)
|
||||||
|
DEF_LIB_BUILTIN (BUILT_IN_PUTS, "puts", BT_FN_INT_CONST_STRING, ATTR_NONNULL_LIST)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_PUTS_UNLOCKED, "puts_unlocked", BT_FN_INT_CONST_STRING, ATTR_NONNULL_LIST)
|
||||||
|
DEF_LIB_BUILTIN (BUILT_IN_SCANF, "scanf", BT_FN_INT_CONST_STRING_VAR, ATTR_FORMAT_SCANF_1_2)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_SNPRINTF, "snprintf", BT_FN_INT_STRING_SIZE_CONST_STRING_VAR, ATTR_FORMAT_PRINTF_NOTHROW_3_4)
|
||||||
|
DEF_LIB_BUILTIN (BUILT_IN_SPRINTF, "sprintf", BT_FN_INT_STRING_CONST_STRING_VAR, ATTR_FORMAT_PRINTF_NOTHROW_2_3)
|
||||||
|
DEF_LIB_BUILTIN (BUILT_IN_SSCANF, "sscanf", BT_FN_INT_CONST_STRING_CONST_STRING_VAR, ATTR_FORMAT_SCANF_NOTHROW_2_3)
|
||||||
|
DEF_LIB_BUILTIN (BUILT_IN_VFPRINTF, "vfprintf", BT_FN_INT_FILEPTR_CONST_STRING_VALIST_ARG, ATTR_FORMAT_PRINTF_2_0)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_VFSCANF, "vfscanf", BT_FN_INT_FILEPTR_CONST_STRING_VALIST_ARG, ATTR_FORMAT_SCANF_2_0)
|
||||||
|
DEF_LIB_BUILTIN (BUILT_IN_VPRINTF, "vprintf", BT_FN_INT_CONST_STRING_VALIST_ARG, ATTR_FORMAT_PRINTF_1_0)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_VSCANF, "vscanf", BT_FN_INT_CONST_STRING_VALIST_ARG, ATTR_FORMAT_SCANF_1_0)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_VSNPRINTF, "vsnprintf", BT_FN_INT_STRING_SIZE_CONST_STRING_VALIST_ARG, ATTR_FORMAT_PRINTF_NOTHROW_3_0)
|
||||||
|
DEF_LIB_BUILTIN (BUILT_IN_VSPRINTF, "vsprintf", BT_FN_INT_STRING_CONST_STRING_VALIST_ARG, ATTR_FORMAT_PRINTF_NOTHROW_2_0)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_VSSCANF, "vsscanf", BT_FN_INT_CONST_STRING_CONST_STRING_VALIST_ARG, ATTR_FORMAT_SCANF_NOTHROW_2_0)
|
||||||
|
|
||||||
|
/* Category: ctype builtins. */
|
||||||
|
DEF_LIB_BUILTIN (BUILT_IN_ISALNUM, "isalnum", BT_FN_INT_INT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_LIB_BUILTIN (BUILT_IN_ISALPHA, "isalpha", BT_FN_INT_INT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_ISASCII, "isascii", BT_FN_INT_INT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_ISBLANK, "isblank", BT_FN_INT_INT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_LIB_BUILTIN (BUILT_IN_ISCNTRL, "iscntrl", BT_FN_INT_INT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_LIB_BUILTIN (BUILT_IN_ISDIGIT, "isdigit", BT_FN_INT_INT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_LIB_BUILTIN (BUILT_IN_ISGRAPH, "isgraph", BT_FN_INT_INT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_LIB_BUILTIN (BUILT_IN_ISLOWER, "islower", BT_FN_INT_INT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_LIB_BUILTIN (BUILT_IN_ISPRINT, "isprint", BT_FN_INT_INT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_LIB_BUILTIN (BUILT_IN_ISPUNCT, "ispunct", BT_FN_INT_INT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_LIB_BUILTIN (BUILT_IN_ISSPACE, "isspace", BT_FN_INT_INT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_LIB_BUILTIN (BUILT_IN_ISUPPER, "isupper", BT_FN_INT_INT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_LIB_BUILTIN (BUILT_IN_ISXDIGIT, "isxdigit", BT_FN_INT_INT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_TOASCII, "toascii", BT_FN_INT_INT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_LIB_BUILTIN (BUILT_IN_TOLOWER, "tolower", BT_FN_INT_INT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_LIB_BUILTIN (BUILT_IN_TOUPPER, "toupper", BT_FN_INT_INT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||||
|
|
||||||
|
/* Category: wctype builtins. */
|
||||||
|
DEF_C94_BUILTIN (BUILT_IN_ISWALNUM, "iswalnum", BT_FN_INT_WINT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_C94_BUILTIN (BUILT_IN_ISWALPHA, "iswalpha", BT_FN_INT_WINT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_ISWBLANK, "iswblank", BT_FN_INT_WINT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_C94_BUILTIN (BUILT_IN_ISWCNTRL, "iswcntrl", BT_FN_INT_WINT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_C94_BUILTIN (BUILT_IN_ISWDIGIT, "iswdigit", BT_FN_INT_WINT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_C94_BUILTIN (BUILT_IN_ISWGRAPH, "iswgraph", BT_FN_INT_WINT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_C94_BUILTIN (BUILT_IN_ISWLOWER, "iswlower", BT_FN_INT_WINT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_C94_BUILTIN (BUILT_IN_ISWPRINT, "iswprint", BT_FN_INT_WINT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_C94_BUILTIN (BUILT_IN_ISWPUNCT, "iswpunct", BT_FN_INT_WINT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_C94_BUILTIN (BUILT_IN_ISWSPACE, "iswspace", BT_FN_INT_WINT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_C94_BUILTIN (BUILT_IN_ISWUPPER, "iswupper", BT_FN_INT_WINT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_C94_BUILTIN (BUILT_IN_ISWXDIGIT, "iswxdigit", BT_FN_INT_WINT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_C94_BUILTIN (BUILT_IN_TOWLOWER, "towlower", BT_FN_WINT_WINT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_C94_BUILTIN (BUILT_IN_TOWUPPER, "towupper", BT_FN_WINT_WINT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||||
|
|
||||||
|
/* Category: miscellaneous builtins. */
|
||||||
|
DEF_LIB_BUILTIN (BUILT_IN_ABORT, "abort", BT_FN_VOID, ATTR_NORETURN_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_LIB_BUILTIN (BUILT_IN_ABS, "abs", BT_FN_INT_INT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_AGGREGATE_INCOMING_ADDRESS, "aggregate_incoming_address", BT_FN_PTR_VAR, ATTR_LEAF_LIST)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_ALLOCA, "alloca", BT_FN_PTR_SIZE, ATTR_MALLOC_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_APPLY, "apply", BT_FN_PTR_PTR_FN_VOID_VAR_PTR_SIZE, ATTR_NULL)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_APPLY_ARGS, "apply_args", BT_FN_PTR_VAR, ATTR_LEAF_LIST)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_BSWAP16, "bswap16", BT_FN_UINT16_UINT16, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_BSWAP32, "bswap32", BT_FN_UINT32_UINT32, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_BSWAP64, "bswap64", BT_FN_UINT64_UINT64, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_CLEAR_CACHE, "__clear_cache", BT_FN_VOID_PTR_PTR, ATTR_NOTHROW_LEAF_LIST)
|
||||||
|
/* [trans-mem]: Adjust BUILT_IN_TM_CALLOC if BUILT_IN_CALLOC is changed. */
|
||||||
|
DEF_LIB_BUILTIN (BUILT_IN_CALLOC, "calloc", BT_FN_PTR_SIZE_SIZE, ATTR_MALLOC_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_CLASSIFY_TYPE, "classify_type", BT_FN_INT_VAR, ATTR_LEAF_LIST)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_CLZ, "clz", BT_FN_INT_UINT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_CLZIMAX, "clzimax", BT_FN_INT_UINTMAX, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_CLZL, "clzl", BT_FN_INT_ULONG, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_CLZLL, "clzll", BT_FN_INT_ULONGLONG, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_CONSTANT_P, "constant_p", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_CTZ, "ctz", BT_FN_INT_UINT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_CTZIMAX, "ctzimax", BT_FN_INT_UINTMAX, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_CTZL, "ctzl", BT_FN_INT_ULONG, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_CTZLL, "ctzll", BT_FN_INT_ULONGLONG, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_CLRSB, "clrsb", BT_FN_INT_INT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_CLRSBIMAX, "clrsbimax", BT_FN_INT_INTMAX, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_CLRSBL, "clrsbl", BT_FN_INT_LONG, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_CLRSBLL, "clrsbll", BT_FN_INT_LONGLONG, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_DCGETTEXT, "dcgettext", BT_FN_STRING_CONST_STRING_CONST_STRING_INT, ATTR_FORMAT_ARG_2)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_DGETTEXT, "dgettext", BT_FN_STRING_CONST_STRING_CONST_STRING, ATTR_FORMAT_ARG_2)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_DWARF_CFA, "dwarf_cfa", BT_FN_PTR, ATTR_NULL)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_DWARF_SP_COLUMN, "dwarf_sp_column", BT_FN_UINT, ATTR_NULL)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_EH_RETURN, "eh_return", BT_FN_VOID_PTRMODE_PTR, ATTR_NORETURN_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_EH_RETURN_DATA_REGNO, "eh_return_data_regno", BT_FN_INT_INT, ATTR_LEAF_LIST)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_EXECL, "execl", BT_FN_INT_CONST_STRING_CONST_STRING_VAR, ATTR_SENTINEL_NOTHROW_LIST)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_EXECLP, "execlp", BT_FN_INT_CONST_STRING_CONST_STRING_VAR, ATTR_SENTINEL_NOTHROW_LIST)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_EXECLE, "execle", BT_FN_INT_CONST_STRING_CONST_STRING_VAR, ATTR_NOTHROW_SENTINEL_1)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_EXECV, "execv", BT_FN_INT_CONST_STRING_PTR_CONST_STRING, ATTR_NOTHROW_LIST)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_EXECVP, "execvp", BT_FN_INT_CONST_STRING_PTR_CONST_STRING, ATTR_NOTHROW_LIST)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_EXECVE, "execve", BT_FN_INT_CONST_STRING_PTR_CONST_STRING_PTR_CONST_STRING, ATTR_NOTHROW_LIST)
|
||||||
|
DEF_LIB_BUILTIN (BUILT_IN_EXIT, "exit", BT_FN_VOID_INT, ATTR_NORETURN_NOTHROW_LIST)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_EXPECT, "expect", BT_FN_LONG_LONG_LONG, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_ASSUME_ALIGNED, "assume_aligned", BT_FN_PTR_CONST_PTR_SIZE_VAR, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_EXTEND_POINTER, "extend_pointer", BT_FN_UNWINDWORD_PTR, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_EXTRACT_RETURN_ADDR, "extract_return_addr", BT_FN_PTR_PTR, ATTR_LEAF_LIST)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_FFS, "ffs", BT_FN_INT_INT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_FFSIMAX, "ffsimax", BT_FN_INT_INTMAX, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_FFSL, "ffsl", BT_FN_INT_LONG, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_FFSLL, "ffsll", BT_FN_INT_LONGLONG, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_FORK, "fork", BT_FN_PID, ATTR_NOTHROW_LIST)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_FRAME_ADDRESS, "frame_address", BT_FN_PTR_UINT, ATTR_NULL)
|
||||||
|
/* [trans-mem]: Adjust BUILT_IN_TM_FREE if BUILT_IN_FREE is changed. */
|
||||||
|
DEF_LIB_BUILTIN (BUILT_IN_FREE, "free", BT_FN_VOID_PTR, ATTR_NOTHROW_LIST)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_FROB_RETURN_ADDR, "frob_return_addr", BT_FN_PTR_PTR, ATTR_NULL)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_GETTEXT, "gettext", BT_FN_STRING_CONST_STRING, ATTR_FORMAT_ARG_1)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_IMAXABS, "imaxabs", BT_FN_INTMAX_INTMAX, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_INIT_DWARF_REG_SIZES, "init_dwarf_reg_size_table", BT_FN_VOID_PTR, ATTR_NULL)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_FINITE, "finite", BT_FN_INT_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_FINITEF, "finitef", BT_FN_INT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_FINITEL, "finitel", BT_FN_INT_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_FINITED32, "finited32", BT_FN_INT_DFLOAT32, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_FINITED64, "finited64", BT_FN_INT_DFLOAT64, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_FINITED128, "finited128", BT_FN_INT_DFLOAT128, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_FPCLASSIFY, "fpclassify", BT_FN_INT_INT_INT_INT_INT_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC_LEAF)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_ISFINITE, "isfinite", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC_LEAF)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_ISINF_SIGN, "isinf_sign", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC_LEAF)
|
||||||
|
DEF_C99_C90RES_BUILTIN (BUILT_IN_ISINF, "isinf", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_ISINFF, "isinff", BT_FN_INT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_ISINFL, "isinfl", BT_FN_INT_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_ISINFD32, "isinfd32", BT_FN_INT_DFLOAT32, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_ISINFD64, "isinfd64", BT_FN_INT_DFLOAT64, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_ISINFD128, "isinfd128", BT_FN_INT_DFLOAT128, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_C99_C90RES_BUILTIN (BUILT_IN_ISNAN, "isnan", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC_LEAF)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_ISNANF, "isnanf", BT_FN_INT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_ISNANL, "isnanl", BT_FN_INT_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_ISNAND32, "isnand32", BT_FN_INT_DFLOAT32, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_ISNAND64, "isnand64", BT_FN_INT_DFLOAT64, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_ISNAND128, "isnand128", BT_FN_INT_DFLOAT128, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_ISNORMAL, "isnormal", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC_LEAF)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_ISGREATER, "isgreater", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC_LEAF)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_ISGREATEREQUAL, "isgreaterequal", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC_LEAF)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_ISLESS, "isless", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC_LEAF)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_ISLESSEQUAL, "islessequal", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC_LEAF)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_ISLESSGREATER, "islessgreater", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC_LEAF)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_ISUNORDERED, "isunordered", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC_LEAF)
|
||||||
|
DEF_LIB_BUILTIN (BUILT_IN_LABS, "labs", BT_FN_LONG_LONG, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN_LLABS, "llabs", BT_FN_LONGLONG_LONGLONG, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_LONGJMP, "longjmp", BT_FN_VOID_PTR_INT, ATTR_NORETURN_NOTHROW_LEAF_LIST)
|
||||||
|
/* [trans-mem]: Adjust BUILT_IN_TM_MALLOC if BUILT_IN_MALLOC is changed. */
|
||||||
|
DEF_LIB_BUILTIN (BUILT_IN_MALLOC, "malloc", BT_FN_PTR_SIZE, ATTR_MALLOC_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_NEXT_ARG, "next_arg", BT_FN_PTR_VAR, ATTR_LEAF_LIST)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_PARITY, "parity", BT_FN_INT_UINT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_PARITYIMAX, "parityimax", BT_FN_INT_UINTMAX, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_PARITYL, "parityl", BT_FN_INT_ULONG, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_PARITYLL, "parityll", BT_FN_INT_ULONGLONG, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_POPCOUNT, "popcount", BT_FN_INT_UINT, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_POPCOUNTIMAX, "popcountimax", BT_FN_INT_UINTMAX, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_POPCOUNTL, "popcountl", BT_FN_INT_ULONG, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_POPCOUNTLL, "popcountll", BT_FN_INT_ULONGLONG, ATTR_CONST_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_PREFETCH, "prefetch", BT_FN_VOID_CONST_PTR_VAR, ATTR_NOVOPS_LEAF_LIST)
|
||||||
|
DEF_LIB_BUILTIN (BUILT_IN_REALLOC, "realloc", BT_FN_PTR_PTR_SIZE, ATTR_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_RETURN, "return", BT_FN_VOID_PTR, ATTR_NORETURN_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_RETURN_ADDRESS, "return_address", BT_FN_PTR_UINT, ATTR_LEAF_LIST)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_SAVEREGS, "saveregs", BT_FN_PTR_VAR, ATTR_NULL)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_SETJMP, "setjmp", BT_FN_INT_PTR, ATTR_NULL)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_STRFMON, "strfmon", BT_FN_SSIZE_STRING_SIZE_CONST_STRING_VAR, ATTR_FORMAT_STRFMON_NOTHROW_3_4)
|
||||||
|
DEF_LIB_BUILTIN (BUILT_IN_STRFTIME, "strftime", BT_FN_SIZE_STRING_SIZE_CONST_STRING_CONST_PTR, ATTR_FORMAT_STRFTIME_NOTHROW_3_0)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_TRAP, "trap", BT_FN_VOID, ATTR_NORETURN_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_UNREACHABLE, "unreachable", BT_FN_VOID, ATTR_CONST_NORETURN_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_UNWIND_INIT, "unwind_init", BT_FN_VOID, ATTR_NULL)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_UPDATE_SETJMP_BUF, "update_setjmp_buf", BT_FN_VOID_PTR_INT, ATTR_NULL)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_VA_COPY, "va_copy", BT_FN_VOID_VALIST_REF_VALIST_ARG, ATTR_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_VA_END, "va_end", BT_FN_VOID_VALIST_REF, ATTR_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_VA_START, "va_start", BT_FN_VOID_VALIST_REF_VAR, ATTR_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_VA_ARG_PACK, "va_arg_pack", BT_FN_INT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_VA_ARG_PACK_LEN, "va_arg_pack_len", BT_FN_INT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN__EXIT, "_exit", BT_FN_VOID_INT, ATTR_NORETURN_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_C99_BUILTIN (BUILT_IN__EXIT2, "_Exit", BT_FN_VOID_INT, ATTR_NORETURN_NOTHROW_LEAF_LIST)
|
||||||
|
|
||||||
|
/* Implementing nested functions. */
|
||||||
|
DEF_BUILTIN_STUB (BUILT_IN_INIT_TRAMPOLINE, "__builtin_init_trampoline")
|
||||||
|
DEF_BUILTIN_STUB (BUILT_IN_INIT_HEAP_TRAMPOLINE, "__builtin_init_heap_trampoline")
|
||||||
|
DEF_BUILTIN_STUB (BUILT_IN_ADJUST_TRAMPOLINE, "__builtin_adjust_trampoline")
|
||||||
|
DEF_BUILTIN_STUB (BUILT_IN_NONLOCAL_GOTO, "__builtin_nonlocal_goto")
|
||||||
|
|
||||||
|
/* Implementing __builtin_setjmp. */
|
||||||
|
DEF_BUILTIN_STUB (BUILT_IN_SETJMP_SETUP, "__builtin_setjmp_setup")
|
||||||
|
DEF_BUILTIN_STUB (BUILT_IN_SETJMP_DISPATCHER, "__builtin_setjmp_dispatcher")
|
||||||
|
DEF_BUILTIN_STUB (BUILT_IN_SETJMP_RECEIVER, "__builtin_setjmp_receiver")
|
||||||
|
|
||||||
|
/* Implementing variable sized local variables. */
|
||||||
|
DEF_BUILTIN_STUB (BUILT_IN_STACK_SAVE, "__builtin_stack_save")
|
||||||
|
DEF_BUILTIN_STUB (BUILT_IN_STACK_RESTORE, "__builtin_stack_restore")
|
||||||
|
DEF_BUILTIN_STUB (BUILT_IN_ALLOCA_WITH_ALIGN, "__builtin_alloca_with_align")
|
||||||
|
|
||||||
|
/* Object size checking builtins. */
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_OBJECT_SIZE, "object_size", BT_FN_SIZE_CONST_PTR_INT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_MEMCPY_CHK, "__memcpy_chk", BT_FN_PTR_PTR_CONST_PTR_SIZE_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_MEMMOVE_CHK, "__memmove_chk", BT_FN_PTR_PTR_CONST_PTR_SIZE_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_MEMPCPY_CHK, "__mempcpy_chk", BT_FN_PTR_PTR_CONST_PTR_SIZE_SIZE, ATTR_NOTHROW_NONNULL_LEAF)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_MEMSET_CHK, "__memset_chk", BT_FN_PTR_PTR_INT_SIZE_SIZE, ATTR_NOTHROW_NONNULL_LEAF)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_STPCPY_CHK, "__stpcpy_chk", BT_FN_STRING_STRING_CONST_STRING_SIZE, ATTR_NOTHROW_NONNULL_LEAF)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_STPNCPY_CHK, "__stpncpy_chk", BT_FN_STRING_STRING_CONST_STRING_SIZE_SIZE, ATTR_NOTHROW_NONNULL_LEAF)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_STRCAT_CHK, "__strcat_chk", BT_FN_STRING_STRING_CONST_STRING_SIZE, ATTR_NOTHROW_NONNULL_LEAF)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_STRCPY_CHK, "__strcpy_chk", BT_FN_STRING_STRING_CONST_STRING_SIZE, ATTR_NOTHROW_NONNULL_LEAF)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_STRNCAT_CHK, "__strncat_chk", BT_FN_STRING_STRING_CONST_STRING_SIZE_SIZE, ATTR_NOTHROW_NONNULL_LEAF)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_STRNCPY_CHK, "__strncpy_chk", BT_FN_STRING_STRING_CONST_STRING_SIZE_SIZE, ATTR_NOTHROW_NONNULL_LEAF)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_SNPRINTF_CHK, "__snprintf_chk", BT_FN_INT_STRING_SIZE_INT_SIZE_CONST_STRING_VAR, ATTR_FORMAT_PRINTF_NOTHROW_5_6)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_SPRINTF_CHK, "__sprintf_chk", BT_FN_INT_STRING_INT_SIZE_CONST_STRING_VAR, ATTR_FORMAT_PRINTF_NOTHROW_4_5)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_VSNPRINTF_CHK, "__vsnprintf_chk", BT_FN_INT_STRING_SIZE_INT_SIZE_CONST_STRING_VALIST_ARG, ATTR_FORMAT_PRINTF_NOTHROW_5_0)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_VSPRINTF_CHK, "__vsprintf_chk", BT_FN_INT_STRING_INT_SIZE_CONST_STRING_VALIST_ARG, ATTR_FORMAT_PRINTF_NOTHROW_4_0)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_FPRINTF_CHK, "__fprintf_chk", BT_FN_INT_FILEPTR_INT_CONST_STRING_VAR, ATTR_FORMAT_PRINTF_3_4)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_PRINTF_CHK, "__printf_chk", BT_FN_INT_INT_CONST_STRING_VAR, ATTR_FORMAT_PRINTF_2_3)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_VFPRINTF_CHK, "__vfprintf_chk", BT_FN_INT_FILEPTR_INT_CONST_STRING_VALIST_ARG, ATTR_FORMAT_PRINTF_3_0)
|
||||||
|
DEF_EXT_LIB_BUILTIN (BUILT_IN_VPRINTF_CHK, "__vprintf_chk", BT_FN_INT_INT_CONST_STRING_VALIST_ARG, ATTR_FORMAT_PRINTF_2_0)
|
||||||
|
|
||||||
|
/* Profiling hooks. */
|
||||||
|
DEF_BUILTIN (BUILT_IN_PROFILE_FUNC_ENTER, "__cyg_profile_func_enter", BUILT_IN_NORMAL, BT_FN_VOID_PTR_PTR, BT_LAST,
|
||||||
|
false, false, false, ATTR_NULL, true, true)
|
||||||
|
DEF_BUILTIN (BUILT_IN_PROFILE_FUNC_EXIT, "__cyg_profile_func_exit", BUILT_IN_NORMAL, BT_FN_VOID_PTR_PTR, BT_LAST,
|
||||||
|
false, false, false, ATTR_NULL, true, true)
|
||||||
|
|
||||||
|
/* TLS thread pointer related builtins. */
|
||||||
|
DEF_BUILTIN (BUILT_IN_THREAD_POINTER, "__builtin_thread_pointer",
|
||||||
|
BUILT_IN_NORMAL, BT_FN_PTR, BT_LAST,
|
||||||
|
false, false, true, ATTR_CONST_NOTHROW_LIST, true,
|
||||||
|
targetm.have_tls)
|
||||||
|
|
||||||
|
DEF_BUILTIN (BUILT_IN_SET_THREAD_POINTER, "__builtin_set_thread_pointer",
|
||||||
|
BUILT_IN_NORMAL, BT_FN_VOID_PTR, BT_LAST,
|
||||||
|
false, false, true, ATTR_NOTHROW_LIST, true,
|
||||||
|
targetm.have_tls)
|
||||||
|
|
||||||
|
/* TLS emulation. */
|
||||||
|
DEF_BUILTIN (BUILT_IN_EMUTLS_GET_ADDRESS, targetm.emutls.get_address,
|
||||||
|
BUILT_IN_NORMAL,
|
||||||
|
BT_FN_PTR_PTR, BT_FN_PTR_PTR,
|
||||||
|
true, true, true, ATTR_CONST_NOTHROW_NONNULL_LEAF, false,
|
||||||
|
!targetm.have_tls)
|
||||||
|
DEF_BUILTIN (BUILT_IN_EMUTLS_REGISTER_COMMON,
|
||||||
|
targetm.emutls.register_common, BUILT_IN_NORMAL,
|
||||||
|
BT_FN_VOID_PTR_WORD_WORD_PTR, BT_FN_VOID_PTR_WORD_WORD_PTR,
|
||||||
|
true, true, true, ATTR_NOTHROW_LEAF_LIST, false,
|
||||||
|
!targetm.have_tls)
|
||||||
|
|
||||||
|
/* Exception support. */
|
||||||
|
DEF_BUILTIN_STUB (BUILT_IN_UNWIND_RESUME, "__builtin_unwind_resume")
|
||||||
|
DEF_BUILTIN_STUB (BUILT_IN_CXA_END_CLEANUP, "__builtin_cxa_end_cleanup")
|
||||||
|
DEF_BUILTIN_STUB (BUILT_IN_EH_POINTER, "__builtin_eh_pointer")
|
||||||
|
DEF_BUILTIN_STUB (BUILT_IN_EH_FILTER, "__builtin_eh_filter")
|
||||||
|
DEF_BUILTIN_STUB (BUILT_IN_EH_COPY_VALUES, "__builtin_eh_copy_values")
|
||||||
|
|
||||||
|
/* __FILE__, __LINE__, __FUNCTION__ as builtins. */
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_FILE, "FILE", BT_FN_CONST_STRING, ATTR_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_FUNCTION, "FUNCTION", BT_FN_CONST_STRING, ATTR_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_GCC_BUILTIN (BUILT_IN_LINE, "LINE", BT_FN_INT, ATTR_NOTHROW_LEAF_LIST)
|
||||||
|
|
||||||
|
/* Synchronization Primitives. */
|
||||||
|
#include "sync-builtins.def"
|
||||||
|
|
||||||
|
/* OpenMP builtins. */
|
||||||
|
#include "omp-builtins.def"
|
||||||
|
|
||||||
|
/* GTM builtins. */
|
||||||
|
#include "gtm-builtins.def"
|
||||||
|
|
||||||
|
/* Sanitizer builtins. */
|
||||||
|
#include "sanitizer.def"
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
#define BUILDING_GCC_MAJOR 4
|
||||||
|
#define BUILDING_GCC_MINOR 8
|
||||||
|
#define BUILDING_GCC_PATCHLEVEL 5
|
||||||
|
#define BUILDING_GCC_VERSION (BUILDING_GCC_MAJOR * 1000 + BUILDING_GCC_MINOR)
|
|
@ -0,0 +1,62 @@
|
||||||
|
/* This file contains the definitions and documentation for the
|
||||||
|
additional tree codes used in the GNU C compiler (see tree.def
|
||||||
|
for the standard codes).
|
||||||
|
Copyright (C) 1987-2013 Free Software Foundation, Inc.
|
||||||
|
Written by Benjamin Chelf <chelf@codesourcery.com>
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free
|
||||||
|
Software Foundation; either version 3, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GCC; see the file COPYING3. If not see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
/* Tree nodes used in the C frontend. These are also shared with the
|
||||||
|
C++ and Objective C frontends. */
|
||||||
|
|
||||||
|
/* A C_MAYBE_CONST_EXPR, currently only used for C and Objective C,
|
||||||
|
tracks information about constancy of an expression and VLA type
|
||||||
|
sizes or VM expressions from typeof that need to be evaluated
|
||||||
|
before the main expression. It is used during parsing and removed
|
||||||
|
in c_fully_fold. C_MAYBE_CONST_EXPR_PRE is the expression to
|
||||||
|
evaluate first, if not NULL; C_MAYBE_CONST_EXPR_EXPR is the main
|
||||||
|
expression. If C_MAYBE_CONST_EXPR_INT_OPERANDS is set then the
|
||||||
|
expression may be used in an unevaluated part of an integer
|
||||||
|
constant expression, but not in an evaluated part. If
|
||||||
|
C_MAYBE_CONST_EXPR_NON_CONST is set then the expression contains
|
||||||
|
something that cannot occur in an evaluated part of a constant
|
||||||
|
expression (or outside of sizeof in C90 mode); otherwise it does
|
||||||
|
not. */
|
||||||
|
DEFTREECODE (C_MAYBE_CONST_EXPR, "c_maybe_const_expr", tcc_expression, 2)
|
||||||
|
|
||||||
|
/* An EXCESS_PRECISION_EXPR, currently only used for C and Objective
|
||||||
|
C, represents an expression evaluated in greater range or precision
|
||||||
|
than its type. The type of the EXCESS_PRECISION_EXPR is the
|
||||||
|
semantic type while the operand represents what is actually being
|
||||||
|
evaluated. */
|
||||||
|
DEFTREECODE (EXCESS_PRECISION_EXPR, "excess_precision_expr", tcc_expression, 1)
|
||||||
|
|
||||||
|
/* Used to represent a user-defined literal.
|
||||||
|
The operands are an IDENTIFIER for the suffix, the VALUE of the literal,
|
||||||
|
and for numeric literals the original string representation of the
|
||||||
|
number. */
|
||||||
|
DEFTREECODE (USERDEF_LITERAL, "userdef_literal", tcc_exceptional, 3)
|
||||||
|
|
||||||
|
/* Represents a 'sizeof' expression during C++ template expansion,
|
||||||
|
or for the purpose of -Wsizeof-pointer-memaccess warning. */
|
||||||
|
DEFTREECODE (SIZEOF_EXPR, "sizeof_expr", tcc_expression, 1)
|
||||||
|
|
||||||
|
/*
|
||||||
|
Local variables:
|
||||||
|
mode:c
|
||||||
|
End:
|
||||||
|
*/
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,114 @@
|
||||||
|
/* Definitions of Objective-C front-end entry points used for C and C++.
|
||||||
|
Copyright (C) 1987-2013 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free
|
||||||
|
Software Foundation; either version 3, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GCC; see the file COPYING3. If not see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#ifndef GCC_C_COMMON_OBJC_H
|
||||||
|
#define GCC_C_COMMON_OBJC_H
|
||||||
|
|
||||||
|
/* ObjC ivar visibility types. */
|
||||||
|
typedef enum objc_ivar_visibility_kind {
|
||||||
|
OBJC_IVAR_VIS_PROTECTED = 0,
|
||||||
|
OBJC_IVAR_VIS_PUBLIC = 1,
|
||||||
|
OBJC_IVAR_VIS_PRIVATE = 2,
|
||||||
|
OBJC_IVAR_VIS_PACKAGE = 3
|
||||||
|
} objc_ivar_visibility_kind;
|
||||||
|
|
||||||
|
/* Objective-C / Objective-C++ entry points. */
|
||||||
|
|
||||||
|
/* The following ObjC/ObjC++ functions are called by the C and/or C++
|
||||||
|
front-ends; they all must have corresponding stubs in stub-objc.c. */
|
||||||
|
extern void objc_write_global_declarations (void);
|
||||||
|
extern tree objc_is_class_name (tree);
|
||||||
|
extern tree objc_is_object_ptr (tree);
|
||||||
|
extern void objc_check_decl (tree);
|
||||||
|
extern void objc_check_global_decl (tree);
|
||||||
|
extern tree objc_common_type (tree, tree);
|
||||||
|
extern bool objc_compare_types (tree, tree, int, tree);
|
||||||
|
extern bool objc_have_common_type (tree, tree, int, tree);
|
||||||
|
extern bool objc_diagnose_private_ivar (tree);
|
||||||
|
extern void objc_volatilize_decl (tree);
|
||||||
|
extern tree objc_rewrite_function_call (tree, tree);
|
||||||
|
extern tree objc_message_selector (void);
|
||||||
|
extern tree objc_lookup_ivar (tree, tree);
|
||||||
|
extern void objc_clear_super_receiver (void);
|
||||||
|
extern int objc_is_public (tree, tree);
|
||||||
|
extern tree objc_is_id (tree);
|
||||||
|
extern void objc_declare_alias (tree, tree);
|
||||||
|
extern void objc_declare_class (tree);
|
||||||
|
extern void objc_declare_protocol (tree, tree);
|
||||||
|
extern tree objc_build_message_expr (tree, tree);
|
||||||
|
extern tree objc_finish_message_expr (tree, tree, tree, tree*);
|
||||||
|
extern tree objc_build_selector_expr (location_t, tree);
|
||||||
|
extern tree objc_build_protocol_expr (tree);
|
||||||
|
extern tree objc_build_encode_expr (tree);
|
||||||
|
extern tree objc_build_string_object (tree);
|
||||||
|
extern tree objc_get_protocol_qualified_type (tree, tree);
|
||||||
|
extern tree objc_get_class_reference (tree);
|
||||||
|
extern tree objc_get_class_ivars (tree);
|
||||||
|
extern bool objc_detect_field_duplicates (bool);
|
||||||
|
extern void objc_start_class_interface (tree, tree, tree, tree);
|
||||||
|
extern void objc_start_category_interface (tree, tree, tree, tree);
|
||||||
|
extern void objc_start_protocol (tree, tree, tree);
|
||||||
|
extern void objc_continue_interface (void);
|
||||||
|
extern void objc_finish_interface (void);
|
||||||
|
extern void objc_start_class_implementation (tree, tree);
|
||||||
|
extern void objc_start_category_implementation (tree, tree);
|
||||||
|
extern void objc_continue_implementation (void);
|
||||||
|
extern void objc_finish_implementation (void);
|
||||||
|
extern void objc_set_visibility (objc_ivar_visibility_kind);
|
||||||
|
extern tree objc_build_method_signature (bool, tree, tree, tree, bool);
|
||||||
|
extern void objc_add_method_declaration (bool, tree, tree);
|
||||||
|
extern bool objc_start_method_definition (bool, tree, tree, tree);
|
||||||
|
extern void objc_finish_method_definition (tree);
|
||||||
|
extern void objc_add_instance_variable (tree);
|
||||||
|
extern tree objc_build_keyword_decl (tree, tree, tree, tree);
|
||||||
|
extern tree objc_build_throw_stmt (location_t, tree);
|
||||||
|
extern void objc_begin_try_stmt (location_t, tree);
|
||||||
|
extern tree objc_finish_try_stmt (void);
|
||||||
|
extern void objc_begin_catch_clause (tree);
|
||||||
|
extern void objc_finish_catch_clause (void);
|
||||||
|
extern void objc_build_finally_clause (location_t, tree);
|
||||||
|
extern tree objc_build_synchronized (location_t, tree, tree);
|
||||||
|
extern int objc_static_init_needed_p (void);
|
||||||
|
extern tree objc_generate_static_init_call (tree);
|
||||||
|
extern tree objc_generate_write_barrier (tree, enum tree_code, tree);
|
||||||
|
extern void objc_set_method_opt (bool);
|
||||||
|
extern void objc_finish_foreach_loop (location_t, tree, tree, tree, tree, tree);
|
||||||
|
extern bool objc_method_decl (enum tree_code);
|
||||||
|
extern void objc_add_property_declaration (location_t, tree, bool, bool, bool,
|
||||||
|
bool, bool, bool, tree, tree);
|
||||||
|
extern tree objc_maybe_build_component_ref (tree, tree);
|
||||||
|
extern tree objc_build_class_component_ref (tree, tree);
|
||||||
|
extern tree objc_maybe_build_modify_expr (tree, tree);
|
||||||
|
extern tree objc_build_incr_expr_for_property_ref (location_t, enum tree_code,
|
||||||
|
tree, tree);
|
||||||
|
extern void objc_add_synthesize_declaration (location_t, tree);
|
||||||
|
extern void objc_add_dynamic_declaration (location_t, tree);
|
||||||
|
extern const char * objc_maybe_printable_name (tree, int);
|
||||||
|
extern bool objc_is_property_ref (tree);
|
||||||
|
extern bool objc_string_ref_type_p (tree);
|
||||||
|
extern void objc_check_format_arg (tree, tree);
|
||||||
|
extern void objc_finish_function (void);
|
||||||
|
extern void objc_maybe_warn_exceptions (location_t);
|
||||||
|
|
||||||
|
/* The following are provided by the C and C++ front-ends, and called by
|
||||||
|
ObjC/ObjC++. */
|
||||||
|
extern void *objc_get_current_scope (void);
|
||||||
|
extern void objc_mark_locals_volatile (void *);
|
||||||
|
|
||||||
|
#endif /* ! GCC_C_COMMON_OBJC_H */
|
|
@ -0,0 +1,150 @@
|
||||||
|
/* Pragma related interfaces.
|
||||||
|
Copyright (C) 1995-2013 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free
|
||||||
|
Software Foundation; either version 3, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GCC; see the file COPYING3. If not see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#ifndef GCC_C_PRAGMA_H
|
||||||
|
#define GCC_C_PRAGMA_H
|
||||||
|
|
||||||
|
#include "cpplib.h" /* For enum cpp_ttype. */
|
||||||
|
|
||||||
|
/* Pragma identifiers built in to the front end parsers. Identifiers
|
||||||
|
for ancillary handlers will follow these. */
|
||||||
|
typedef enum pragma_kind {
|
||||||
|
PRAGMA_NONE = 0,
|
||||||
|
|
||||||
|
PRAGMA_OMP_ATOMIC,
|
||||||
|
PRAGMA_OMP_BARRIER,
|
||||||
|
PRAGMA_OMP_CRITICAL,
|
||||||
|
PRAGMA_OMP_FLUSH,
|
||||||
|
PRAGMA_OMP_FOR,
|
||||||
|
PRAGMA_OMP_MASTER,
|
||||||
|
PRAGMA_OMP_ORDERED,
|
||||||
|
PRAGMA_OMP_PARALLEL,
|
||||||
|
PRAGMA_OMP_PARALLEL_FOR,
|
||||||
|
PRAGMA_OMP_PARALLEL_SECTIONS,
|
||||||
|
PRAGMA_OMP_SECTION,
|
||||||
|
PRAGMA_OMP_SECTIONS,
|
||||||
|
PRAGMA_OMP_SINGLE,
|
||||||
|
PRAGMA_OMP_TASK,
|
||||||
|
PRAGMA_OMP_TASKWAIT,
|
||||||
|
PRAGMA_OMP_TASKYIELD,
|
||||||
|
PRAGMA_OMP_THREADPRIVATE,
|
||||||
|
|
||||||
|
PRAGMA_GCC_PCH_PREPROCESS,
|
||||||
|
|
||||||
|
PRAGMA_FIRST_EXTERNAL
|
||||||
|
} pragma_kind;
|
||||||
|
|
||||||
|
|
||||||
|
/* All clauses defined by OpenMP 2.5 and 3.0.
|
||||||
|
Used internally by both C and C++ parsers. */
|
||||||
|
typedef enum pragma_omp_clause {
|
||||||
|
PRAGMA_OMP_CLAUSE_NONE = 0,
|
||||||
|
|
||||||
|
PRAGMA_OMP_CLAUSE_COLLAPSE,
|
||||||
|
PRAGMA_OMP_CLAUSE_COPYIN,
|
||||||
|
PRAGMA_OMP_CLAUSE_COPYPRIVATE,
|
||||||
|
PRAGMA_OMP_CLAUSE_DEFAULT,
|
||||||
|
PRAGMA_OMP_CLAUSE_FIRSTPRIVATE,
|
||||||
|
PRAGMA_OMP_CLAUSE_IF,
|
||||||
|
PRAGMA_OMP_CLAUSE_LASTPRIVATE,
|
||||||
|
PRAGMA_OMP_CLAUSE_NOWAIT,
|
||||||
|
PRAGMA_OMP_CLAUSE_NUM_THREADS,
|
||||||
|
PRAGMA_OMP_CLAUSE_ORDERED,
|
||||||
|
PRAGMA_OMP_CLAUSE_PRIVATE,
|
||||||
|
PRAGMA_OMP_CLAUSE_REDUCTION,
|
||||||
|
PRAGMA_OMP_CLAUSE_SCHEDULE,
|
||||||
|
PRAGMA_OMP_CLAUSE_SHARED,
|
||||||
|
PRAGMA_OMP_CLAUSE_UNTIED,
|
||||||
|
PRAGMA_OMP_CLAUSE_FINAL,
|
||||||
|
PRAGMA_OMP_CLAUSE_MERGEABLE
|
||||||
|
} pragma_omp_clause;
|
||||||
|
|
||||||
|
extern struct cpp_reader* parse_in;
|
||||||
|
|
||||||
|
/* It's safe to always leave visibility pragma enabled as if
|
||||||
|
visibility is not supported on the host OS platform the
|
||||||
|
statements are ignored. */
|
||||||
|
extern void push_visibility (const char *, int);
|
||||||
|
extern bool pop_visibility (int);
|
||||||
|
|
||||||
|
extern void init_pragma (void);
|
||||||
|
|
||||||
|
/* Front-end wrappers for pragma registration. */
|
||||||
|
typedef void (*pragma_handler_1arg)(struct cpp_reader *);
|
||||||
|
/* A second pragma handler, which adds a void * argument allowing to pass extra
|
||||||
|
data to the handler. */
|
||||||
|
typedef void (*pragma_handler_2arg)(struct cpp_reader *, void *);
|
||||||
|
|
||||||
|
/* This union allows to abstract the different handlers. */
|
||||||
|
union gen_pragma_handler {
|
||||||
|
pragma_handler_1arg handler_1arg;
|
||||||
|
pragma_handler_2arg handler_2arg;
|
||||||
|
};
|
||||||
|
/* Internally used to keep the data of the handler. */
|
||||||
|
struct internal_pragma_handler_d {
|
||||||
|
union gen_pragma_handler handler;
|
||||||
|
/* Permits to know if handler is a pragma_handler_1arg (extra_data is false)
|
||||||
|
or a pragma_handler_2arg (extra_data is true). */
|
||||||
|
bool extra_data;
|
||||||
|
/* A data field which can be used when extra_data is true. */
|
||||||
|
void * data;
|
||||||
|
};
|
||||||
|
typedef struct internal_pragma_handler_d internal_pragma_handler;
|
||||||
|
|
||||||
|
extern void c_register_pragma (const char *space, const char *name,
|
||||||
|
pragma_handler_1arg handler);
|
||||||
|
extern void c_register_pragma_with_data (const char *space, const char *name,
|
||||||
|
pragma_handler_2arg handler,
|
||||||
|
void *data);
|
||||||
|
|
||||||
|
extern void c_register_pragma_with_expansion (const char *space,
|
||||||
|
const char *name,
|
||||||
|
pragma_handler_1arg handler);
|
||||||
|
extern void c_register_pragma_with_expansion_and_data (const char *space,
|
||||||
|
const char *name,
|
||||||
|
pragma_handler_2arg handler,
|
||||||
|
void *data);
|
||||||
|
extern void c_invoke_pragma_handler (unsigned int);
|
||||||
|
|
||||||
|
extern void maybe_apply_pragma_weak (tree);
|
||||||
|
extern void maybe_apply_pending_pragma_weaks (void);
|
||||||
|
extern tree maybe_apply_renaming_pragma (tree, tree);
|
||||||
|
extern void add_to_renaming_pragma_list (tree, tree);
|
||||||
|
|
||||||
|
extern enum cpp_ttype pragma_lex (tree *);
|
||||||
|
|
||||||
|
/* Flags for use with c_lex_with_flags. The values here were picked
|
||||||
|
so that 0 means to translate and join strings. */
|
||||||
|
#define C_LEX_STRING_NO_TRANSLATE 1 /* Do not lex strings into
|
||||||
|
execution character set. */
|
||||||
|
#define C_LEX_STRING_NO_JOIN 2 /* Do not concatenate strings
|
||||||
|
nor translate them into execution
|
||||||
|
character set. */
|
||||||
|
|
||||||
|
/* This is not actually available to pragma parsers. It's merely a
|
||||||
|
convenient location to declare this function for c-lex, after
|
||||||
|
having enum cpp_ttype declared. */
|
||||||
|
extern enum cpp_ttype c_lex_with_flags (tree *, location_t *, unsigned char *,
|
||||||
|
int);
|
||||||
|
|
||||||
|
extern void c_pp_lookup_pragma (unsigned int, const char **, const char **);
|
||||||
|
|
||||||
|
extern GTY(()) tree pragma_extern_prefix;
|
||||||
|
|
||||||
|
#endif /* GCC_C_PRAGMA_H */
|
|
@ -0,0 +1,215 @@
|
||||||
|
/* Various declarations for the C and C++ pretty-printers.
|
||||||
|
Copyright (C) 2002-2013 Free Software Foundation, Inc.
|
||||||
|
Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net>
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free
|
||||||
|
Software Foundation; either version 3, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GCC; see the file COPYING3. If not see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#ifndef GCC_C_PRETTY_PRINTER
|
||||||
|
#define GCC_C_PRETTY_PRINTER
|
||||||
|
|
||||||
|
#include "tree.h"
|
||||||
|
#include "c-family/c-common.h"
|
||||||
|
#include "pretty-print.h"
|
||||||
|
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
pp_c_flag_abstract = 1 << 1,
|
||||||
|
pp_c_flag_gnu_v3 = 1 << 2,
|
||||||
|
pp_c_flag_last_bit = 3
|
||||||
|
} pp_c_pretty_print_flags;
|
||||||
|
|
||||||
|
|
||||||
|
/* The data type used to bundle information necessary for pretty-printing
|
||||||
|
a C or C++ entity. */
|
||||||
|
typedef struct c_pretty_print_info c_pretty_printer;
|
||||||
|
|
||||||
|
/* The type of a C pretty-printer 'member' function. */
|
||||||
|
typedef void (*c_pretty_print_fn) (c_pretty_printer *, tree);
|
||||||
|
|
||||||
|
/* The datatype that contains information necessary for pretty-printing
|
||||||
|
a tree that represents a C construct. Any pretty-printer for a
|
||||||
|
language using C/c++ syntax can derive from this datatype and reuse
|
||||||
|
facilities provided here. It can do so by having a subobject of type
|
||||||
|
c_pretty_printer and override the macro pp_c_base to return a pointer
|
||||||
|
to that subobject. Such a pretty-printer has the responsibility to
|
||||||
|
initialize the pp_base() part, then call pp_c_pretty_printer_init
|
||||||
|
to set up the components that are specific to the C pretty-printer.
|
||||||
|
A derived pretty-printer can override any function listed in the
|
||||||
|
vtable below. See cp/cxx-pretty-print.h and cp/cxx-pretty-print.c
|
||||||
|
for an example of derivation. */
|
||||||
|
struct c_pretty_print_info
|
||||||
|
{
|
||||||
|
pretty_printer base;
|
||||||
|
/* Points to the first element of an array of offset-list.
|
||||||
|
Not used yet. */
|
||||||
|
int *offset_list;
|
||||||
|
|
||||||
|
pp_flags flags;
|
||||||
|
|
||||||
|
/* These must be overridden by each of the C and C++ front-end to
|
||||||
|
reflect their understanding of syntactic productions when they differ. */
|
||||||
|
c_pretty_print_fn declaration;
|
||||||
|
c_pretty_print_fn declaration_specifiers;
|
||||||
|
c_pretty_print_fn declarator;
|
||||||
|
c_pretty_print_fn abstract_declarator;
|
||||||
|
c_pretty_print_fn direct_abstract_declarator;
|
||||||
|
c_pretty_print_fn type_specifier_seq;
|
||||||
|
c_pretty_print_fn direct_declarator;
|
||||||
|
c_pretty_print_fn ptr_operator;
|
||||||
|
c_pretty_print_fn parameter_list;
|
||||||
|
c_pretty_print_fn type_id;
|
||||||
|
c_pretty_print_fn simple_type_specifier;
|
||||||
|
c_pretty_print_fn function_specifier;
|
||||||
|
c_pretty_print_fn storage_class_specifier;
|
||||||
|
c_pretty_print_fn initializer;
|
||||||
|
|
||||||
|
c_pretty_print_fn statement;
|
||||||
|
|
||||||
|
c_pretty_print_fn constant;
|
||||||
|
c_pretty_print_fn id_expression;
|
||||||
|
c_pretty_print_fn primary_expression;
|
||||||
|
c_pretty_print_fn postfix_expression;
|
||||||
|
c_pretty_print_fn unary_expression;
|
||||||
|
c_pretty_print_fn multiplicative_expression;
|
||||||
|
c_pretty_print_fn conditional_expression;
|
||||||
|
c_pretty_print_fn assignment_expression;
|
||||||
|
c_pretty_print_fn expression;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Override the pp_base macro. Derived pretty-printers should not
|
||||||
|
touch this macro. Instead they should override pp_c_base instead. */
|
||||||
|
#undef pp_base
|
||||||
|
#define pp_base(PP) (&pp_c_base (PP)->base)
|
||||||
|
|
||||||
|
|
||||||
|
#define pp_c_tree_identifier(PPI, ID) \
|
||||||
|
pp_c_identifier (PPI, IDENTIFIER_POINTER (ID))
|
||||||
|
|
||||||
|
#define pp_declaration(PPI, T) \
|
||||||
|
pp_c_base (PPI)->declaration (pp_c_base (PPI), T)
|
||||||
|
#define pp_declaration_specifiers(PPI, D) \
|
||||||
|
pp_c_base (PPI)->declaration_specifiers (pp_c_base (PPI), D)
|
||||||
|
#define pp_abstract_declarator(PP, D) \
|
||||||
|
pp_c_base (PP)->abstract_declarator (pp_c_base (PP), D)
|
||||||
|
#define pp_type_specifier_seq(PPI, D) \
|
||||||
|
pp_c_base (PPI)->type_specifier_seq (pp_c_base (PPI), D)
|
||||||
|
#define pp_declarator(PPI, D) \
|
||||||
|
pp_c_base (PPI)->declarator (pp_c_base (PPI), D)
|
||||||
|
#define pp_direct_declarator(PPI, D) \
|
||||||
|
pp_c_base (PPI)->direct_declarator (pp_c_base (PPI), D)
|
||||||
|
#define pp_direct_abstract_declarator(PP, D) \
|
||||||
|
pp_c_base (PP)->direct_abstract_declarator (pp_c_base (PP), D)
|
||||||
|
#define pp_ptr_operator(PP, D) \
|
||||||
|
pp_c_base (PP)->ptr_operator (pp_c_base (PP), D)
|
||||||
|
#define pp_parameter_list(PPI, T) \
|
||||||
|
pp_c_base (PPI)->parameter_list (pp_c_base (PPI), T)
|
||||||
|
#define pp_type_id(PPI, D) \
|
||||||
|
pp_c_base (PPI)->type_id (pp_c_base (PPI), D)
|
||||||
|
#define pp_simple_type_specifier(PP, T) \
|
||||||
|
pp_c_base (PP)->simple_type_specifier (pp_c_base (PP), T)
|
||||||
|
#define pp_function_specifier(PP, D) \
|
||||||
|
pp_c_base (PP)->function_specifier (pp_c_base (PP), D)
|
||||||
|
#define pp_storage_class_specifier(PP, D) \
|
||||||
|
pp_c_base (PP)->storage_class_specifier (pp_c_base (PP), D);
|
||||||
|
|
||||||
|
#define pp_statement(PPI, S) \
|
||||||
|
pp_c_base (PPI)->statement (pp_c_base (PPI), S)
|
||||||
|
|
||||||
|
#define pp_constant(PP, E) \
|
||||||
|
pp_c_base (PP)->constant (pp_c_base (PP), E)
|
||||||
|
#define pp_id_expression(PP, E) \
|
||||||
|
pp_c_base (PP)->id_expression (pp_c_base (PP), E)
|
||||||
|
#define pp_primary_expression(PPI, E) \
|
||||||
|
pp_c_base (PPI)->primary_expression (pp_c_base (PPI), E)
|
||||||
|
#define pp_postfix_expression(PPI, E) \
|
||||||
|
pp_c_base (PPI)->postfix_expression (pp_c_base (PPI), E)
|
||||||
|
#define pp_unary_expression(PPI, E) \
|
||||||
|
pp_c_base (PPI)->unary_expression (pp_c_base (PPI), E)
|
||||||
|
#define pp_initializer(PPI, E) \
|
||||||
|
pp_c_base (PPI)->initializer (pp_c_base (PPI), E)
|
||||||
|
#define pp_multiplicative_expression(PPI, E) \
|
||||||
|
pp_c_base (PPI)->multiplicative_expression (pp_c_base (PPI), E)
|
||||||
|
#define pp_conditional_expression(PPI, E) \
|
||||||
|
pp_c_base (PPI)->conditional_expression (pp_c_base (PPI), E)
|
||||||
|
#define pp_assignment_expression(PPI, E) \
|
||||||
|
pp_c_base (PPI)->assignment_expression (pp_c_base (PPI), E)
|
||||||
|
#define pp_expression(PP, E) \
|
||||||
|
pp_c_base (PP)->expression (pp_c_base (PP), E)
|
||||||
|
|
||||||
|
|
||||||
|
/* Returns the c_pretty_printer base object of PRETTY-PRINTER. This
|
||||||
|
macro must be overridden by any subclass of c_pretty_print_info. */
|
||||||
|
#define pp_c_base(PP) (PP)
|
||||||
|
|
||||||
|
extern void pp_c_pretty_printer_init (c_pretty_printer *);
|
||||||
|
void pp_c_whitespace (c_pretty_printer *);
|
||||||
|
void pp_c_left_paren (c_pretty_printer *);
|
||||||
|
void pp_c_right_paren (c_pretty_printer *);
|
||||||
|
void pp_c_left_brace (c_pretty_printer *);
|
||||||
|
void pp_c_right_brace (c_pretty_printer *);
|
||||||
|
void pp_c_left_bracket (c_pretty_printer *);
|
||||||
|
void pp_c_right_bracket (c_pretty_printer *);
|
||||||
|
void pp_c_dot (c_pretty_printer *);
|
||||||
|
void pp_c_ampersand (c_pretty_printer *);
|
||||||
|
void pp_c_star (c_pretty_printer *);
|
||||||
|
void pp_c_arrow (c_pretty_printer *);
|
||||||
|
void pp_c_semicolon (c_pretty_printer *);
|
||||||
|
void pp_c_complement (c_pretty_printer *);
|
||||||
|
void pp_c_exclamation (c_pretty_printer *);
|
||||||
|
void pp_c_space_for_pointer_operator (c_pretty_printer *, tree);
|
||||||
|
|
||||||
|
/* Declarations. */
|
||||||
|
void pp_c_tree_decl_identifier (c_pretty_printer *, tree);
|
||||||
|
void pp_c_function_definition (c_pretty_printer *, tree);
|
||||||
|
void pp_c_attributes (c_pretty_printer *, tree);
|
||||||
|
void pp_c_attributes_display (c_pretty_printer *, tree);
|
||||||
|
void pp_c_cv_qualifiers (c_pretty_printer *pp, int qualifiers, bool func_type);
|
||||||
|
void pp_c_type_qualifier_list (c_pretty_printer *, tree);
|
||||||
|
void pp_c_parameter_type_list (c_pretty_printer *, tree);
|
||||||
|
void pp_c_declaration (c_pretty_printer *, tree);
|
||||||
|
void pp_c_declaration_specifiers (c_pretty_printer *, tree);
|
||||||
|
void pp_c_declarator (c_pretty_printer *, tree);
|
||||||
|
void pp_c_direct_declarator (c_pretty_printer *, tree);
|
||||||
|
void pp_c_specifier_qualifier_list (c_pretty_printer *, tree);
|
||||||
|
void pp_c_function_specifier (c_pretty_printer *, tree);
|
||||||
|
void pp_c_type_id (c_pretty_printer *, tree);
|
||||||
|
void pp_c_direct_abstract_declarator (c_pretty_printer *, tree);
|
||||||
|
void pp_c_type_specifier (c_pretty_printer *, tree);
|
||||||
|
void pp_c_storage_class_specifier (c_pretty_printer *, tree);
|
||||||
|
/* Statements. */
|
||||||
|
void pp_c_statement (c_pretty_printer *, tree);
|
||||||
|
/* Expressions. */
|
||||||
|
void pp_c_expression (c_pretty_printer *, tree);
|
||||||
|
void pp_c_logical_or_expression (c_pretty_printer *, tree);
|
||||||
|
void pp_c_expression_list (c_pretty_printer *, tree);
|
||||||
|
void pp_c_constructor_elts (c_pretty_printer *, vec<constructor_elt, va_gc> *);
|
||||||
|
void pp_c_call_argument_list (c_pretty_printer *, tree);
|
||||||
|
void pp_c_unary_expression (c_pretty_printer *, tree);
|
||||||
|
void pp_c_cast_expression (c_pretty_printer *, tree);
|
||||||
|
void pp_c_postfix_expression (c_pretty_printer *, tree);
|
||||||
|
void pp_c_primary_expression (c_pretty_printer *, tree);
|
||||||
|
void pp_c_init_declarator (c_pretty_printer *, tree);
|
||||||
|
void pp_c_constant (c_pretty_printer *, tree);
|
||||||
|
void pp_c_id_expression (c_pretty_printer *, tree);
|
||||||
|
void pp_c_ws_string (c_pretty_printer *, const char *);
|
||||||
|
void pp_c_identifier (c_pretty_printer *, const char *);
|
||||||
|
void pp_c_string_literal (c_pretty_printer *, tree);
|
||||||
|
|
||||||
|
void print_c_tree (FILE *file, tree t);
|
||||||
|
|
||||||
|
#endif /* GCC_C_PRETTY_PRINTER */
|
|
@ -0,0 +1,673 @@
|
||||||
|
/* Definitions for C parsing and type checking.
|
||||||
|
Copyright (C) 1987-2013 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free
|
||||||
|
Software Foundation; either version 3, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GCC; see the file COPYING3. If not see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#ifndef GCC_C_TREE_H
|
||||||
|
#define GCC_C_TREE_H
|
||||||
|
|
||||||
|
#include "c-family/c-common.h"
|
||||||
|
#include "diagnostic.h"
|
||||||
|
|
||||||
|
/* struct lang_identifier is private to c-decl.c, but langhooks.c needs to
|
||||||
|
know how big it is. This is sanity-checked in c-decl.c. */
|
||||||
|
#define C_SIZEOF_STRUCT_LANG_IDENTIFIER \
|
||||||
|
(sizeof (struct c_common_identifier) + 3 * sizeof (void *))
|
||||||
|
|
||||||
|
/* In a RECORD_TYPE or UNION_TYPE, nonzero if any component is read-only. */
|
||||||
|
#define C_TYPE_FIELDS_READONLY(TYPE) TREE_LANG_FLAG_1 (TYPE)
|
||||||
|
|
||||||
|
/* In a RECORD_TYPE or UNION_TYPE, nonzero if any component is volatile. */
|
||||||
|
#define C_TYPE_FIELDS_VOLATILE(TYPE) TREE_LANG_FLAG_2 (TYPE)
|
||||||
|
|
||||||
|
/* In a RECORD_TYPE or UNION_TYPE or ENUMERAL_TYPE
|
||||||
|
nonzero if the definition of the type has already started. */
|
||||||
|
#define C_TYPE_BEING_DEFINED(TYPE) TYPE_LANG_FLAG_0 (TYPE)
|
||||||
|
|
||||||
|
/* In an incomplete RECORD_TYPE or UNION_TYPE, a list of variable
|
||||||
|
declarations whose type would be completed by completing that type. */
|
||||||
|
#define C_TYPE_INCOMPLETE_VARS(TYPE) TYPE_VFIELD (TYPE)
|
||||||
|
|
||||||
|
/* In an IDENTIFIER_NODE, nonzero if this identifier is actually a
|
||||||
|
keyword. C_RID_CODE (node) is then the RID_* value of the keyword,
|
||||||
|
and C_RID_YYCODE is the token number wanted by Yacc. */
|
||||||
|
#define C_IS_RESERVED_WORD(ID) TREE_LANG_FLAG_0 (ID)
|
||||||
|
|
||||||
|
/* Record whether a type or decl was written with nonconstant size.
|
||||||
|
Note that TYPE_SIZE may have simplified to a constant. */
|
||||||
|
#define C_TYPE_VARIABLE_SIZE(TYPE) TYPE_LANG_FLAG_1 (TYPE)
|
||||||
|
#define C_DECL_VARIABLE_SIZE(TYPE) DECL_LANG_FLAG_0 (TYPE)
|
||||||
|
|
||||||
|
/* Record whether a type is defined inside a struct or union type.
|
||||||
|
This is used for -Wc++-compat. */
|
||||||
|
#define C_TYPE_DEFINED_IN_STRUCT(TYPE) TYPE_LANG_FLAG_2 (TYPE)
|
||||||
|
|
||||||
|
/* Record whether a typedef for type `int' was actually `signed int'. */
|
||||||
|
#define C_TYPEDEF_EXPLICITLY_SIGNED(EXP) DECL_LANG_FLAG_1 (EXP)
|
||||||
|
|
||||||
|
/* For a FUNCTION_DECL, nonzero if it was defined without an explicit
|
||||||
|
return type. */
|
||||||
|
#define C_FUNCTION_IMPLICIT_INT(EXP) DECL_LANG_FLAG_1 (EXP)
|
||||||
|
|
||||||
|
/* For a FUNCTION_DECL, nonzero if it was an implicit declaration. */
|
||||||
|
#define C_DECL_IMPLICIT(EXP) DECL_LANG_FLAG_2 (EXP)
|
||||||
|
|
||||||
|
/* For FUNCTION_DECLs, evaluates true if the decl is built-in but has
|
||||||
|
been declared. */
|
||||||
|
#define C_DECL_DECLARED_BUILTIN(EXP) \
|
||||||
|
DECL_LANG_FLAG_3 (FUNCTION_DECL_CHECK (EXP))
|
||||||
|
|
||||||
|
/* For FUNCTION_DECLs, evaluates true if the decl is built-in, has a
|
||||||
|
built-in prototype and does not have a non-built-in prototype. */
|
||||||
|
#define C_DECL_BUILTIN_PROTOTYPE(EXP) \
|
||||||
|
DECL_LANG_FLAG_6 (FUNCTION_DECL_CHECK (EXP))
|
||||||
|
|
||||||
|
/* Record whether a decl was declared register. This is strictly a
|
||||||
|
front-end flag, whereas DECL_REGISTER is used for code generation;
|
||||||
|
they may differ for structures with volatile fields. */
|
||||||
|
#define C_DECL_REGISTER(EXP) DECL_LANG_FLAG_4 (EXP)
|
||||||
|
|
||||||
|
/* Record whether a decl was used in an expression anywhere except an
|
||||||
|
unevaluated operand of sizeof / typeof / alignof. This is only
|
||||||
|
used for functions declared static but not defined, though outside
|
||||||
|
sizeof and typeof it is set for other function decls as well. */
|
||||||
|
#define C_DECL_USED(EXP) DECL_LANG_FLAG_5 (FUNCTION_DECL_CHECK (EXP))
|
||||||
|
|
||||||
|
/* Record whether a variable has been declared threadprivate by
|
||||||
|
#pragma omp threadprivate. */
|
||||||
|
#define C_DECL_THREADPRIVATE_P(DECL) DECL_LANG_FLAG_3 (VAR_DECL_CHECK (DECL))
|
||||||
|
|
||||||
|
/* Nonzero for a decl which either doesn't exist or isn't a prototype.
|
||||||
|
N.B. Could be simplified if all built-in decls had complete prototypes
|
||||||
|
(but this is presently difficult because some of them need FILE*). */
|
||||||
|
#define C_DECL_ISNT_PROTOTYPE(EXP) \
|
||||||
|
(EXP == 0 \
|
||||||
|
|| (!prototype_p (TREE_TYPE (EXP)) \
|
||||||
|
&& !DECL_BUILT_IN (EXP)))
|
||||||
|
|
||||||
|
/* For FUNCTION_TYPE, a hidden list of types of arguments. The same as
|
||||||
|
TYPE_ARG_TYPES for functions with prototypes, but created for functions
|
||||||
|
without prototypes. */
|
||||||
|
#define TYPE_ACTUAL_ARG_TYPES(NODE) TYPE_LANG_SLOT_1 (NODE)
|
||||||
|
|
||||||
|
/* For a CONSTRUCTOR, whether some initializer contains a
|
||||||
|
subexpression meaning it is not a constant expression. */
|
||||||
|
#define CONSTRUCTOR_NON_CONST(EXPR) TREE_LANG_FLAG_1 (CONSTRUCTOR_CHECK (EXPR))
|
||||||
|
|
||||||
|
/* Record parser information about an expression that is irrelevant
|
||||||
|
for code generation alongside a tree representing its value. */
|
||||||
|
struct c_expr
|
||||||
|
{
|
||||||
|
/* The value of the expression. */
|
||||||
|
tree value;
|
||||||
|
/* Record the original unary/binary operator of an expression, which may
|
||||||
|
have been changed by fold, STRING_CST for unparenthesized string
|
||||||
|
constants, C_MAYBE_CONST_EXPR for __builtin_constant_p calls
|
||||||
|
(even if parenthesized), for subexpressions, and for non-constant
|
||||||
|
initializers, or ERROR_MARK for other expressions (including
|
||||||
|
parenthesized expressions). */
|
||||||
|
enum tree_code original_code;
|
||||||
|
/* If not NULL, the original type of an expression. This will
|
||||||
|
differ from the type of the value field for an enum constant.
|
||||||
|
The type of an enum constant is a plain integer type, but this
|
||||||
|
field will be the enum type. */
|
||||||
|
tree original_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Type alias for struct c_expr. This allows to use the structure
|
||||||
|
inside the VEC types. */
|
||||||
|
typedef struct c_expr c_expr_t;
|
||||||
|
|
||||||
|
/* A varray of c_expr_t. */
|
||||||
|
|
||||||
|
/* Append a new c_expr_t element to V. */
|
||||||
|
#define C_EXPR_APPEND(V, ELEM) \
|
||||||
|
do { \
|
||||||
|
c_expr_t __elem = (ELEM); \
|
||||||
|
vec_safe_push (V, __elem); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/* A kind of type specifier. Note that this information is currently
|
||||||
|
only used to distinguish tag definitions, tag references and typeof
|
||||||
|
uses. */
|
||||||
|
enum c_typespec_kind {
|
||||||
|
/* No typespec. This appears only in struct c_declspec. */
|
||||||
|
ctsk_none,
|
||||||
|
/* A reserved keyword type specifier. */
|
||||||
|
ctsk_resword,
|
||||||
|
/* A reference to a tag, previously declared, such as "struct foo".
|
||||||
|
This includes where the previous declaration was as a different
|
||||||
|
kind of tag, in which case this is only valid if shadowing that
|
||||||
|
tag in an inner scope. */
|
||||||
|
ctsk_tagref,
|
||||||
|
/* A reference to a tag, not previously declared in a visible
|
||||||
|
scope. */
|
||||||
|
ctsk_tagfirstref,
|
||||||
|
/* A definition of a tag such as "struct foo { int a; }". */
|
||||||
|
ctsk_tagdef,
|
||||||
|
/* A typedef name. */
|
||||||
|
ctsk_typedef,
|
||||||
|
/* An ObjC-specific kind of type specifier. */
|
||||||
|
ctsk_objc,
|
||||||
|
/* A typeof specifier. */
|
||||||
|
ctsk_typeof
|
||||||
|
};
|
||||||
|
|
||||||
|
/* A type specifier: this structure is created in the parser and
|
||||||
|
passed to declspecs_add_type only. */
|
||||||
|
struct c_typespec {
|
||||||
|
/* What kind of type specifier this is. */
|
||||||
|
enum c_typespec_kind kind;
|
||||||
|
/* Whether the expression has operands suitable for use in constant
|
||||||
|
expressions. */
|
||||||
|
bool expr_const_operands;
|
||||||
|
/* The specifier itself. */
|
||||||
|
tree spec;
|
||||||
|
/* An expression to be evaluated before the type specifier, in the
|
||||||
|
case of typeof specifiers, or NULL otherwise or if no such
|
||||||
|
expression is required for a particular typeof specifier. In
|
||||||
|
particular, when typeof is applied to an expression of variably
|
||||||
|
modified type, that expression must be evaluated in order to
|
||||||
|
determine array sizes that form part of the type, but the
|
||||||
|
expression itself (as opposed to the array sizes) forms no part
|
||||||
|
of the type and so needs to be recorded separately. */
|
||||||
|
tree expr;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* A storage class specifier. */
|
||||||
|
enum c_storage_class {
|
||||||
|
csc_none,
|
||||||
|
csc_auto,
|
||||||
|
csc_extern,
|
||||||
|
csc_register,
|
||||||
|
csc_static,
|
||||||
|
csc_typedef
|
||||||
|
};
|
||||||
|
|
||||||
|
/* A type specifier keyword "void", "_Bool", "char", "int", "float",
|
||||||
|
"double", "_Decimal32", "_Decimal64", "_Decimal128", "_Fract", "_Accum",
|
||||||
|
or none of these. */
|
||||||
|
enum c_typespec_keyword {
|
||||||
|
cts_none,
|
||||||
|
cts_void,
|
||||||
|
cts_bool,
|
||||||
|
cts_char,
|
||||||
|
cts_int,
|
||||||
|
cts_float,
|
||||||
|
cts_int128,
|
||||||
|
cts_double,
|
||||||
|
cts_dfloat32,
|
||||||
|
cts_dfloat64,
|
||||||
|
cts_dfloat128,
|
||||||
|
cts_fract,
|
||||||
|
cts_accum
|
||||||
|
};
|
||||||
|
|
||||||
|
/* This enum lists all the possible declarator specifiers, storage
|
||||||
|
class or attribute that a user can write. There is at least one
|
||||||
|
enumerator per possible declarator specifier in the struct
|
||||||
|
c_declspecs below.
|
||||||
|
|
||||||
|
It is used to index the array of declspec locations in struct
|
||||||
|
c_declspecs. */
|
||||||
|
enum c_declspec_word {
|
||||||
|
cdw_typespec /* A catch-all for a typespec. */,
|
||||||
|
cdw_storage_class /* A catch-all for a storage class */,
|
||||||
|
cdw_attributes,
|
||||||
|
cdw_typedef,
|
||||||
|
cdw_explicit_signed,
|
||||||
|
cdw_deprecated,
|
||||||
|
cdw_default_int,
|
||||||
|
cdw_long,
|
||||||
|
cdw_long_long,
|
||||||
|
cdw_short,
|
||||||
|
cdw_signed,
|
||||||
|
cdw_unsigned,
|
||||||
|
cdw_complex,
|
||||||
|
cdw_inline,
|
||||||
|
cdw_noreturn,
|
||||||
|
cdw_thread,
|
||||||
|
cdw_const,
|
||||||
|
cdw_volatile,
|
||||||
|
cdw_restrict,
|
||||||
|
cdw_saturating,
|
||||||
|
cdw_alignas,
|
||||||
|
cdw_address_space,
|
||||||
|
cdw_number_of_elements /* This one must always be the last
|
||||||
|
enumerator. */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* A sequence of declaration specifiers in C. When a new declaration
|
||||||
|
specifier is added, please update the enum c_declspec_word above
|
||||||
|
accordingly. */
|
||||||
|
struct c_declspecs {
|
||||||
|
source_location locations[cdw_number_of_elements];
|
||||||
|
/* The type specified, if a single type specifier such as a struct,
|
||||||
|
union or enum specifier, typedef name or typeof specifies the
|
||||||
|
whole type, or NULL_TREE if none or a keyword such as "void" or
|
||||||
|
"char" is used. Does not include qualifiers. */
|
||||||
|
tree type;
|
||||||
|
/* Any expression to be evaluated before the type, from a typeof
|
||||||
|
specifier. */
|
||||||
|
tree expr;
|
||||||
|
/* The attributes from a typedef decl. */
|
||||||
|
tree decl_attr;
|
||||||
|
/* When parsing, the attributes. Outside the parser, this will be
|
||||||
|
NULL; attributes (possibly from multiple lists) will be passed
|
||||||
|
separately. */
|
||||||
|
tree attrs;
|
||||||
|
/* The base-2 log of the greatest alignment required by an _Alignas
|
||||||
|
specifier, in bytes, or -1 if no such specifiers with nonzero
|
||||||
|
alignment. */
|
||||||
|
int align_log;
|
||||||
|
/* The storage class specifier, or csc_none if none. */
|
||||||
|
enum c_storage_class storage_class;
|
||||||
|
/* Any type specifier keyword used such as "int", not reflecting
|
||||||
|
modifiers such as "short", or cts_none if none. */
|
||||||
|
ENUM_BITFIELD (c_typespec_keyword) typespec_word : 8;
|
||||||
|
/* The kind of type specifier if one has been seen, ctsk_none
|
||||||
|
otherwise. */
|
||||||
|
ENUM_BITFIELD (c_typespec_kind) typespec_kind : 3;
|
||||||
|
/* Whether any expressions in typeof specifiers may appear in
|
||||||
|
constant expressions. */
|
||||||
|
BOOL_BITFIELD expr_const_operands : 1;
|
||||||
|
/* Whether any declaration specifiers have been seen at all. */
|
||||||
|
BOOL_BITFIELD declspecs_seen_p : 1;
|
||||||
|
/* Whether something other than a storage class specifier or
|
||||||
|
attribute has been seen. This is used to warn for the
|
||||||
|
obsolescent usage of storage class specifiers other than at the
|
||||||
|
start of the list. (Doing this properly would require function
|
||||||
|
specifiers to be handled separately from storage class
|
||||||
|
specifiers.) */
|
||||||
|
BOOL_BITFIELD non_sc_seen_p : 1;
|
||||||
|
/* Whether the type is specified by a typedef or typeof name. */
|
||||||
|
BOOL_BITFIELD typedef_p : 1;
|
||||||
|
/* Whether the type is explicitly "signed" or specified by a typedef
|
||||||
|
whose type is explicitly "signed". */
|
||||||
|
BOOL_BITFIELD explicit_signed_p : 1;
|
||||||
|
/* Whether the specifiers include a deprecated typedef. */
|
||||||
|
BOOL_BITFIELD deprecated_p : 1;
|
||||||
|
/* Whether the type defaulted to "int" because there were no type
|
||||||
|
specifiers. */
|
||||||
|
BOOL_BITFIELD default_int_p : 1;
|
||||||
|
/* Whether "long" was specified. */
|
||||||
|
BOOL_BITFIELD long_p : 1;
|
||||||
|
/* Whether "long" was specified more than once. */
|
||||||
|
BOOL_BITFIELD long_long_p : 1;
|
||||||
|
/* Whether "short" was specified. */
|
||||||
|
BOOL_BITFIELD short_p : 1;
|
||||||
|
/* Whether "signed" was specified. */
|
||||||
|
BOOL_BITFIELD signed_p : 1;
|
||||||
|
/* Whether "unsigned" was specified. */
|
||||||
|
BOOL_BITFIELD unsigned_p : 1;
|
||||||
|
/* Whether "complex" was specified. */
|
||||||
|
BOOL_BITFIELD complex_p : 1;
|
||||||
|
/* Whether "inline" was specified. */
|
||||||
|
BOOL_BITFIELD inline_p : 1;
|
||||||
|
/* Whether "_Noreturn" was speciied. */
|
||||||
|
BOOL_BITFIELD noreturn_p : 1;
|
||||||
|
/* Whether "__thread" was specified. */
|
||||||
|
BOOL_BITFIELD thread_p : 1;
|
||||||
|
/* Whether "const" was specified. */
|
||||||
|
BOOL_BITFIELD const_p : 1;
|
||||||
|
/* Whether "volatile" was specified. */
|
||||||
|
BOOL_BITFIELD volatile_p : 1;
|
||||||
|
/* Whether "restrict" was specified. */
|
||||||
|
BOOL_BITFIELD restrict_p : 1;
|
||||||
|
/* Whether "_Sat" was specified. */
|
||||||
|
BOOL_BITFIELD saturating_p : 1;
|
||||||
|
/* Whether any alignment specifier (even with zero alignment) was
|
||||||
|
specified. */
|
||||||
|
BOOL_BITFIELD alignas_p : 1;
|
||||||
|
/* The address space that the declaration belongs to. */
|
||||||
|
addr_space_t address_space;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* The various kinds of declarators in C. */
|
||||||
|
enum c_declarator_kind {
|
||||||
|
/* An identifier. */
|
||||||
|
cdk_id,
|
||||||
|
/* A function. */
|
||||||
|
cdk_function,
|
||||||
|
/* An array. */
|
||||||
|
cdk_array,
|
||||||
|
/* A pointer. */
|
||||||
|
cdk_pointer,
|
||||||
|
/* Parenthesized declarator with nested attributes. */
|
||||||
|
cdk_attrs
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct c_arg_tag_d {
|
||||||
|
/* The argument name. */
|
||||||
|
tree id;
|
||||||
|
/* The type of the argument. */
|
||||||
|
tree type;
|
||||||
|
} c_arg_tag;
|
||||||
|
|
||||||
|
|
||||||
|
/* Information about the parameters in a function declarator. */
|
||||||
|
struct c_arg_info {
|
||||||
|
/* A list of parameter decls. */
|
||||||
|
tree parms;
|
||||||
|
/* A list of structure, union and enum tags defined. */
|
||||||
|
vec<c_arg_tag, va_gc> *tags;
|
||||||
|
/* A list of argument types to go in the FUNCTION_TYPE. */
|
||||||
|
tree types;
|
||||||
|
/* A list of non-parameter decls (notably enumeration constants)
|
||||||
|
defined with the parameters. */
|
||||||
|
tree others;
|
||||||
|
/* A compound expression of VLA sizes from the parameters, or NULL.
|
||||||
|
In a function definition, these are used to ensure that
|
||||||
|
side-effects in sizes of arrays converted to pointers (such as a
|
||||||
|
parameter int i[n++]) take place; otherwise, they are
|
||||||
|
ignored. */
|
||||||
|
tree pending_sizes;
|
||||||
|
/* True when these arguments had [*]. */
|
||||||
|
BOOL_BITFIELD had_vla_unspec : 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* A declarator. */
|
||||||
|
struct c_declarator {
|
||||||
|
/* The kind of declarator. */
|
||||||
|
enum c_declarator_kind kind;
|
||||||
|
location_t id_loc; /* Currently only set for cdk_id, cdk_array. */
|
||||||
|
/* Except for cdk_id, the contained declarator. For cdk_id, NULL. */
|
||||||
|
struct c_declarator *declarator;
|
||||||
|
union {
|
||||||
|
/* For identifiers, an IDENTIFIER_NODE or NULL_TREE if an abstract
|
||||||
|
declarator. */
|
||||||
|
tree id;
|
||||||
|
/* For functions. */
|
||||||
|
struct c_arg_info *arg_info;
|
||||||
|
/* For arrays. */
|
||||||
|
struct {
|
||||||
|
/* The array dimension, or NULL for [] and [*]. */
|
||||||
|
tree dimen;
|
||||||
|
/* The qualifiers inside []. */
|
||||||
|
int quals;
|
||||||
|
/* The attributes (currently ignored) inside []. */
|
||||||
|
tree attrs;
|
||||||
|
/* Whether [static] was used. */
|
||||||
|
BOOL_BITFIELD static_p : 1;
|
||||||
|
/* Whether [*] was used. */
|
||||||
|
BOOL_BITFIELD vla_unspec_p : 1;
|
||||||
|
} array;
|
||||||
|
/* For pointers, the qualifiers on the pointer type. */
|
||||||
|
int pointer_quals;
|
||||||
|
/* For attributes. */
|
||||||
|
tree attrs;
|
||||||
|
} u;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* A type name. */
|
||||||
|
struct c_type_name {
|
||||||
|
/* The declaration specifiers. */
|
||||||
|
struct c_declspecs *specs;
|
||||||
|
/* The declarator. */
|
||||||
|
struct c_declarator *declarator;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* A parameter. */
|
||||||
|
struct c_parm {
|
||||||
|
/* The declaration specifiers, minus any prefix attributes. */
|
||||||
|
struct c_declspecs *specs;
|
||||||
|
/* The attributes. */
|
||||||
|
tree attrs;
|
||||||
|
/* The declarator. */
|
||||||
|
struct c_declarator *declarator;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Used when parsing an enum. Initialized by start_enum. */
|
||||||
|
struct c_enum_contents
|
||||||
|
{
|
||||||
|
/* While defining an enum type, this is 1 plus the last enumerator
|
||||||
|
constant value. */
|
||||||
|
tree enum_next_value;
|
||||||
|
|
||||||
|
/* Nonzero means that there was overflow computing enum_next_value. */
|
||||||
|
int enum_overflow;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* A type of reference to a static identifier in an inline
|
||||||
|
function. */
|
||||||
|
enum c_inline_static_type {
|
||||||
|
/* Identifier with internal linkage used in function that may be an
|
||||||
|
inline definition (i.e., file-scope static). */
|
||||||
|
csi_internal,
|
||||||
|
/* Modifiable object with static storage duration defined in
|
||||||
|
function that may be an inline definition (i.e., local
|
||||||
|
static). */
|
||||||
|
csi_modifiable
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* in c-parser.c */
|
||||||
|
extern void c_parse_init (void);
|
||||||
|
|
||||||
|
/* in c-aux-info.c */
|
||||||
|
extern void gen_aux_info_record (tree, int, int, int);
|
||||||
|
|
||||||
|
/* in c-decl.c */
|
||||||
|
struct c_spot_bindings;
|
||||||
|
struct c_struct_parse_info;
|
||||||
|
extern struct obstack parser_obstack;
|
||||||
|
extern tree c_break_label;
|
||||||
|
extern tree c_cont_label;
|
||||||
|
|
||||||
|
extern bool global_bindings_p (void);
|
||||||
|
extern void push_scope (void);
|
||||||
|
extern tree pop_scope (void);
|
||||||
|
extern void c_bindings_start_stmt_expr (struct c_spot_bindings *);
|
||||||
|
extern void c_bindings_end_stmt_expr (struct c_spot_bindings *);
|
||||||
|
|
||||||
|
extern void record_inline_static (location_t, tree, tree,
|
||||||
|
enum c_inline_static_type);
|
||||||
|
extern void c_init_decl_processing (void);
|
||||||
|
extern void c_print_identifier (FILE *, tree, int);
|
||||||
|
extern int quals_from_declspecs (const struct c_declspecs *);
|
||||||
|
extern struct c_declarator *build_array_declarator (location_t, tree,
|
||||||
|
struct c_declspecs *,
|
||||||
|
bool, bool);
|
||||||
|
extern tree build_enumerator (location_t, location_t, struct c_enum_contents *,
|
||||||
|
tree, tree);
|
||||||
|
extern tree check_for_loop_decls (location_t, bool);
|
||||||
|
extern void mark_forward_parm_decls (void);
|
||||||
|
extern void declare_parm_level (void);
|
||||||
|
extern void undeclared_variable (location_t, tree);
|
||||||
|
extern tree lookup_label_for_goto (location_t, tree);
|
||||||
|
extern tree declare_label (tree);
|
||||||
|
extern tree define_label (location_t, tree);
|
||||||
|
extern struct c_spot_bindings *c_get_switch_bindings (void);
|
||||||
|
extern void c_release_switch_bindings (struct c_spot_bindings *);
|
||||||
|
extern bool c_check_switch_jump_warnings (struct c_spot_bindings *,
|
||||||
|
location_t, location_t);
|
||||||
|
extern void finish_decl (tree, location_t, tree, tree, tree);
|
||||||
|
extern tree finish_enum (tree, tree, tree);
|
||||||
|
extern void finish_function (void);
|
||||||
|
extern tree finish_struct (location_t, tree, tree, tree,
|
||||||
|
struct c_struct_parse_info *);
|
||||||
|
extern struct c_arg_info *build_arg_info (void);
|
||||||
|
extern struct c_arg_info *get_parm_info (bool, tree);
|
||||||
|
extern tree grokfield (location_t, struct c_declarator *,
|
||||||
|
struct c_declspecs *, tree, tree *);
|
||||||
|
extern tree groktypename (struct c_type_name *, tree *, bool *);
|
||||||
|
extern tree grokparm (const struct c_parm *, tree *);
|
||||||
|
extern tree implicitly_declare (location_t, tree);
|
||||||
|
extern void keep_next_level (void);
|
||||||
|
extern void pending_xref_error (void);
|
||||||
|
extern void c_push_function_context (void);
|
||||||
|
extern void c_pop_function_context (void);
|
||||||
|
extern void push_parm_decl (const struct c_parm *, tree *);
|
||||||
|
extern struct c_declarator *set_array_declarator_inner (struct c_declarator *,
|
||||||
|
struct c_declarator *);
|
||||||
|
extern tree c_builtin_function (tree);
|
||||||
|
extern tree c_builtin_function_ext_scope (tree);
|
||||||
|
extern void shadow_tag (const struct c_declspecs *);
|
||||||
|
extern void shadow_tag_warned (const struct c_declspecs *, int);
|
||||||
|
extern tree start_enum (location_t, struct c_enum_contents *, tree);
|
||||||
|
extern int start_function (struct c_declspecs *, struct c_declarator *, tree);
|
||||||
|
extern tree start_decl (struct c_declarator *, struct c_declspecs *, bool,
|
||||||
|
tree);
|
||||||
|
extern tree start_struct (location_t, enum tree_code, tree,
|
||||||
|
struct c_struct_parse_info **);
|
||||||
|
extern void store_parm_decls (void);
|
||||||
|
extern void store_parm_decls_from (struct c_arg_info *);
|
||||||
|
extern tree xref_tag (enum tree_code, tree);
|
||||||
|
extern struct c_typespec parser_xref_tag (location_t, enum tree_code, tree);
|
||||||
|
extern struct c_parm *build_c_parm (struct c_declspecs *, tree,
|
||||||
|
struct c_declarator *);
|
||||||
|
extern struct c_declarator *build_attrs_declarator (tree,
|
||||||
|
struct c_declarator *);
|
||||||
|
extern struct c_declarator *build_function_declarator (struct c_arg_info *,
|
||||||
|
struct c_declarator *);
|
||||||
|
extern struct c_declarator *build_id_declarator (tree);
|
||||||
|
extern struct c_declarator *make_pointer_declarator (struct c_declspecs *,
|
||||||
|
struct c_declarator *);
|
||||||
|
extern struct c_declspecs *build_null_declspecs (void);
|
||||||
|
extern struct c_declspecs *declspecs_add_qual (source_location,
|
||||||
|
struct c_declspecs *, tree);
|
||||||
|
extern struct c_declspecs *declspecs_add_type (location_t,
|
||||||
|
struct c_declspecs *,
|
||||||
|
struct c_typespec);
|
||||||
|
extern struct c_declspecs *declspecs_add_scspec (source_location,
|
||||||
|
struct c_declspecs *, tree);
|
||||||
|
extern struct c_declspecs *declspecs_add_attrs (source_location,
|
||||||
|
struct c_declspecs *, tree);
|
||||||
|
extern struct c_declspecs *declspecs_add_addrspace (source_location,
|
||||||
|
struct c_declspecs *,
|
||||||
|
addr_space_t);
|
||||||
|
extern struct c_declspecs *declspecs_add_alignas (source_location,
|
||||||
|
struct c_declspecs *, tree);
|
||||||
|
extern struct c_declspecs *finish_declspecs (struct c_declspecs *);
|
||||||
|
|
||||||
|
/* in c-objc-common.c */
|
||||||
|
extern bool c_objc_common_init (void);
|
||||||
|
extern bool c_missing_noreturn_ok_p (tree);
|
||||||
|
extern bool c_warn_unused_global_decl (const_tree);
|
||||||
|
extern void c_initialize_diagnostics (diagnostic_context *);
|
||||||
|
extern bool c_vla_unspec_p (tree x, tree fn);
|
||||||
|
|
||||||
|
/* in c-typeck.c */
|
||||||
|
extern int in_alignof;
|
||||||
|
extern int in_sizeof;
|
||||||
|
extern int in_typeof;
|
||||||
|
|
||||||
|
extern tree c_last_sizeof_arg;
|
||||||
|
|
||||||
|
extern struct c_switch *c_switch_stack;
|
||||||
|
|
||||||
|
extern tree c_objc_common_truthvalue_conversion (location_t, tree);
|
||||||
|
extern tree require_complete_type (tree);
|
||||||
|
extern int same_translation_unit_p (const_tree, const_tree);
|
||||||
|
extern int comptypes (tree, tree);
|
||||||
|
extern int comptypes_check_different_types (tree, tree, bool *);
|
||||||
|
extern bool c_vla_type_p (const_tree);
|
||||||
|
extern bool c_mark_addressable (tree);
|
||||||
|
extern void c_incomplete_type_error (const_tree, const_tree);
|
||||||
|
extern tree c_type_promotes_to (tree);
|
||||||
|
extern struct c_expr default_function_array_conversion (location_t,
|
||||||
|
struct c_expr);
|
||||||
|
extern struct c_expr default_function_array_read_conversion (location_t,
|
||||||
|
struct c_expr);
|
||||||
|
extern void mark_exp_read (tree);
|
||||||
|
extern tree composite_type (tree, tree);
|
||||||
|
extern tree build_component_ref (location_t, tree, tree);
|
||||||
|
extern tree build_array_ref (location_t, tree, tree);
|
||||||
|
extern tree build_external_ref (location_t, tree, int, tree *);
|
||||||
|
extern void pop_maybe_used (bool);
|
||||||
|
extern struct c_expr c_expr_sizeof_expr (location_t, struct c_expr);
|
||||||
|
extern struct c_expr c_expr_sizeof_type (location_t, struct c_type_name *);
|
||||||
|
extern struct c_expr parser_build_unary_op (location_t, enum tree_code,
|
||||||
|
struct c_expr);
|
||||||
|
extern struct c_expr parser_build_binary_op (location_t,
|
||||||
|
enum tree_code, struct c_expr,
|
||||||
|
struct c_expr);
|
||||||
|
extern tree build_conditional_expr (location_t, tree, bool, tree, tree,
|
||||||
|
tree, tree);
|
||||||
|
extern tree build_compound_expr (location_t, tree, tree);
|
||||||
|
extern tree c_cast_expr (location_t, struct c_type_name *, tree);
|
||||||
|
extern tree build_c_cast (location_t, tree, tree);
|
||||||
|
extern void store_init_value (location_t, tree, tree, tree);
|
||||||
|
extern void error_init (const char *);
|
||||||
|
extern void pedwarn_init (location_t, int opt, const char *);
|
||||||
|
extern void maybe_warn_string_init (tree, struct c_expr);
|
||||||
|
extern void start_init (tree, tree, int);
|
||||||
|
extern void finish_init (void);
|
||||||
|
extern void really_start_incremental_init (tree);
|
||||||
|
extern void push_init_level (int, struct obstack *);
|
||||||
|
extern struct c_expr pop_init_level (int, struct obstack *);
|
||||||
|
extern void set_init_index (tree, tree, struct obstack *);
|
||||||
|
extern void set_init_label (tree, struct obstack *);
|
||||||
|
extern void process_init_element (struct c_expr, bool, struct obstack *);
|
||||||
|
extern tree build_compound_literal (location_t, tree, tree, bool);
|
||||||
|
extern void check_compound_literal_type (location_t, struct c_type_name *);
|
||||||
|
extern tree c_start_case (location_t, location_t, tree);
|
||||||
|
extern void c_finish_case (tree);
|
||||||
|
extern tree build_asm_expr (location_t, tree, tree, tree, tree, tree, bool);
|
||||||
|
extern tree build_asm_stmt (tree, tree);
|
||||||
|
extern int c_types_compatible_p (tree, tree);
|
||||||
|
extern tree c_begin_compound_stmt (bool);
|
||||||
|
extern tree c_end_compound_stmt (location_t, tree, bool);
|
||||||
|
extern void c_finish_if_stmt (location_t, tree, tree, tree, bool);
|
||||||
|
extern void c_finish_loop (location_t, tree, tree, tree, tree, tree, bool);
|
||||||
|
extern tree c_begin_stmt_expr (void);
|
||||||
|
extern tree c_finish_stmt_expr (location_t, tree);
|
||||||
|
extern tree c_process_expr_stmt (location_t, tree);
|
||||||
|
extern tree c_finish_expr_stmt (location_t, tree);
|
||||||
|
extern tree c_finish_return (location_t, tree, tree);
|
||||||
|
extern tree c_finish_bc_stmt (location_t, tree *, bool);
|
||||||
|
extern tree c_finish_goto_label (location_t, tree);
|
||||||
|
extern tree c_finish_goto_ptr (location_t, tree);
|
||||||
|
extern tree c_expr_to_decl (tree, bool *, bool *);
|
||||||
|
extern tree c_begin_omp_parallel (void);
|
||||||
|
extern tree c_finish_omp_parallel (location_t, tree, tree);
|
||||||
|
extern tree c_begin_omp_task (void);
|
||||||
|
extern tree c_finish_omp_task (location_t, tree, tree);
|
||||||
|
extern tree c_finish_omp_clauses (tree);
|
||||||
|
extern tree c_build_va_arg (location_t, tree, tree);
|
||||||
|
extern tree c_finish_transaction (location_t, tree, int);
|
||||||
|
extern tree c_build_function_call_vec (location_t, tree, vec<tree, va_gc> *,
|
||||||
|
vec<tree, va_gc> *);
|
||||||
|
|
||||||
|
/* Set to 0 at beginning of a function definition, set to 1 if
|
||||||
|
a return statement that specifies a return value is seen. */
|
||||||
|
|
||||||
|
extern int current_function_returns_value;
|
||||||
|
|
||||||
|
/* Set to 0 at beginning of a function definition, set to 1 if
|
||||||
|
a return statement with no argument is seen. */
|
||||||
|
|
||||||
|
extern int current_function_returns_null;
|
||||||
|
|
||||||
|
/* Set to 0 at beginning of a function definition, set to 1 if
|
||||||
|
a call to a noreturn function is seen. */
|
||||||
|
|
||||||
|
extern int current_function_returns_abnormally;
|
||||||
|
|
||||||
|
/* Mode used to build pointers (VOIDmode means ptr_mode). */
|
||||||
|
|
||||||
|
extern enum machine_mode c_default_pointer_mode;
|
||||||
|
|
||||||
|
/* In c-decl.c */
|
||||||
|
extern void c_finish_incomplete_decl (tree);
|
||||||
|
extern void c_write_global_declarations (void);
|
||||||
|
|
||||||
|
/* In c-errors.c */
|
||||||
|
extern void pedwarn_c90 (location_t, int opt, const char *, ...) ATTRIBUTE_GCC_DIAG(3,4);
|
||||||
|
extern void pedwarn_c99 (location_t, int opt, const char *, ...) ATTRIBUTE_GCC_DIAG(3,4);
|
||||||
|
|
||||||
|
#endif /* ! GCC_C_TREE_H */
|
|
@ -0,0 +1,186 @@
|
||||||
|
/* Flags on basic blocks and edges.
|
||||||
|
Copyright (C) 2012-2013 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free
|
||||||
|
Software Foundation; either version 3, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GCC; see the file COPYING3. If not see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
/* This file defines flags that may appear on basic blocks or on
|
||||||
|
edges. Source files define DEF_BASIC_BLOCK_FLAG or DEF_EDGE_FLAG
|
||||||
|
appropriately before including this file. */
|
||||||
|
|
||||||
|
#if !defined(DEF_BASIC_BLOCK_FLAG) && !defined(DEF_EDGE_FLAG)
|
||||||
|
#error "You must define DEF_BASIC_BLOCK_FLAG or DEF_EDGE_FLAG"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef DEF_BASIC_BLOCK_FLAG
|
||||||
|
|
||||||
|
/* Masks for basic_block.flags.
|
||||||
|
|
||||||
|
The format of this file is: DEF_BASIC_BLOCK_FLAG(NAME, IDX).
|
||||||
|
NAME is the name of the basic block flag. A flag BB_#NAME will be
|
||||||
|
created and the name is used in dump_edge_info.
|
||||||
|
IDX is a sequence number that is used to determine the value
|
||||||
|
of the flag, which is 1 << IDX).
|
||||||
|
|
||||||
|
BB_HOT_PARTITION and BB_COLD_PARTITION should be preserved throughout
|
||||||
|
the compilation, so they are never cleared.
|
||||||
|
|
||||||
|
All other flags may be cleared by clear_bb_flags(). It is generally
|
||||||
|
a bad idea to rely on any flags being up-to-date. */
|
||||||
|
|
||||||
|
/* Only set on blocks that have just been created by create_bb. */
|
||||||
|
DEF_BASIC_BLOCK_FLAG(NEW, 0)
|
||||||
|
|
||||||
|
/* Set by find_unreachable_blocks. Do not rely on this being set in any
|
||||||
|
pass. */
|
||||||
|
DEF_BASIC_BLOCK_FLAG(REACHABLE, 1)
|
||||||
|
|
||||||
|
/* Set for blocks in an irreducible loop by loop analysis. */
|
||||||
|
DEF_BASIC_BLOCK_FLAG(IRREDUCIBLE_LOOP, 2)
|
||||||
|
|
||||||
|
/* Set on blocks that may actually not be single-entry single-exit block. */
|
||||||
|
DEF_BASIC_BLOCK_FLAG(SUPERBLOCK, 3)
|
||||||
|
|
||||||
|
/* Set on basic blocks that the scheduler should not touch. This is used
|
||||||
|
by SMS to prevent other schedulers from messing with the loop schedule. */
|
||||||
|
DEF_BASIC_BLOCK_FLAG(DISABLE_SCHEDULE, 4)
|
||||||
|
|
||||||
|
/* Set on blocks that should be put in a hot section. */
|
||||||
|
DEF_BASIC_BLOCK_FLAG(HOT_PARTITION, 5)
|
||||||
|
|
||||||
|
/* Set on blocks that should be put in a cold section. */
|
||||||
|
DEF_BASIC_BLOCK_FLAG(COLD_PARTITION, 6)
|
||||||
|
|
||||||
|
/* Set on block that was duplicated. */
|
||||||
|
DEF_BASIC_BLOCK_FLAG(DUPLICATED, 7)
|
||||||
|
|
||||||
|
/* Set if the label at the top of this block is the target of a non-local goto. */
|
||||||
|
DEF_BASIC_BLOCK_FLAG(NON_LOCAL_GOTO_TARGET, 8)
|
||||||
|
|
||||||
|
/* Set on blocks that are in RTL format. */
|
||||||
|
DEF_BASIC_BLOCK_FLAG(RTL, 9)
|
||||||
|
|
||||||
|
/* Set on blocks that are forwarder blocks.
|
||||||
|
Only used in cfgcleanup.c. */
|
||||||
|
DEF_BASIC_BLOCK_FLAG(FORWARDER_BLOCK, 10)
|
||||||
|
|
||||||
|
/* Set on blocks that cannot be threaded through.
|
||||||
|
Only used in cfgcleanup.c. */
|
||||||
|
DEF_BASIC_BLOCK_FLAG(NONTHREADABLE_BLOCK, 11)
|
||||||
|
|
||||||
|
/* Set on blocks that were modified in some way. This bit is set in
|
||||||
|
df_set_bb_dirty, but not cleared by df_analyze, so it can be used
|
||||||
|
to test whether a block has been modified prior to a df_analyze call. */
|
||||||
|
DEF_BASIC_BLOCK_FLAG(MODIFIED, 12)
|
||||||
|
|
||||||
|
/* A general visited flag for passes to use. */
|
||||||
|
DEF_BASIC_BLOCK_FLAG(VISITED, 13)
|
||||||
|
|
||||||
|
/* Set on blocks that are in a transaction. This is calculated on
|
||||||
|
demand, and is available after calling compute_transaction_bits(). */
|
||||||
|
DEF_BASIC_BLOCK_FLAG(IN_TRANSACTION, 14)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef DEF_EDGE_FLAG
|
||||||
|
|
||||||
|
/* Masks for edge.flags.
|
||||||
|
|
||||||
|
The format of this file is: DEF_EDGE_FLAG(NAME, IDX, STRING).
|
||||||
|
NAME is the name of the edge flag. A flag EDGE_#NAME will be
|
||||||
|
created and the name is used in dump_edge_info.
|
||||||
|
IDX is a sequence number that is used to determine the value
|
||||||
|
of the flag, which is 1 << IDX). */
|
||||||
|
|
||||||
|
/* 'Straight line' flow. In GIMPLE and in cfglayout mode, all normal
|
||||||
|
edges are fallthru edges. In cfgrtl mode, this flag really means
|
||||||
|
that control flow falls through to the next basic block in the line. */
|
||||||
|
DEF_EDGE_FLAG(FALLTHRU, 0)
|
||||||
|
|
||||||
|
/* Strange flow, like a computed jump or exception handling. Usually
|
||||||
|
this means that the edge cannot be split. */
|
||||||
|
DEF_EDGE_FLAG(ABNORMAL, 1)
|
||||||
|
|
||||||
|
/* Edge out of a basic block that ends with a CALL_INSN with abnormal
|
||||||
|
exit, like an exception or a non-local goto.
|
||||||
|
ABNORMAL_CALL edges also have ABNORMAL set.
|
||||||
|
This flag is only used for the RTL CFG. */
|
||||||
|
DEF_EDGE_FLAG(ABNORMAL_CALL, 2)
|
||||||
|
|
||||||
|
/* Exception edge. Exception handling edges represent possible control
|
||||||
|
transfers from a trapping instruction to an exception handler.
|
||||||
|
EH edges also have ABNORMAL set for the RTL CFG. */
|
||||||
|
DEF_EDGE_FLAG(EH, 3)
|
||||||
|
|
||||||
|
/* Never merge blocks via this edge. This is used for exception handling,
|
||||||
|
to prevent merging away edges to the post-landing-pad basic block.
|
||||||
|
This flag is only used for the RTL CFG. */
|
||||||
|
DEF_EDGE_FLAG(PRESERVE, 4)
|
||||||
|
|
||||||
|
/* Not a real edge. This is used to connect parts of the CFG that do
|
||||||
|
not halt, such as infinite loops and noreturn functions, to the
|
||||||
|
EXIT_BLOCK, so that traversing of the reverse CFG is possible. */
|
||||||
|
DEF_EDGE_FLAG(FAKE, 5)
|
||||||
|
|
||||||
|
/* A back edge, marked in a depth-first search of the CFG. Back edges
|
||||||
|
are hints that this edge may be part of a loop in the CFG. */
|
||||||
|
DEF_EDGE_FLAG(DFS_BACK, 6)
|
||||||
|
|
||||||
|
/* Edge in a part of the CFG that is an irreducible loop. */
|
||||||
|
DEF_EDGE_FLAG(IRREDUCIBLE_LOOP, 7)
|
||||||
|
|
||||||
|
/* Edge taken when controlling predicate is nonzero.
|
||||||
|
This is only used for the GIMPLE CFG. */
|
||||||
|
DEF_EDGE_FLAG(TRUE_VALUE, 8)
|
||||||
|
|
||||||
|
/* Edge taken when controlling predicate is zero.
|
||||||
|
This is only used for the GIMPLE CFG. */
|
||||||
|
DEF_EDGE_FLAG(FALSE_VALUE, 9)
|
||||||
|
|
||||||
|
/* Edge is executable. This is only used in GIMPLE SSA-CCP and VRP.
|
||||||
|
This is only used for the GIMPLE CFG. */
|
||||||
|
DEF_EDGE_FLAG(EXECUTABLE, 10)
|
||||||
|
|
||||||
|
/* Edge crosses between hot and cold sections, when we do partitioning.
|
||||||
|
This flag is only used for the RTL CFG. */
|
||||||
|
DEF_EDGE_FLAG(CROSSING, 11)
|
||||||
|
|
||||||
|
/* Edge from a sibcall CALL_INSN to exit.
|
||||||
|
SIBCALL edges also have ABNORMAL set.
|
||||||
|
This flag is only used for the RTL CFG. */
|
||||||
|
DEF_EDGE_FLAG(SIBCALL, 12)
|
||||||
|
|
||||||
|
/* Candidate for straight line flow. Only used in bb-reorder.c.
|
||||||
|
This flag is only used for the RTL CFG. */
|
||||||
|
DEF_EDGE_FLAG(CAN_FALLTHRU, 13)
|
||||||
|
|
||||||
|
/* Exit of a loop. This is only used in ifcvt.c.
|
||||||
|
This flag is only used for the RTL CFG. */
|
||||||
|
DEF_EDGE_FLAG(LOOP_EXIT, 14)
|
||||||
|
|
||||||
|
/* Uninstrumented edge out of a GIMPLE_TRANSACTION statement. */
|
||||||
|
DEF_EDGE_FLAG(TM_UNINSTRUMENTED, 15)
|
||||||
|
|
||||||
|
/* Abort (over) edge out of a GIMPLE_TRANSACTION statement. */
|
||||||
|
DEF_EDGE_FLAG(TM_ABORT, 16)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
Local variables:
|
||||||
|
mode:c
|
||||||
|
End:
|
||||||
|
*/
|
|
@ -0,0 +1,223 @@
|
||||||
|
/* Hooks for cfg representation specific functions.
|
||||||
|
Copyright (C) 2003-2013 Free Software Foundation, Inc.
|
||||||
|
Contributed by Sebastian Pop <s.pop@laposte.net>
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GCC; see the file COPYING3. If not see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
/* Only basic-block.h includes this. */
|
||||||
|
|
||||||
|
struct cfg_hooks
|
||||||
|
{
|
||||||
|
/* Name of the corresponding ir. */
|
||||||
|
const char *name;
|
||||||
|
|
||||||
|
/* Debugging. */
|
||||||
|
int (*verify_flow_info) (void);
|
||||||
|
void (*dump_bb) (FILE *, basic_block, int, int);
|
||||||
|
void (*dump_bb_for_graph) (pretty_printer *, basic_block);
|
||||||
|
|
||||||
|
/* Basic CFG manipulation. */
|
||||||
|
|
||||||
|
/* Return new basic block. */
|
||||||
|
basic_block (*create_basic_block) (void *head, void *end, basic_block after);
|
||||||
|
|
||||||
|
/* Redirect edge E to the given basic block B and update underlying program
|
||||||
|
representation. Returns edge representing redirected branch (that may not
|
||||||
|
be equivalent to E in the case of duplicate edges being removed) or NULL
|
||||||
|
if edge is not easily redirectable for whatever reason. */
|
||||||
|
edge (*redirect_edge_and_branch) (edge e, basic_block b);
|
||||||
|
|
||||||
|
/* Same as the above but allows redirecting of fallthru edges. In that case
|
||||||
|
newly created forwarder basic block is returned. The edge must
|
||||||
|
not be abnormal. */
|
||||||
|
basic_block (*redirect_edge_and_branch_force) (edge, basic_block);
|
||||||
|
|
||||||
|
/* Returns true if it is possible to remove the edge by redirecting it
|
||||||
|
to the destination of the other edge going from its source. */
|
||||||
|
bool (*can_remove_branch_p) (const_edge);
|
||||||
|
|
||||||
|
/* Remove statements corresponding to a given basic block. */
|
||||||
|
void (*delete_basic_block) (basic_block);
|
||||||
|
|
||||||
|
/* Creates a new basic block just after basic block B by splitting
|
||||||
|
everything after specified instruction I. */
|
||||||
|
basic_block (*split_block) (basic_block b, void * i);
|
||||||
|
|
||||||
|
/* Move block B immediately after block A. */
|
||||||
|
bool (*move_block_after) (basic_block b, basic_block a);
|
||||||
|
|
||||||
|
/* Return true when blocks A and B can be merged into single basic block. */
|
||||||
|
bool (*can_merge_blocks_p) (basic_block a, basic_block b);
|
||||||
|
|
||||||
|
/* Merge blocks A and B. */
|
||||||
|
void (*merge_blocks) (basic_block a, basic_block b);
|
||||||
|
|
||||||
|
/* Predict edge E using PREDICTOR to given PROBABILITY. */
|
||||||
|
void (*predict_edge) (edge e, enum br_predictor predictor, int probability);
|
||||||
|
|
||||||
|
/* Return true if the one of outgoing edges is already predicted by
|
||||||
|
PREDICTOR. */
|
||||||
|
bool (*predicted_by_p) (const_basic_block bb, enum br_predictor predictor);
|
||||||
|
|
||||||
|
/* Return true when block A can be duplicated. */
|
||||||
|
bool (*can_duplicate_block_p) (const_basic_block a);
|
||||||
|
|
||||||
|
/* Duplicate block A. */
|
||||||
|
basic_block (*duplicate_block) (basic_block a);
|
||||||
|
|
||||||
|
/* Higher level functions representable by primitive operations above if
|
||||||
|
we didn't have some oddities in RTL and Tree representations. */
|
||||||
|
basic_block (*split_edge) (edge);
|
||||||
|
void (*make_forwarder_block) (edge);
|
||||||
|
|
||||||
|
/* Try to make the edge fallthru. */
|
||||||
|
void (*tidy_fallthru_edge) (edge);
|
||||||
|
|
||||||
|
/* Make the edge non-fallthru. */
|
||||||
|
basic_block (*force_nonfallthru) (edge);
|
||||||
|
|
||||||
|
/* Say whether a block ends with a call, possibly followed by some
|
||||||
|
other code that must stay with the call. */
|
||||||
|
bool (*block_ends_with_call_p) (basic_block);
|
||||||
|
|
||||||
|
/* Say whether a block ends with a conditional branch. Switches
|
||||||
|
and unconditional branches do not qualify. */
|
||||||
|
bool (*block_ends_with_condjump_p) (const_basic_block);
|
||||||
|
|
||||||
|
/* Add fake edges to the function exit for any non constant and non noreturn
|
||||||
|
calls, volatile inline assembly in the bitmap of blocks specified by
|
||||||
|
BLOCKS or to the whole CFG if BLOCKS is zero. Return the number of blocks
|
||||||
|
that were split.
|
||||||
|
|
||||||
|
The goal is to expose cases in which entering a basic block does not imply
|
||||||
|
that all subsequent instructions must be executed. */
|
||||||
|
int (*flow_call_edges_add) (sbitmap);
|
||||||
|
|
||||||
|
/* This function is called immediately after edge E is added to the
|
||||||
|
edge vector E->dest->preds. */
|
||||||
|
void (*execute_on_growing_pred) (edge);
|
||||||
|
|
||||||
|
/* This function is called immediately before edge E is removed from
|
||||||
|
the edge vector E->dest->preds. */
|
||||||
|
void (*execute_on_shrinking_pred) (edge);
|
||||||
|
|
||||||
|
/* A hook for duplicating loop in CFG, currently this is used
|
||||||
|
in loop versioning. */
|
||||||
|
bool (*cfg_hook_duplicate_loop_to_header_edge) (struct loop *, edge,
|
||||||
|
unsigned, sbitmap,
|
||||||
|
edge, vec<edge> *,
|
||||||
|
int);
|
||||||
|
|
||||||
|
/* Add condition to new basic block and update CFG used in loop
|
||||||
|
versioning. */
|
||||||
|
void (*lv_add_condition_to_bb) (basic_block, basic_block, basic_block,
|
||||||
|
void *);
|
||||||
|
/* Update the PHI nodes in case of loop versioning. */
|
||||||
|
void (*lv_adjust_loop_header_phi) (basic_block, basic_block,
|
||||||
|
basic_block, edge);
|
||||||
|
|
||||||
|
/* Given a condition BB extract the true/false taken/not taken edges
|
||||||
|
(depending if we are on tree's or RTL). */
|
||||||
|
void (*extract_cond_bb_edges) (basic_block, edge *, edge *);
|
||||||
|
|
||||||
|
|
||||||
|
/* Add PHI arguments queued in PENDINT_STMT list on edge E to edge
|
||||||
|
E->dest (only in tree-ssa loop versioning. */
|
||||||
|
void (*flush_pending_stmts) (edge);
|
||||||
|
|
||||||
|
/* True if a block contains no executable instructions. */
|
||||||
|
bool (*empty_block_p) (basic_block);
|
||||||
|
|
||||||
|
/* Split a basic block if it ends with a conditional branch and if
|
||||||
|
the other part of the block is not empty. */
|
||||||
|
basic_block (*split_block_before_cond_jump) (basic_block);
|
||||||
|
|
||||||
|
/* Do book-keeping of a basic block for the profile consistency checker. */
|
||||||
|
void (*account_profile_record) (basic_block, int, struct profile_record *);
|
||||||
|
};
|
||||||
|
|
||||||
|
extern void verify_flow_info (void);
|
||||||
|
extern void dump_bb (FILE *, basic_block, int, int);
|
||||||
|
extern void dump_bb_for_graph (pretty_printer *, basic_block);
|
||||||
|
|
||||||
|
extern edge redirect_edge_and_branch (edge, basic_block);
|
||||||
|
extern basic_block redirect_edge_and_branch_force (edge, basic_block);
|
||||||
|
extern bool can_remove_branch_p (const_edge);
|
||||||
|
extern void remove_branch (edge);
|
||||||
|
extern void remove_edge (edge);
|
||||||
|
extern edge split_block (basic_block, void *);
|
||||||
|
extern edge split_block_after_labels (basic_block);
|
||||||
|
extern bool move_block_after (basic_block, basic_block);
|
||||||
|
extern void delete_basic_block (basic_block);
|
||||||
|
extern basic_block split_edge (edge);
|
||||||
|
extern basic_block create_basic_block (void *, void *, basic_block);
|
||||||
|
extern basic_block create_empty_bb (basic_block);
|
||||||
|
extern bool can_merge_blocks_p (basic_block, basic_block);
|
||||||
|
extern void merge_blocks (basic_block, basic_block);
|
||||||
|
extern edge make_forwarder_block (basic_block, bool (*)(edge),
|
||||||
|
void (*) (basic_block));
|
||||||
|
extern basic_block force_nonfallthru (edge);
|
||||||
|
extern void tidy_fallthru_edge (edge);
|
||||||
|
extern void tidy_fallthru_edges (void);
|
||||||
|
extern void predict_edge (edge e, enum br_predictor predictor, int probability);
|
||||||
|
extern bool predicted_by_p (const_basic_block bb, enum br_predictor predictor);
|
||||||
|
extern bool can_duplicate_block_p (const_basic_block);
|
||||||
|
extern basic_block duplicate_block (basic_block, edge, basic_block);
|
||||||
|
extern bool block_ends_with_call_p (basic_block bb);
|
||||||
|
extern bool empty_block_p (basic_block);
|
||||||
|
extern basic_block split_block_before_cond_jump (basic_block);
|
||||||
|
extern bool block_ends_with_condjump_p (const_basic_block bb);
|
||||||
|
extern int flow_call_edges_add (sbitmap);
|
||||||
|
extern void execute_on_growing_pred (edge);
|
||||||
|
extern void execute_on_shrinking_pred (edge);
|
||||||
|
extern bool cfg_hook_duplicate_loop_to_header_edge (struct loop *loop, edge,
|
||||||
|
unsigned int ndupl,
|
||||||
|
sbitmap wont_exit,
|
||||||
|
edge orig,
|
||||||
|
vec<edge> *to_remove,
|
||||||
|
int flags);
|
||||||
|
|
||||||
|
extern void lv_flush_pending_stmts (edge);
|
||||||
|
extern void extract_cond_bb_edges (basic_block, edge *, edge*);
|
||||||
|
extern void lv_adjust_loop_header_phi (basic_block, basic_block, basic_block,
|
||||||
|
edge);
|
||||||
|
extern void lv_add_condition_to_bb (basic_block, basic_block, basic_block,
|
||||||
|
void *);
|
||||||
|
|
||||||
|
extern bool can_copy_bbs_p (basic_block *, unsigned);
|
||||||
|
extern void copy_bbs (basic_block *, unsigned, basic_block *,
|
||||||
|
edge *, unsigned, edge *, struct loop *,
|
||||||
|
basic_block);
|
||||||
|
|
||||||
|
void account_profile_record (struct profile_record *, int);
|
||||||
|
|
||||||
|
extern void cfg_layout_initialize (unsigned int);
|
||||||
|
extern void cfg_layout_finalize (void);
|
||||||
|
|
||||||
|
/* Hooks containers. */
|
||||||
|
extern struct cfg_hooks gimple_cfg_hooks;
|
||||||
|
extern struct cfg_hooks rtl_cfg_hooks;
|
||||||
|
extern struct cfg_hooks cfg_layout_rtl_cfg_hooks;
|
||||||
|
|
||||||
|
/* Declarations. */
|
||||||
|
extern enum ir_type current_ir_type (void);
|
||||||
|
extern void rtl_register_cfg_hooks (void);
|
||||||
|
extern void cfg_layout_rtl_register_cfg_hooks (void);
|
||||||
|
extern void gimple_register_cfg_hooks (void);
|
||||||
|
extern struct cfg_hooks get_cfg_hooks (void);
|
||||||
|
extern void set_cfg_hooks (struct cfg_hooks);
|
||||||
|
|
|
@ -0,0 +1,733 @@
|
||||||
|
/* Natural loop functions
|
||||||
|
Copyright (C) 1987-2013 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free
|
||||||
|
Software Foundation; either version 3, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GCC; see the file COPYING3. If not see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#ifndef GCC_CFGLOOP_H
|
||||||
|
#define GCC_CFGLOOP_H
|
||||||
|
|
||||||
|
#include "basic-block.h"
|
||||||
|
#include "double-int.h"
|
||||||
|
|
||||||
|
#include "bitmap.h"
|
||||||
|
#include "sbitmap.h"
|
||||||
|
|
||||||
|
/* Structure to hold decision about unrolling/peeling. */
|
||||||
|
enum lpt_dec
|
||||||
|
{
|
||||||
|
LPT_NONE,
|
||||||
|
LPT_PEEL_COMPLETELY,
|
||||||
|
LPT_PEEL_SIMPLE,
|
||||||
|
LPT_UNROLL_CONSTANT,
|
||||||
|
LPT_UNROLL_RUNTIME,
|
||||||
|
LPT_UNROLL_STUPID
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GTY (()) lpt_decision {
|
||||||
|
enum lpt_dec decision;
|
||||||
|
unsigned times;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* The type of extend applied to an IV. */
|
||||||
|
enum iv_extend_code
|
||||||
|
{
|
||||||
|
IV_SIGN_EXTEND,
|
||||||
|
IV_ZERO_EXTEND,
|
||||||
|
IV_UNKNOWN_EXTEND
|
||||||
|
};
|
||||||
|
|
||||||
|
/* The structure describing a bound on number of iterations of a loop. */
|
||||||
|
|
||||||
|
struct GTY ((chain_next ("%h.next"))) nb_iter_bound {
|
||||||
|
/* The statement STMT is executed at most ... */
|
||||||
|
gimple stmt;
|
||||||
|
|
||||||
|
/* ... BOUND + 1 times (BOUND must be an unsigned constant).
|
||||||
|
The + 1 is added for the following reasons:
|
||||||
|
|
||||||
|
a) 0 would otherwise be unused, while we would need to care more about
|
||||||
|
overflows (as MAX + 1 is sometimes produced as the estimate on number
|
||||||
|
of executions of STMT).
|
||||||
|
b) it is consistent with the result of number_of_iterations_exit. */
|
||||||
|
double_int bound;
|
||||||
|
|
||||||
|
/* True if the statement will cause the loop to be leaved the (at most)
|
||||||
|
BOUND + 1-st time it is executed, that is, all the statements after it
|
||||||
|
are executed at most BOUND times. */
|
||||||
|
bool is_exit;
|
||||||
|
|
||||||
|
/* The next bound in the list. */
|
||||||
|
struct nb_iter_bound *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Description of the loop exit. */
|
||||||
|
|
||||||
|
struct GTY (()) loop_exit {
|
||||||
|
/* The exit edge. */
|
||||||
|
edge e;
|
||||||
|
|
||||||
|
/* Previous and next exit in the list of the exits of the loop. */
|
||||||
|
struct loop_exit *prev;
|
||||||
|
struct loop_exit *next;
|
||||||
|
|
||||||
|
/* Next element in the list of loops from that E exits. */
|
||||||
|
struct loop_exit *next_e;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct loop *loop_p;
|
||||||
|
|
||||||
|
/* An integer estimation of the number of iterations. Estimate_state
|
||||||
|
describes what is the state of the estimation. */
|
||||||
|
enum loop_estimation
|
||||||
|
{
|
||||||
|
/* Estimate was not computed yet. */
|
||||||
|
EST_NOT_COMPUTED,
|
||||||
|
/* Estimate is ready. */
|
||||||
|
EST_AVAILABLE
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Structure to hold information for each natural loop. */
|
||||||
|
struct GTY ((chain_next ("%h.next"))) loop {
|
||||||
|
/* Index into loops array. */
|
||||||
|
int num;
|
||||||
|
|
||||||
|
/* Number of loop insns. */
|
||||||
|
unsigned ninsns;
|
||||||
|
|
||||||
|
/* Basic block of loop header. */
|
||||||
|
basic_block header;
|
||||||
|
|
||||||
|
/* Basic block of loop latch. */
|
||||||
|
basic_block latch;
|
||||||
|
|
||||||
|
/* For loop unrolling/peeling decision. */
|
||||||
|
struct lpt_decision lpt_decision;
|
||||||
|
|
||||||
|
/* Average number of executed insns per iteration. */
|
||||||
|
unsigned av_ninsns;
|
||||||
|
|
||||||
|
/* Number of blocks contained within the loop. */
|
||||||
|
unsigned num_nodes;
|
||||||
|
|
||||||
|
/* Superloops of the loop, starting with the outermost loop. */
|
||||||
|
vec<loop_p, va_gc> *superloops;
|
||||||
|
|
||||||
|
/* The first inner (child) loop or NULL if innermost loop. */
|
||||||
|
struct loop *inner;
|
||||||
|
|
||||||
|
/* Link to the next (sibling) loop. */
|
||||||
|
struct loop *next;
|
||||||
|
|
||||||
|
/* Auxiliary info specific to a pass. */
|
||||||
|
PTR GTY ((skip (""))) aux;
|
||||||
|
|
||||||
|
/* The number of times the latch of the loop is executed. This can be an
|
||||||
|
INTEGER_CST, or a symbolic expression representing the number of
|
||||||
|
iterations like "N - 1", or a COND_EXPR containing the runtime
|
||||||
|
conditions under which the number of iterations is non zero.
|
||||||
|
|
||||||
|
Don't access this field directly: number_of_latch_executions
|
||||||
|
computes and caches the computed information in this field. */
|
||||||
|
tree nb_iterations;
|
||||||
|
|
||||||
|
/* An integer guaranteed to be greater or equal to nb_iterations. Only
|
||||||
|
valid if any_upper_bound is true. */
|
||||||
|
double_int nb_iterations_upper_bound;
|
||||||
|
|
||||||
|
/* An integer giving an estimate on nb_iterations. Unlike
|
||||||
|
nb_iterations_upper_bound, there is no guarantee that it is at least
|
||||||
|
nb_iterations. */
|
||||||
|
double_int nb_iterations_estimate;
|
||||||
|
|
||||||
|
bool any_upper_bound;
|
||||||
|
bool any_estimate;
|
||||||
|
|
||||||
|
/* True if the loop can be parallel. */
|
||||||
|
bool can_be_parallel;
|
||||||
|
|
||||||
|
/* True if -Waggressive-loop-optimizations warned about this loop
|
||||||
|
already. */
|
||||||
|
bool warned_aggressive_loop_optimizations;
|
||||||
|
|
||||||
|
/* An integer estimation of the number of iterations. Estimate_state
|
||||||
|
describes what is the state of the estimation. */
|
||||||
|
enum loop_estimation estimate_state;
|
||||||
|
|
||||||
|
/* Upper bound on number of iterations of a loop. */
|
||||||
|
struct nb_iter_bound *bounds;
|
||||||
|
|
||||||
|
/* Head of the cyclic list of the exits of the loop. */
|
||||||
|
struct loop_exit *exits;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Flags for state of loop structure. */
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
LOOPS_HAVE_PREHEADERS = 1,
|
||||||
|
LOOPS_HAVE_SIMPLE_LATCHES = 2,
|
||||||
|
LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS = 4,
|
||||||
|
LOOPS_HAVE_RECORDED_EXITS = 8,
|
||||||
|
LOOPS_MAY_HAVE_MULTIPLE_LATCHES = 16,
|
||||||
|
LOOP_CLOSED_SSA = 32,
|
||||||
|
LOOPS_NEED_FIXUP = 64,
|
||||||
|
LOOPS_HAVE_FALLTHRU_PREHEADERS = 128
|
||||||
|
};
|
||||||
|
|
||||||
|
#define LOOPS_NORMAL (LOOPS_HAVE_PREHEADERS | LOOPS_HAVE_SIMPLE_LATCHES \
|
||||||
|
| LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS)
|
||||||
|
#define AVOID_CFG_MODIFICATIONS (LOOPS_MAY_HAVE_MULTIPLE_LATCHES)
|
||||||
|
|
||||||
|
/* Structure to hold CFG information about natural loops within a function. */
|
||||||
|
struct GTY (()) loops {
|
||||||
|
/* State of loops. */
|
||||||
|
int state;
|
||||||
|
|
||||||
|
/* Array of the loops. */
|
||||||
|
vec<loop_p, va_gc> *larray;
|
||||||
|
|
||||||
|
/* Maps edges to the list of their descriptions as loop exits. Edges
|
||||||
|
whose sources or destinations have loop_father == NULL (which may
|
||||||
|
happen during the cfg manipulations) should not appear in EXITS. */
|
||||||
|
htab_t GTY((param_is (struct loop_exit))) exits;
|
||||||
|
|
||||||
|
/* Pointer to root of loop hierarchy tree. */
|
||||||
|
struct loop *tree_root;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Loop recognition. */
|
||||||
|
bool bb_loop_header_p (basic_block);
|
||||||
|
extern struct loops *flow_loops_find (struct loops *);
|
||||||
|
extern void disambiguate_loops_with_multiple_latches (void);
|
||||||
|
extern void flow_loops_free (struct loops *);
|
||||||
|
extern void flow_loops_dump (FILE *,
|
||||||
|
void (*)(const struct loop *, FILE *, int), int);
|
||||||
|
extern void flow_loop_dump (const struct loop *, FILE *,
|
||||||
|
void (*)(const struct loop *, FILE *, int), int);
|
||||||
|
struct loop *alloc_loop (void);
|
||||||
|
extern void flow_loop_free (struct loop *);
|
||||||
|
int flow_loop_nodes_find (basic_block, struct loop *);
|
||||||
|
unsigned fix_loop_structure (bitmap changed_bbs);
|
||||||
|
bool mark_irreducible_loops (void);
|
||||||
|
void release_recorded_exits (void);
|
||||||
|
void record_loop_exits (void);
|
||||||
|
void rescan_loop_exit (edge, bool, bool);
|
||||||
|
|
||||||
|
/* Loop data structure manipulation/querying. */
|
||||||
|
extern void flow_loop_tree_node_add (struct loop *, struct loop *);
|
||||||
|
extern void flow_loop_tree_node_remove (struct loop *);
|
||||||
|
extern void add_loop (struct loop *, struct loop *);
|
||||||
|
extern bool flow_loop_nested_p (const struct loop *, const struct loop *);
|
||||||
|
extern bool flow_bb_inside_loop_p (const struct loop *, const_basic_block);
|
||||||
|
extern struct loop * find_common_loop (struct loop *, struct loop *);
|
||||||
|
struct loop *superloop_at_depth (struct loop *, unsigned);
|
||||||
|
struct eni_weights_d;
|
||||||
|
extern unsigned tree_num_loop_insns (struct loop *, struct eni_weights_d *);
|
||||||
|
extern int num_loop_insns (const struct loop *);
|
||||||
|
extern int average_num_loop_insns (const struct loop *);
|
||||||
|
extern unsigned get_loop_level (const struct loop *);
|
||||||
|
extern bool loop_exit_edge_p (const struct loop *, const_edge);
|
||||||
|
extern bool loop_exits_to_bb_p (struct loop *, basic_block);
|
||||||
|
extern bool loop_exits_from_bb_p (struct loop *, basic_block);
|
||||||
|
extern void mark_loop_exit_edges (void);
|
||||||
|
extern location_t get_loop_location (struct loop *loop);
|
||||||
|
|
||||||
|
/* Loops & cfg manipulation. */
|
||||||
|
extern basic_block *get_loop_body (const struct loop *);
|
||||||
|
extern unsigned get_loop_body_with_size (const struct loop *, basic_block *,
|
||||||
|
unsigned);
|
||||||
|
extern basic_block *get_loop_body_in_dom_order (const struct loop *);
|
||||||
|
extern basic_block *get_loop_body_in_bfs_order (const struct loop *);
|
||||||
|
extern basic_block *get_loop_body_in_custom_order (const struct loop *,
|
||||||
|
int (*) (const void *, const void *));
|
||||||
|
|
||||||
|
extern vec<edge> get_loop_exit_edges (const struct loop *);
|
||||||
|
extern edge single_exit (const struct loop *);
|
||||||
|
extern edge single_likely_exit (struct loop *loop);
|
||||||
|
extern unsigned num_loop_branches (const struct loop *);
|
||||||
|
|
||||||
|
extern edge loop_preheader_edge (const struct loop *);
|
||||||
|
extern edge loop_latch_edge (const struct loop *);
|
||||||
|
|
||||||
|
extern void add_bb_to_loop (basic_block, struct loop *);
|
||||||
|
extern void remove_bb_from_loops (basic_block);
|
||||||
|
|
||||||
|
extern void cancel_loop_tree (struct loop *);
|
||||||
|
extern void delete_loop (struct loop *);
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
CP_SIMPLE_PREHEADERS = 1,
|
||||||
|
CP_FALLTHRU_PREHEADERS = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
basic_block create_preheader (struct loop *, int);
|
||||||
|
extern void create_preheaders (int);
|
||||||
|
extern void force_single_succ_latches (void);
|
||||||
|
|
||||||
|
extern void verify_loop_structure (void);
|
||||||
|
|
||||||
|
/* Loop analysis. */
|
||||||
|
extern bool just_once_each_iteration_p (const struct loop *, const_basic_block);
|
||||||
|
gcov_type expected_loop_iterations_unbounded (const struct loop *);
|
||||||
|
extern unsigned expected_loop_iterations (const struct loop *);
|
||||||
|
extern rtx doloop_condition_get (rtx);
|
||||||
|
|
||||||
|
void estimate_numbers_of_iterations_loop (struct loop *);
|
||||||
|
void record_niter_bound (struct loop *, double_int, bool, bool);
|
||||||
|
bool estimated_loop_iterations (struct loop *, double_int *);
|
||||||
|
bool max_loop_iterations (struct loop *, double_int *);
|
||||||
|
HOST_WIDE_INT estimated_loop_iterations_int (struct loop *);
|
||||||
|
HOST_WIDE_INT max_loop_iterations_int (struct loop *);
|
||||||
|
bool max_stmt_executions (struct loop *, double_int *);
|
||||||
|
bool estimated_stmt_executions (struct loop *, double_int *);
|
||||||
|
HOST_WIDE_INT max_stmt_executions_int (struct loop *);
|
||||||
|
HOST_WIDE_INT estimated_stmt_executions_int (struct loop *);
|
||||||
|
|
||||||
|
/* Loop manipulation. */
|
||||||
|
extern bool can_duplicate_loop_p (const struct loop *loop);
|
||||||
|
|
||||||
|
#define DLTHE_FLAG_UPDATE_FREQ 1 /* Update frequencies in
|
||||||
|
duplicate_loop_to_header_edge. */
|
||||||
|
#define DLTHE_RECORD_COPY_NUMBER 2 /* Record copy number in the aux
|
||||||
|
field of newly create BB. */
|
||||||
|
#define DLTHE_FLAG_COMPLETTE_PEEL 4 /* Update frequencies expecting
|
||||||
|
a complete peeling. */
|
||||||
|
|
||||||
|
extern edge create_empty_if_region_on_edge (edge, tree);
|
||||||
|
extern struct loop *create_empty_loop_on_edge (edge, tree, tree, tree, tree,
|
||||||
|
tree *, tree *, struct loop *);
|
||||||
|
extern struct loop * duplicate_loop (struct loop *, struct loop *);
|
||||||
|
extern void copy_loop_info (struct loop *loop, struct loop *target);
|
||||||
|
extern void duplicate_subloops (struct loop *, struct loop *);
|
||||||
|
extern bool duplicate_loop_to_header_edge (struct loop *, edge,
|
||||||
|
unsigned, sbitmap, edge,
|
||||||
|
vec<edge> *, int);
|
||||||
|
extern struct loop *loopify (edge, edge,
|
||||||
|
basic_block, edge, edge, bool,
|
||||||
|
unsigned, unsigned);
|
||||||
|
struct loop * loop_version (struct loop *, void *,
|
||||||
|
basic_block *, unsigned, unsigned, unsigned, bool);
|
||||||
|
extern bool remove_path (edge);
|
||||||
|
extern void unloop (struct loop *, bool *, bitmap);
|
||||||
|
extern void scale_loop_frequencies (struct loop *, int, int);
|
||||||
|
|
||||||
|
/* Induction variable analysis. */
|
||||||
|
|
||||||
|
/* The description of induction variable. The things are a bit complicated
|
||||||
|
due to need to handle subregs and extends. The value of the object described
|
||||||
|
by it can be obtained as follows (all computations are done in extend_mode):
|
||||||
|
|
||||||
|
Value in i-th iteration is
|
||||||
|
delta + mult * extend_{extend_mode} (subreg_{mode} (base + i * step)).
|
||||||
|
|
||||||
|
If first_special is true, the value in the first iteration is
|
||||||
|
delta + mult * base
|
||||||
|
|
||||||
|
If extend = UNKNOWN, first_special must be false, delta 0, mult 1 and value is
|
||||||
|
subreg_{mode} (base + i * step)
|
||||||
|
|
||||||
|
The get_iv_value function can be used to obtain these expressions.
|
||||||
|
|
||||||
|
??? Add a third mode field that would specify the mode in that inner
|
||||||
|
computation is done, which would enable it to be different from the
|
||||||
|
outer one? */
|
||||||
|
|
||||||
|
struct rtx_iv
|
||||||
|
{
|
||||||
|
/* Its base and step (mode of base and step is supposed to be extend_mode,
|
||||||
|
see the description above). */
|
||||||
|
rtx base, step;
|
||||||
|
|
||||||
|
/* The type of extend applied to it (IV_SIGN_EXTEND, IV_ZERO_EXTEND,
|
||||||
|
or IV_UNKNOWN_EXTEND). */
|
||||||
|
enum iv_extend_code extend;
|
||||||
|
|
||||||
|
/* Operations applied in the extended mode. */
|
||||||
|
rtx delta, mult;
|
||||||
|
|
||||||
|
/* The mode it is extended to. */
|
||||||
|
enum machine_mode extend_mode;
|
||||||
|
|
||||||
|
/* The mode the variable iterates in. */
|
||||||
|
enum machine_mode mode;
|
||||||
|
|
||||||
|
/* Whether the first iteration needs to be handled specially. */
|
||||||
|
unsigned first_special : 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* The description of an exit from the loop and of the number of iterations
|
||||||
|
till we take the exit. */
|
||||||
|
|
||||||
|
struct niter_desc
|
||||||
|
{
|
||||||
|
/* The edge out of the loop. */
|
||||||
|
edge out_edge;
|
||||||
|
|
||||||
|
/* The other edge leading from the condition. */
|
||||||
|
edge in_edge;
|
||||||
|
|
||||||
|
/* True if we are able to say anything about number of iterations of the
|
||||||
|
loop. */
|
||||||
|
bool simple_p;
|
||||||
|
|
||||||
|
/* True if the loop iterates the constant number of times. */
|
||||||
|
bool const_iter;
|
||||||
|
|
||||||
|
/* Number of iterations if constant. */
|
||||||
|
unsigned HOST_WIDEST_INT niter;
|
||||||
|
|
||||||
|
/* Assumptions under that the rest of the information is valid. */
|
||||||
|
rtx assumptions;
|
||||||
|
|
||||||
|
/* Assumptions under that the loop ends before reaching the latch,
|
||||||
|
even if value of niter_expr says otherwise. */
|
||||||
|
rtx noloop_assumptions;
|
||||||
|
|
||||||
|
/* Condition under that the loop is infinite. */
|
||||||
|
rtx infinite;
|
||||||
|
|
||||||
|
/* Whether the comparison is signed. */
|
||||||
|
bool signed_p;
|
||||||
|
|
||||||
|
/* The mode in that niter_expr should be computed. */
|
||||||
|
enum machine_mode mode;
|
||||||
|
|
||||||
|
/* The number of iterations of the loop. */
|
||||||
|
rtx niter_expr;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern void iv_analysis_loop_init (struct loop *);
|
||||||
|
extern bool iv_analyze (rtx, rtx, struct rtx_iv *);
|
||||||
|
extern bool iv_analyze_result (rtx, rtx, struct rtx_iv *);
|
||||||
|
extern bool iv_analyze_expr (rtx, rtx, enum machine_mode, struct rtx_iv *);
|
||||||
|
extern rtx get_iv_value (struct rtx_iv *, rtx);
|
||||||
|
extern bool biv_p (rtx, rtx);
|
||||||
|
extern void find_simple_exit (struct loop *, struct niter_desc *);
|
||||||
|
extern void iv_analysis_done (void);
|
||||||
|
|
||||||
|
extern struct niter_desc *get_simple_loop_desc (struct loop *loop);
|
||||||
|
extern void free_simple_loop_desc (struct loop *loop);
|
||||||
|
|
||||||
|
static inline struct niter_desc *
|
||||||
|
simple_loop_desc (struct loop *loop)
|
||||||
|
{
|
||||||
|
return (struct niter_desc *) loop->aux;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Accessors for the loop structures. */
|
||||||
|
|
||||||
|
/* Returns the loop with index NUM from current_loops. */
|
||||||
|
|
||||||
|
static inline struct loop *
|
||||||
|
get_loop (unsigned num)
|
||||||
|
{
|
||||||
|
return (*current_loops->larray)[num];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns the number of superloops of LOOP. */
|
||||||
|
|
||||||
|
static inline unsigned
|
||||||
|
loop_depth (const struct loop *loop)
|
||||||
|
{
|
||||||
|
return vec_safe_length (loop->superloops);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns the loop depth of the loop BB belongs to. */
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
bb_loop_depth (const_basic_block bb)
|
||||||
|
{
|
||||||
|
return bb->loop_father ? loop_depth (bb->loop_father) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns the immediate superloop of LOOP, or NULL if LOOP is the outermost
|
||||||
|
loop. */
|
||||||
|
|
||||||
|
static inline struct loop *
|
||||||
|
loop_outer (const struct loop *loop)
|
||||||
|
{
|
||||||
|
unsigned n = vec_safe_length (loop->superloops);
|
||||||
|
|
||||||
|
if (n == 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return (*loop->superloops)[n - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns true if LOOP has at least one exit edge. */
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
loop_has_exit_edges (const struct loop *loop)
|
||||||
|
{
|
||||||
|
return loop->exits->next->e != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns the list of loops in current_loops. */
|
||||||
|
|
||||||
|
static inline vec<loop_p, va_gc> *
|
||||||
|
get_loops (void)
|
||||||
|
{
|
||||||
|
if (!current_loops)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return current_loops->larray;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns the number of loops in current_loops (including the removed
|
||||||
|
ones and the fake loop that forms the root of the loop tree). */
|
||||||
|
|
||||||
|
static inline unsigned
|
||||||
|
number_of_loops (void)
|
||||||
|
{
|
||||||
|
if (!current_loops)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return vec_safe_length (current_loops->larray);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns true if state of the loops satisfies all properties
|
||||||
|
described by FLAGS. */
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
loops_state_satisfies_p (unsigned flags)
|
||||||
|
{
|
||||||
|
return (current_loops->state & flags) == flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Sets FLAGS to the loops state. */
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
loops_state_set (unsigned flags)
|
||||||
|
{
|
||||||
|
current_loops->state |= flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Clears FLAGS from the loops state. */
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
loops_state_clear (unsigned flags)
|
||||||
|
{
|
||||||
|
if (!current_loops)
|
||||||
|
return;
|
||||||
|
current_loops->state &= ~flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Loop iterators. */
|
||||||
|
|
||||||
|
/* Flags for loop iteration. */
|
||||||
|
|
||||||
|
enum li_flags
|
||||||
|
{
|
||||||
|
LI_INCLUDE_ROOT = 1, /* Include the fake root of the loop tree. */
|
||||||
|
LI_FROM_INNERMOST = 2, /* Iterate over the loops in the reverse order,
|
||||||
|
starting from innermost ones. */
|
||||||
|
LI_ONLY_INNERMOST = 4 /* Iterate only over innermost loops. */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* The iterator for loops. */
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
/* The list of loops to visit. */
|
||||||
|
vec<int> to_visit;
|
||||||
|
|
||||||
|
/* The index of the actual loop. */
|
||||||
|
unsigned idx;
|
||||||
|
} loop_iterator;
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
fel_next (loop_iterator *li, loop_p *loop)
|
||||||
|
{
|
||||||
|
int anum;
|
||||||
|
|
||||||
|
while (li->to_visit.iterate (li->idx, &anum))
|
||||||
|
{
|
||||||
|
li->idx++;
|
||||||
|
*loop = get_loop (anum);
|
||||||
|
if (*loop)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
li->to_visit.release ();
|
||||||
|
*loop = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
fel_init (loop_iterator *li, loop_p *loop, unsigned flags)
|
||||||
|
{
|
||||||
|
struct loop *aloop;
|
||||||
|
unsigned i;
|
||||||
|
int mn;
|
||||||
|
|
||||||
|
li->idx = 0;
|
||||||
|
if (!current_loops)
|
||||||
|
{
|
||||||
|
li->to_visit.create (0);
|
||||||
|
*loop = NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
li->to_visit.create (number_of_loops ());
|
||||||
|
mn = (flags & LI_INCLUDE_ROOT) ? 0 : 1;
|
||||||
|
|
||||||
|
if (flags & LI_ONLY_INNERMOST)
|
||||||
|
{
|
||||||
|
for (i = 0; vec_safe_iterate (current_loops->larray, i, &aloop); i++)
|
||||||
|
if (aloop != NULL
|
||||||
|
&& aloop->inner == NULL
|
||||||
|
&& aloop->num >= mn)
|
||||||
|
li->to_visit.quick_push (aloop->num);
|
||||||
|
}
|
||||||
|
else if (flags & LI_FROM_INNERMOST)
|
||||||
|
{
|
||||||
|
/* Push the loops to LI->TO_VISIT in postorder. */
|
||||||
|
for (aloop = current_loops->tree_root;
|
||||||
|
aloop->inner != NULL;
|
||||||
|
aloop = aloop->inner)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
if (aloop->num >= mn)
|
||||||
|
li->to_visit.quick_push (aloop->num);
|
||||||
|
|
||||||
|
if (aloop->next)
|
||||||
|
{
|
||||||
|
for (aloop = aloop->next;
|
||||||
|
aloop->inner != NULL;
|
||||||
|
aloop = aloop->inner)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (!loop_outer (aloop))
|
||||||
|
break;
|
||||||
|
else
|
||||||
|
aloop = loop_outer (aloop);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Push the loops to LI->TO_VISIT in preorder. */
|
||||||
|
aloop = current_loops->tree_root;
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
if (aloop->num >= mn)
|
||||||
|
li->to_visit.quick_push (aloop->num);
|
||||||
|
|
||||||
|
if (aloop->inner != NULL)
|
||||||
|
aloop = aloop->inner;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while (aloop != NULL && aloop->next == NULL)
|
||||||
|
aloop = loop_outer (aloop);
|
||||||
|
if (aloop == NULL)
|
||||||
|
break;
|
||||||
|
aloop = aloop->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fel_next (li, loop);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define FOR_EACH_LOOP(LI, LOOP, FLAGS) \
|
||||||
|
for (fel_init (&(LI), &(LOOP), FLAGS); \
|
||||||
|
(LOOP); \
|
||||||
|
fel_next (&(LI), &(LOOP)))
|
||||||
|
|
||||||
|
#define FOR_EACH_LOOP_BREAK(LI) \
|
||||||
|
{ \
|
||||||
|
(LI).to_visit.release (); \
|
||||||
|
break; \
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The properties of the target. */
|
||||||
|
struct target_cfgloop {
|
||||||
|
/* Number of available registers. */
|
||||||
|
unsigned x_target_avail_regs;
|
||||||
|
|
||||||
|
/* Number of available registers that are call-clobbered. */
|
||||||
|
unsigned x_target_clobbered_regs;
|
||||||
|
|
||||||
|
/* Number of registers reserved for temporary expressions. */
|
||||||
|
unsigned x_target_res_regs;
|
||||||
|
|
||||||
|
/* The cost for register when there still is some reserve, but we are
|
||||||
|
approaching the number of available registers. */
|
||||||
|
unsigned x_target_reg_cost[2];
|
||||||
|
|
||||||
|
/* The cost for register when we need to spill. */
|
||||||
|
unsigned x_target_spill_cost[2];
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct target_cfgloop default_target_cfgloop;
|
||||||
|
#if SWITCHABLE_TARGET
|
||||||
|
extern struct target_cfgloop *this_target_cfgloop;
|
||||||
|
#else
|
||||||
|
#define this_target_cfgloop (&default_target_cfgloop)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define target_avail_regs \
|
||||||
|
(this_target_cfgloop->x_target_avail_regs)
|
||||||
|
#define target_clobbered_regs \
|
||||||
|
(this_target_cfgloop->x_target_clobbered_regs)
|
||||||
|
#define target_res_regs \
|
||||||
|
(this_target_cfgloop->x_target_res_regs)
|
||||||
|
#define target_reg_cost \
|
||||||
|
(this_target_cfgloop->x_target_reg_cost)
|
||||||
|
#define target_spill_cost \
|
||||||
|
(this_target_cfgloop->x_target_spill_cost)
|
||||||
|
|
||||||
|
/* Register pressure estimation for induction variable optimizations & loop
|
||||||
|
invariant motion. */
|
||||||
|
extern unsigned estimate_reg_pressure_cost (unsigned, unsigned, bool, bool);
|
||||||
|
extern void init_set_costs (void);
|
||||||
|
|
||||||
|
/* Loop optimizer initialization. */
|
||||||
|
extern void loop_optimizer_init (unsigned);
|
||||||
|
extern void loop_optimizer_finalize (void);
|
||||||
|
|
||||||
|
/* Optimization passes. */
|
||||||
|
extern void unswitch_loops (void);
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
UAP_PEEL = 1, /* Enables loop peeling. */
|
||||||
|
UAP_UNROLL = 2, /* Enables unrolling of loops if it seems profitable. */
|
||||||
|
UAP_UNROLL_ALL = 4 /* Enables unrolling of all loops. */
|
||||||
|
};
|
||||||
|
|
||||||
|
extern void unroll_and_peel_loops (int);
|
||||||
|
extern void doloop_optimize_loops (void);
|
||||||
|
extern void move_loop_invariants (void);
|
||||||
|
extern bool finite_loop_p (struct loop *);
|
||||||
|
extern void scale_loop_profile (struct loop *loop, int scale, gcov_type iteration_bound);
|
||||||
|
extern vec<basic_block> get_loop_hot_path (const struct loop *loop);
|
||||||
|
|
||||||
|
/* Returns the outermost loop of the loop nest that contains LOOP.*/
|
||||||
|
static inline struct loop *
|
||||||
|
loop_outermost (struct loop *loop)
|
||||||
|
{
|
||||||
|
unsigned n = vec_safe_length (loop->superloops);
|
||||||
|
|
||||||
|
if (n <= 1)
|
||||||
|
return loop;
|
||||||
|
|
||||||
|
return (*loop->superloops)[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* GCC_CFGLOOP_H */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,105 @@
|
||||||
|
/* This file contains the definitions of the cgraph_inline_failed_t
|
||||||
|
enums used in GCC.
|
||||||
|
|
||||||
|
Copyright (C) 2008-2013 Free Software Foundation, Inc.
|
||||||
|
Contributed by Doug Kwan <dougkwan@google.com>
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free
|
||||||
|
Software Foundation either version 3, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GCC see the file COPYING3. If not see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
/* The format of this file is
|
||||||
|
DEFCIFCODE(code, string).
|
||||||
|
|
||||||
|
Where symbol is the enumeration name without the ``''.
|
||||||
|
The argument STRING is a explain the failure. Except for OK,
|
||||||
|
which is a NULL pointer. */
|
||||||
|
|
||||||
|
/* Inlining successful. This must be the first code. */
|
||||||
|
DEFCIFCODE(OK , NULL)
|
||||||
|
|
||||||
|
/* Inlining failed for an unspecified reason. */
|
||||||
|
DEFCIFCODE(UNSPECIFIED , "")
|
||||||
|
|
||||||
|
/* Function has not be considered for inlining. This is the code for
|
||||||
|
functions that have not been rejected for inlining yet. */
|
||||||
|
DEFCIFCODE(FUNCTION_NOT_CONSIDERED, N_("function not considered for inlining"))
|
||||||
|
|
||||||
|
/* Inlining failed owing to unavailable function body. */
|
||||||
|
DEFCIFCODE(BODY_NOT_AVAILABLE, N_("function body not available"))
|
||||||
|
|
||||||
|
/* Extern inline function that has been redefined. */
|
||||||
|
DEFCIFCODE(REDEFINED_EXTERN_INLINE,
|
||||||
|
N_("redefined extern inline functions are not considered for "
|
||||||
|
"inlining"))
|
||||||
|
|
||||||
|
/* Function is not inlinable. */
|
||||||
|
DEFCIFCODE(FUNCTION_NOT_INLINABLE, N_("function not inlinable"))
|
||||||
|
|
||||||
|
/* Function is not overwritable. */
|
||||||
|
DEFCIFCODE(OVERWRITABLE, N_("function body can be overwritten at link time"))
|
||||||
|
|
||||||
|
/* Function is not an inlining candidate. */
|
||||||
|
DEFCIFCODE(FUNCTION_NOT_INLINE_CANDIDATE, N_("function not inline candidate"))
|
||||||
|
|
||||||
|
/* Inlining failed because of various limit parameters. */
|
||||||
|
DEFCIFCODE(LARGE_FUNCTION_GROWTH_LIMIT,
|
||||||
|
N_("--param large-function-growth limit reached"))
|
||||||
|
DEFCIFCODE(LARGE_STACK_FRAME_GROWTH_LIMIT,
|
||||||
|
N_("--param large-stack-frame-growth limit reached"))
|
||||||
|
DEFCIFCODE(MAX_INLINE_INSNS_SINGLE_LIMIT,
|
||||||
|
N_("--param max-inline-insns-single limit reached"))
|
||||||
|
DEFCIFCODE(MAX_INLINE_INSNS_AUTO_LIMIT,
|
||||||
|
N_("--param max-inline-insns-auto limit reached"))
|
||||||
|
DEFCIFCODE(INLINE_UNIT_GROWTH_LIMIT,
|
||||||
|
N_("--param inline-unit-growth limit reached"))
|
||||||
|
|
||||||
|
/* Recursive inlining. */
|
||||||
|
DEFCIFCODE(RECURSIVE_INLINING, N_("recursive inlining"))
|
||||||
|
|
||||||
|
/* Call is unlikely. */
|
||||||
|
DEFCIFCODE(UNLIKELY_CALL, N_("call is unlikely and code size would grow"))
|
||||||
|
|
||||||
|
/* Function is not declared as inline. */
|
||||||
|
DEFCIFCODE(NOT_DECLARED_INLINED,
|
||||||
|
N_("function not declared inline and code size would grow"))
|
||||||
|
|
||||||
|
/* Inlining suppressed due to size optimization. */
|
||||||
|
DEFCIFCODE(OPTIMIZING_FOR_SIZE,
|
||||||
|
N_("optimizing for size and code size would grow"))
|
||||||
|
|
||||||
|
/* Caller and callee disagree on the arguments. */
|
||||||
|
DEFCIFCODE(MISMATCHED_ARGUMENTS, N_("mismatched arguments"))
|
||||||
|
|
||||||
|
/* Call was originally indirect. */
|
||||||
|
DEFCIFCODE(ORIGINALLY_INDIRECT_CALL,
|
||||||
|
N_("originally indirect function call not considered for inlining"))
|
||||||
|
|
||||||
|
/* Ths edge represents an indirect edge with a yet-undetermined callee . */
|
||||||
|
DEFCIFCODE(INDIRECT_UNKNOWN_CALL,
|
||||||
|
N_("indirect function call with a yet undetermined callee"))
|
||||||
|
|
||||||
|
/* We can't inline different EH personalities together. */
|
||||||
|
DEFCIFCODE(EH_PERSONALITY, N_("exception handling personality mismatch"))
|
||||||
|
|
||||||
|
/* We can't inline if the callee can throw non-call exceptions but the
|
||||||
|
caller cannot. */
|
||||||
|
DEFCIFCODE(NON_CALL_EXCEPTIONS, N_("non-call exception handling mismatch"))
|
||||||
|
|
||||||
|
/* We can't inline because of mismatched target specific options. */
|
||||||
|
DEFCIFCODE(TARGET_OPTION_MISMATCH, N_("target specific option mismatch"))
|
||||||
|
|
||||||
|
/* We can't inline because of mismatched optimization levels. */
|
||||||
|
DEFCIFCODE(OPTIMIZATION_MISMATCH, N_("optimization level attribute mismatch"))
|
|
@ -0,0 +1,10 @@
|
||||||
|
#ifndef GCC_CONFIG_H
|
||||||
|
#define GCC_CONFIG_H
|
||||||
|
#ifdef GENERATOR_FILE
|
||||||
|
#error config.h is for the host, not build, machine.
|
||||||
|
#endif
|
||||||
|
#include "auto-host.h"
|
||||||
|
#ifdef IN_GCC
|
||||||
|
# include "ansidecl.h"
|
||||||
|
#endif
|
||||||
|
#endif /* GCC_CONFIG_H */
|
|
@ -0,0 +1,68 @@
|
||||||
|
/* Definitions needed when using stabs embedded in ELF sections.
|
||||||
|
Copyright (C) 1999-2013 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
Under Section 7 of GPL version 3, you are granted additional
|
||||||
|
permissions described in the GCC Runtime Library Exception, version
|
||||||
|
3.1, as published by the Free Software Foundation.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License and
|
||||||
|
a copy of the GCC Runtime Library Exception along with this program;
|
||||||
|
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
/* This file may be included by any ELF target which wishes to
|
||||||
|
support -gstabs generating stabs in sections, as produced by gas
|
||||||
|
and understood by gdb. */
|
||||||
|
|
||||||
|
#ifndef GCC_DBX_ELF_H
|
||||||
|
#define GCC_DBX_ELF_H
|
||||||
|
|
||||||
|
/* Output DBX (stabs) debugging information if doing -gstabs. */
|
||||||
|
|
||||||
|
#define DBX_DEBUGGING_INFO 1
|
||||||
|
|
||||||
|
/* Make LBRAC and RBRAC addresses relative to the start of the
|
||||||
|
function. The native Solaris stabs debugging format works this
|
||||||
|
way, gdb expects it, and it reduces the number of relocation
|
||||||
|
entries... */
|
||||||
|
|
||||||
|
#define DBX_BLOCKS_FUNCTION_RELATIVE 1
|
||||||
|
|
||||||
|
/* ... but, to make this work, functions must appear prior to line info. */
|
||||||
|
|
||||||
|
#define DBX_FUNCTION_FIRST
|
||||||
|
|
||||||
|
/* When generating stabs debugging, use N_BINCL entries. */
|
||||||
|
|
||||||
|
#define DBX_USE_BINCL
|
||||||
|
|
||||||
|
/* There is no limit to the length of stabs strings. */
|
||||||
|
|
||||||
|
#ifndef DBX_CONTIN_LENGTH
|
||||||
|
#define DBX_CONTIN_LENGTH 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Like block addresses, stabs line numbers are relative to the
|
||||||
|
current function. */
|
||||||
|
|
||||||
|
#define DBX_LINES_FUNCTION_RELATIVE 1
|
||||||
|
|
||||||
|
/* Generate a blank trailing N_SO to mark the end of the .o file, since
|
||||||
|
we can't depend upon the linker to mark .o file boundaries with
|
||||||
|
embedded stabs. */
|
||||||
|
|
||||||
|
#define DBX_OUTPUT_NULL_N_SO_AT_MAIN_SOURCE_FILE_END
|
||||||
|
|
||||||
|
#endif /* ! GCC_DBX_ELF_H */
|
|
@ -0,0 +1,435 @@
|
||||||
|
/* elfos.h -- operating system specific defines to be used when
|
||||||
|
targeting GCC for some generic ELF system
|
||||||
|
Copyright (C) 1991-2013 Free Software Foundation, Inc.
|
||||||
|
Based on svr4.h contributed by Ron Guilmette (rfg@netcom.com).
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
Under Section 7 of GPL version 3, you are granted additional
|
||||||
|
permissions described in the GCC Runtime Library Exception, version
|
||||||
|
3.1, as published by the Free Software Foundation.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License and
|
||||||
|
a copy of the GCC Runtime Library Exception along with this program;
|
||||||
|
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#define TARGET_OBJFMT_CPP_BUILTINS() \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
builtin_define ("__ELF__"); \
|
||||||
|
} \
|
||||||
|
while (0)
|
||||||
|
|
||||||
|
/* Define a symbol indicating that we are using elfos.h.
|
||||||
|
Some CPU specific configuration files use this. */
|
||||||
|
#define USING_ELFOS_H
|
||||||
|
|
||||||
|
/* The prefix to add to user-visible assembler symbols.
|
||||||
|
|
||||||
|
For ELF systems the convention is *not* to prepend a leading
|
||||||
|
underscore onto user-level symbol names. */
|
||||||
|
|
||||||
|
#undef USER_LABEL_PREFIX
|
||||||
|
#define USER_LABEL_PREFIX ""
|
||||||
|
|
||||||
|
/* The biggest alignment supported by ELF in bits. 32-bit ELF
|
||||||
|
supports section alignment up to (0x80000000 * 8), while
|
||||||
|
64-bit ELF supports (0x8000000000000000 * 8). If this macro
|
||||||
|
is not defined, the default is the largest alignment supported
|
||||||
|
by 32-bit ELF and representable on a 32-bit host. Use this
|
||||||
|
macro to limit the alignment which can be specified using
|
||||||
|
the `__attribute__ ((aligned (N)))' construct. */
|
||||||
|
#ifndef MAX_OFILE_ALIGNMENT
|
||||||
|
#define MAX_OFILE_ALIGNMENT (((unsigned int) 1 << 28) * 8)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Use periods rather than dollar signs in special g++ assembler names. */
|
||||||
|
|
||||||
|
#define NO_DOLLAR_IN_LABEL
|
||||||
|
|
||||||
|
/* Writing `int' for a bit-field forces int alignment for the structure. */
|
||||||
|
|
||||||
|
#ifndef PCC_BITFIELD_TYPE_MATTERS
|
||||||
|
#define PCC_BITFIELD_TYPE_MATTERS 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* All ELF targets can support DWARF-2. */
|
||||||
|
|
||||||
|
#define DWARF2_DEBUGGING_INFO 1
|
||||||
|
|
||||||
|
/* The GNU tools operate better with dwarf2, and it is required by some
|
||||||
|
psABI's. Since we don't have any native tools to be compatible with,
|
||||||
|
default to dwarf2. */
|
||||||
|
|
||||||
|
#ifndef PREFERRED_DEBUGGING_TYPE
|
||||||
|
#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* All SVR4 targets use the ELF object file format. */
|
||||||
|
#define OBJECT_FORMAT_ELF
|
||||||
|
|
||||||
|
|
||||||
|
/* Output #ident as a .ident. */
|
||||||
|
|
||||||
|
#undef TARGET_ASM_OUTPUT_IDENT
|
||||||
|
#define TARGET_ASM_OUTPUT_IDENT default_asm_output_ident_directive
|
||||||
|
|
||||||
|
#undef SET_ASM_OP
|
||||||
|
#define SET_ASM_OP "\t.set\t"
|
||||||
|
|
||||||
|
/* Most svr4 assemblers want a .file directive at the beginning of
|
||||||
|
their input file. */
|
||||||
|
#define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
|
||||||
|
|
||||||
|
/* This is how to allocate empty space in some section. The .zero
|
||||||
|
pseudo-op is used for this on most svr4 assemblers. */
|
||||||
|
|
||||||
|
#define SKIP_ASM_OP "\t.zero\t"
|
||||||
|
|
||||||
|
#undef ASM_OUTPUT_SKIP
|
||||||
|
#define ASM_OUTPUT_SKIP(FILE, SIZE) \
|
||||||
|
fprintf ((FILE), "%s"HOST_WIDE_INT_PRINT_UNSIGNED"\n",\
|
||||||
|
SKIP_ASM_OP, (SIZE))
|
||||||
|
|
||||||
|
/* This is how to store into the string LABEL
|
||||||
|
the symbol_ref name of an internal numbered label where
|
||||||
|
PREFIX is the class of label and NUM is the number within the class.
|
||||||
|
This is suitable for output with `assemble_name'.
|
||||||
|
|
||||||
|
For most svr4 systems, the convention is that any symbol which begins
|
||||||
|
with a period is not put into the linker symbol table by the assembler. */
|
||||||
|
|
||||||
|
#undef ASM_GENERATE_INTERNAL_LABEL
|
||||||
|
#define ASM_GENERATE_INTERNAL_LABEL(LABEL, PREFIX, NUM) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
char *__p; \
|
||||||
|
(LABEL)[0] = '*'; \
|
||||||
|
(LABEL)[1] = '.'; \
|
||||||
|
__p = stpcpy (&(LABEL)[2], PREFIX); \
|
||||||
|
sprint_ul (__p, (unsigned long) (NUM)); \
|
||||||
|
} \
|
||||||
|
while (0)
|
||||||
|
|
||||||
|
/* Output the label which precedes a jumptable. Note that for all svr4
|
||||||
|
systems where we actually generate jumptables (which is to say every
|
||||||
|
svr4 target except i386, where we use casesi instead) we put the jump-
|
||||||
|
tables into the .rodata section and since other stuff could have been
|
||||||
|
put into the .rodata section prior to any given jumptable, we have to
|
||||||
|
make sure that the location counter for the .rodata section gets pro-
|
||||||
|
perly re-aligned prior to the actual beginning of the jump table. */
|
||||||
|
|
||||||
|
#undef ALIGN_ASM_OP
|
||||||
|
#define ALIGN_ASM_OP "\t.align\t"
|
||||||
|
|
||||||
|
#ifndef ASM_OUTPUT_BEFORE_CASE_LABEL
|
||||||
|
#define ASM_OUTPUT_BEFORE_CASE_LABEL(FILE, PREFIX, NUM, TABLE) \
|
||||||
|
ASM_OUTPUT_ALIGN ((FILE), 2);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#undef ASM_OUTPUT_CASE_LABEL
|
||||||
|
#define ASM_OUTPUT_CASE_LABEL(FILE, PREFIX, NUM, JUMPTABLE) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
ASM_OUTPUT_BEFORE_CASE_LABEL (FILE, PREFIX, NUM, JUMPTABLE) \
|
||||||
|
(*targetm.asm_out.internal_label) (FILE, PREFIX, NUM); \
|
||||||
|
} \
|
||||||
|
while (0)
|
||||||
|
|
||||||
|
/* The standard SVR4 assembler seems to require that certain builtin
|
||||||
|
library routines (e.g. .udiv) be explicitly declared as .globl
|
||||||
|
in each assembly file where they are referenced. */
|
||||||
|
|
||||||
|
#define ASM_OUTPUT_EXTERNAL_LIBCALL(FILE, FUN) \
|
||||||
|
(*targetm.asm_out.globalize_label) (FILE, XSTR (FUN, 0))
|
||||||
|
|
||||||
|
/* This says how to output assembler code to declare an
|
||||||
|
uninitialized external linkage data object. Under SVR4,
|
||||||
|
the linker seems to want the alignment of data objects
|
||||||
|
to depend on their types. We do exactly that here. */
|
||||||
|
|
||||||
|
#define COMMON_ASM_OP "\t.comm\t"
|
||||||
|
|
||||||
|
#undef ASM_OUTPUT_ALIGNED_COMMON
|
||||||
|
#define ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGN) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
fprintf ((FILE), "%s", COMMON_ASM_OP); \
|
||||||
|
assemble_name ((FILE), (NAME)); \
|
||||||
|
fprintf ((FILE), ","HOST_WIDE_INT_PRINT_UNSIGNED",%u\n", \
|
||||||
|
(SIZE), (ALIGN) / BITS_PER_UNIT); \
|
||||||
|
} \
|
||||||
|
while (0)
|
||||||
|
|
||||||
|
/* This says how to output assembler code to declare an
|
||||||
|
uninitialized internal linkage data object. Under SVR4,
|
||||||
|
the linker seems to want the alignment of data objects
|
||||||
|
to depend on their types. We do exactly that here. */
|
||||||
|
|
||||||
|
#define LOCAL_ASM_OP "\t.local\t"
|
||||||
|
|
||||||
|
#undef ASM_OUTPUT_ALIGNED_LOCAL
|
||||||
|
#define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
fprintf ((FILE), "%s", LOCAL_ASM_OP); \
|
||||||
|
assemble_name ((FILE), (NAME)); \
|
||||||
|
fprintf ((FILE), "\n"); \
|
||||||
|
ASM_OUTPUT_ALIGNED_COMMON (FILE, NAME, SIZE, ALIGN); \
|
||||||
|
} \
|
||||||
|
while (0)
|
||||||
|
|
||||||
|
/* This is the pseudo-op used to generate a contiguous sequence of byte
|
||||||
|
values from a double-quoted string WITHOUT HAVING A TERMINATING NUL
|
||||||
|
AUTOMATICALLY APPENDED. This is the same for most svr4 assemblers. */
|
||||||
|
|
||||||
|
#undef ASCII_DATA_ASM_OP
|
||||||
|
#define ASCII_DATA_ASM_OP "\t.ascii\t"
|
||||||
|
|
||||||
|
/* Support a read-only data section. */
|
||||||
|
#define READONLY_DATA_SECTION_ASM_OP "\t.section\t.rodata"
|
||||||
|
|
||||||
|
/* On svr4, we *do* have support for the .init and .fini sections, and we
|
||||||
|
can put stuff in there to be executed before and after `main'. We let
|
||||||
|
crtstuff.c and other files know this by defining the following symbols.
|
||||||
|
The definitions say how to change sections to the .init and .fini
|
||||||
|
sections. This is the same for all known svr4 assemblers. */
|
||||||
|
|
||||||
|
#define INIT_SECTION_ASM_OP "\t.section\t.init"
|
||||||
|
#define FINI_SECTION_ASM_OP "\t.section\t.fini"
|
||||||
|
|
||||||
|
/* Output assembly directive to move to the beginning of current section. */
|
||||||
|
#ifdef HAVE_GAS_SUBSECTION_ORDERING
|
||||||
|
# define ASM_SECTION_START_OP "\t.subsection\t-1"
|
||||||
|
# define ASM_OUTPUT_SECTION_START(FILE) \
|
||||||
|
fprintf ((FILE), "%s\n", ASM_SECTION_START_OP)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define MAKE_DECL_ONE_ONLY(DECL) (DECL_WEAK (DECL) = 1)
|
||||||
|
|
||||||
|
/* Switch into a generic section. */
|
||||||
|
#define TARGET_ASM_NAMED_SECTION default_elf_asm_named_section
|
||||||
|
|
||||||
|
#undef TARGET_ASM_SELECT_RTX_SECTION
|
||||||
|
#define TARGET_ASM_SELECT_RTX_SECTION default_elf_select_rtx_section
|
||||||
|
#undef TARGET_ASM_SELECT_SECTION
|
||||||
|
#define TARGET_ASM_SELECT_SECTION default_elf_select_section
|
||||||
|
#undef TARGET_HAVE_SWITCHABLE_BSS_SECTIONS
|
||||||
|
#define TARGET_HAVE_SWITCHABLE_BSS_SECTIONS true
|
||||||
|
|
||||||
|
/* Define the strings used for the special svr4 .type and .size directives.
|
||||||
|
These strings generally do not vary from one system running svr4 to
|
||||||
|
another, but if a given system (e.g. m88k running svr) needs to use
|
||||||
|
different pseudo-op names for these, they may be overridden in the
|
||||||
|
file which includes this one. */
|
||||||
|
|
||||||
|
#define TYPE_ASM_OP "\t.type\t"
|
||||||
|
#define SIZE_ASM_OP "\t.size\t"
|
||||||
|
|
||||||
|
/* This is how we tell the assembler that a symbol is weak. */
|
||||||
|
|
||||||
|
#define ASM_WEAKEN_LABEL(FILE, NAME) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
fputs ("\t.weak\t", (FILE)); \
|
||||||
|
assemble_name ((FILE), (NAME)); \
|
||||||
|
fputc ('\n', (FILE)); \
|
||||||
|
} \
|
||||||
|
while (0)
|
||||||
|
|
||||||
|
/* The following macro defines the format used to output the second
|
||||||
|
operand of the .type assembler directive. Different svr4 assemblers
|
||||||
|
expect various different forms for this operand. The one given here
|
||||||
|
is just a default. You may need to override it in your machine-
|
||||||
|
specific tm.h file (depending upon the particulars of your assembler). */
|
||||||
|
|
||||||
|
#define TYPE_OPERAND_FMT "@%s"
|
||||||
|
|
||||||
|
/* Write the extra assembler code needed to declare a function's result.
|
||||||
|
Most svr4 assemblers don't require any special declaration of the
|
||||||
|
result value, but there are exceptions. */
|
||||||
|
|
||||||
|
#ifndef ASM_DECLARE_RESULT
|
||||||
|
#define ASM_DECLARE_RESULT(FILE, RESULT)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* These macros generate the special .type and .size directives which
|
||||||
|
are used to set the corresponding fields of the linker symbol table
|
||||||
|
entries in an ELF object file under SVR4. These macros also output
|
||||||
|
the starting labels for the relevant functions/objects. */
|
||||||
|
|
||||||
|
/* Write the extra assembler code needed to declare a function properly.
|
||||||
|
Some svr4 assemblers need to also have something extra said about the
|
||||||
|
function's return value. We allow for that here. */
|
||||||
|
|
||||||
|
#ifndef ASM_DECLARE_FUNCTION_NAME
|
||||||
|
#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "function"); \
|
||||||
|
ASM_DECLARE_RESULT (FILE, DECL_RESULT (DECL)); \
|
||||||
|
ASM_OUTPUT_FUNCTION_LABEL (FILE, NAME, DECL); \
|
||||||
|
} \
|
||||||
|
while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Write the extra assembler code needed to declare an object properly. */
|
||||||
|
|
||||||
|
#ifdef HAVE_GAS_GNU_UNIQUE_OBJECT
|
||||||
|
#define USE_GNU_UNIQUE_OBJECT flag_gnu_unique
|
||||||
|
#else
|
||||||
|
#define USE_GNU_UNIQUE_OBJECT 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define ASM_DECLARE_OBJECT_NAME(FILE, NAME, DECL) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
HOST_WIDE_INT size; \
|
||||||
|
\
|
||||||
|
/* For template static data member instantiations or \
|
||||||
|
inline fn local statics and their guard variables, use \
|
||||||
|
gnu_unique_object so that they will be combined even under \
|
||||||
|
RTLD_LOCAL. Don't use gnu_unique_object for typeinfo, \
|
||||||
|
vtables and other read-only artificial decls. */ \
|
||||||
|
if (USE_GNU_UNIQUE_OBJECT && DECL_ONE_ONLY (DECL) \
|
||||||
|
&& (!DECL_ARTIFICIAL (DECL) || !TREE_READONLY (DECL))) \
|
||||||
|
ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "gnu_unique_object"); \
|
||||||
|
else \
|
||||||
|
ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "object"); \
|
||||||
|
\
|
||||||
|
size_directive_output = 0; \
|
||||||
|
if (!flag_inhibit_size_directive \
|
||||||
|
&& (DECL) && DECL_SIZE (DECL)) \
|
||||||
|
{ \
|
||||||
|
size_directive_output = 1; \
|
||||||
|
size = int_size_in_bytes (TREE_TYPE (DECL)); \
|
||||||
|
ASM_OUTPUT_SIZE_DIRECTIVE (FILE, NAME, size); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
ASM_OUTPUT_LABEL (FILE, NAME); \
|
||||||
|
} \
|
||||||
|
while (0)
|
||||||
|
|
||||||
|
/* Output the size directive for a decl in rest_of_decl_compilation
|
||||||
|
in the case where we did not do so before the initializer.
|
||||||
|
Once we find the error_mark_node, we know that the value of
|
||||||
|
size_directive_output was set
|
||||||
|
by ASM_DECLARE_OBJECT_NAME when it was run for the same decl. */
|
||||||
|
|
||||||
|
#undef ASM_FINISH_DECLARE_OBJECT
|
||||||
|
#define ASM_FINISH_DECLARE_OBJECT(FILE, DECL, TOP_LEVEL, AT_END)\
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
const char *name = XSTR (XEXP (DECL_RTL (DECL), 0), 0); \
|
||||||
|
HOST_WIDE_INT size; \
|
||||||
|
\
|
||||||
|
if (!flag_inhibit_size_directive \
|
||||||
|
&& DECL_SIZE (DECL) \
|
||||||
|
&& ! AT_END && TOP_LEVEL \
|
||||||
|
&& DECL_INITIAL (DECL) == error_mark_node \
|
||||||
|
&& !size_directive_output) \
|
||||||
|
{ \
|
||||||
|
size_directive_output = 1; \
|
||||||
|
size = int_size_in_bytes (TREE_TYPE (DECL)); \
|
||||||
|
ASM_OUTPUT_SIZE_DIRECTIVE (FILE, name, size); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
while (0)
|
||||||
|
|
||||||
|
/* This is how to declare the size of a function. */
|
||||||
|
#ifndef ASM_DECLARE_FUNCTION_SIZE
|
||||||
|
#define ASM_DECLARE_FUNCTION_SIZE(FILE, FNAME, DECL) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
if (!flag_inhibit_size_directive) \
|
||||||
|
ASM_OUTPUT_MEASURED_SIZE (FILE, FNAME); \
|
||||||
|
} \
|
||||||
|
while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* A table of bytes codes used by the ASM_OUTPUT_ASCII and
|
||||||
|
ASM_OUTPUT_LIMITED_STRING macros. Each byte in the table
|
||||||
|
corresponds to a particular byte value [0..255]. For any
|
||||||
|
given byte value, if the value in the corresponding table
|
||||||
|
position is zero, the given character can be output directly.
|
||||||
|
If the table value is 1, the byte must be output as a \ooo
|
||||||
|
octal escape. If the tables value is anything else, then the
|
||||||
|
byte value should be output as a \ followed by the value
|
||||||
|
in the table. Note that we can use standard UN*X escape
|
||||||
|
sequences for many control characters, but we don't use
|
||||||
|
\a to represent BEL because some svr4 assemblers (e.g. on
|
||||||
|
the i386) don't know about that. Also, we don't use \v
|
||||||
|
since some versions of gas, such as 2.2 did not accept it. */
|
||||||
|
|
||||||
|
#define ELF_ASCII_ESCAPES \
|
||||||
|
"\1\1\1\1\1\1\1\1btn\1fr\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\
|
||||||
|
\0\0\"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
|
||||||
|
\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\\\0\0\0\
|
||||||
|
\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1\
|
||||||
|
\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\
|
||||||
|
\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\
|
||||||
|
\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\
|
||||||
|
\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"
|
||||||
|
|
||||||
|
/* Some svr4 assemblers have a limit on the number of characters which
|
||||||
|
can appear in the operand of a .string directive. If your assembler
|
||||||
|
has such a limitation, you should define STRING_LIMIT to reflect that
|
||||||
|
limit. Note that at least some svr4 assemblers have a limit on the
|
||||||
|
actual number of bytes in the double-quoted string, and that they
|
||||||
|
count each character in an escape sequence as one byte. Thus, an
|
||||||
|
escape sequence like \377 would count as four bytes.
|
||||||
|
|
||||||
|
If your target assembler doesn't support the .string directive, you
|
||||||
|
should define this to zero.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define ELF_STRING_LIMIT ((unsigned) 256)
|
||||||
|
|
||||||
|
#define STRING_ASM_OP "\t.string\t"
|
||||||
|
|
||||||
|
/* The routine used to output NUL terminated strings. We use a special
|
||||||
|
version of this for most svr4 targets because doing so makes the
|
||||||
|
generated assembly code more compact (and thus faster to assemble)
|
||||||
|
as well as more readable, especially for targets like the i386
|
||||||
|
(where the only alternative is to output character sequences as
|
||||||
|
comma separated lists of numbers). */
|
||||||
|
|
||||||
|
#define ASM_OUTPUT_LIMITED_STRING(FILE, STR) \
|
||||||
|
default_elf_asm_output_limited_string ((FILE), (STR))
|
||||||
|
|
||||||
|
/* The routine used to output sequences of byte values. We use a special
|
||||||
|
version of this for most svr4 targets because doing so makes the
|
||||||
|
generated assembly code more compact (and thus faster to assemble)
|
||||||
|
as well as more readable. Note that if we find subparts of the
|
||||||
|
character sequence which end with NUL (and which are shorter than
|
||||||
|
STRING_LIMIT) we output those using ASM_OUTPUT_LIMITED_STRING. */
|
||||||
|
|
||||||
|
#undef ASM_OUTPUT_ASCII
|
||||||
|
#define ASM_OUTPUT_ASCII(FILE, STR, LENGTH) \
|
||||||
|
default_elf_asm_output_ascii ((FILE), (STR), (LENGTH));
|
||||||
|
|
||||||
|
/* Allow the use of the -frecord-gcc-switches switch via the
|
||||||
|
elf_record_gcc_switches function defined in varasm.c. */
|
||||||
|
#undef TARGET_ASM_RECORD_GCC_SWITCHES
|
||||||
|
#define TARGET_ASM_RECORD_GCC_SWITCHES elf_record_gcc_switches
|
||||||
|
|
||||||
|
/* A C statement (sans semicolon) to output to the stdio stream STREAM
|
||||||
|
any text necessary for declaring the name of an external symbol
|
||||||
|
named NAME which is referenced in this compilation but not defined.
|
||||||
|
It is needed to properly support non-default visibility. */
|
||||||
|
|
||||||
|
#ifndef ASM_OUTPUT_EXTERNAL
|
||||||
|
#define ASM_OUTPUT_EXTERNAL(FILE, DECL, NAME) \
|
||||||
|
default_elf_asm_output_external (FILE, DECL, NAME)
|
||||||
|
#endif
|
|
@ -0,0 +1,55 @@
|
||||||
|
/* Definitions for <stdint.h> types on systems using GNU libc or uClibc.
|
||||||
|
Copyright (C) 2008-2013 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
Under Section 7 of GPL version 3, you are granted additional
|
||||||
|
permissions described in the GCC Runtime Library Exception, version
|
||||||
|
3.1, as published by the Free Software Foundation.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License and
|
||||||
|
a copy of the GCC Runtime Library Exception along with this program;
|
||||||
|
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#define SIG_ATOMIC_TYPE "int"
|
||||||
|
|
||||||
|
#define INT8_TYPE "signed char"
|
||||||
|
#define INT16_TYPE "short int"
|
||||||
|
#define INT32_TYPE "int"
|
||||||
|
#define INT64_TYPE (LONG_TYPE_SIZE == 64 ? "long int" : "long long int")
|
||||||
|
#define UINT8_TYPE "unsigned char"
|
||||||
|
#define UINT16_TYPE "short unsigned int"
|
||||||
|
#define UINT32_TYPE "unsigned int"
|
||||||
|
#define UINT64_TYPE (LONG_TYPE_SIZE == 64 ? "long unsigned int" : "long long unsigned int")
|
||||||
|
|
||||||
|
#define INT_LEAST8_TYPE "signed char"
|
||||||
|
#define INT_LEAST16_TYPE "short int"
|
||||||
|
#define INT_LEAST32_TYPE "int"
|
||||||
|
#define INT_LEAST64_TYPE (LONG_TYPE_SIZE == 64 ? "long int" : "long long int")
|
||||||
|
#define UINT_LEAST8_TYPE "unsigned char"
|
||||||
|
#define UINT_LEAST16_TYPE "short unsigned int"
|
||||||
|
#define UINT_LEAST32_TYPE "unsigned int"
|
||||||
|
#define UINT_LEAST64_TYPE (LONG_TYPE_SIZE == 64 ? "long unsigned int" : "long long unsigned int")
|
||||||
|
|
||||||
|
#define INT_FAST8_TYPE "signed char"
|
||||||
|
#define INT_FAST16_TYPE (LONG_TYPE_SIZE == 64 ? "long int" : "int")
|
||||||
|
#define INT_FAST32_TYPE (LONG_TYPE_SIZE == 64 ? "long int" : "int")
|
||||||
|
#define INT_FAST64_TYPE (LONG_TYPE_SIZE == 64 ? "long int" : "long long int")
|
||||||
|
#define UINT_FAST8_TYPE "unsigned char"
|
||||||
|
#define UINT_FAST16_TYPE (LONG_TYPE_SIZE == 64 ? "long unsigned int" : "unsigned int")
|
||||||
|
#define UINT_FAST32_TYPE (LONG_TYPE_SIZE == 64 ? "long unsigned int" : "unsigned int")
|
||||||
|
#define UINT_FAST64_TYPE (LONG_TYPE_SIZE == 64 ? "long unsigned int" : "long long unsigned int")
|
||||||
|
|
||||||
|
#define INTPTR_TYPE (LONG_TYPE_SIZE == 64 ? "long int" : "int")
|
||||||
|
#define UINTPTR_TYPE (LONG_TYPE_SIZE == 64 ? "long unsigned int" : "unsigned int")
|
|
@ -0,0 +1,123 @@
|
||||||
|
/* Definitions for systems using, at least optionally, a GNU
|
||||||
|
(glibc-based) userspace or other userspace with libc derived from
|
||||||
|
glibc (e.g. uClibc) or for which similar specs are appropriate.
|
||||||
|
Copyright (C) 1995-2013 Free Software Foundation, Inc.
|
||||||
|
Contributed by Eric Youngdale.
|
||||||
|
Modified for stabs-in-ELF by H.J. Lu (hjl@lucon.org).
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
Under Section 7 of GPL version 3, you are granted additional
|
||||||
|
permissions described in the GCC Runtime Library Exception, version
|
||||||
|
3.1, as published by the Free Software Foundation.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License and
|
||||||
|
a copy of the GCC Runtime Library Exception along with this program;
|
||||||
|
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
/* Don't assume anything about the header files. */
|
||||||
|
#define NO_IMPLICIT_EXTERN_C
|
||||||
|
|
||||||
|
#undef ASM_APP_ON
|
||||||
|
#define ASM_APP_ON "#APP\n"
|
||||||
|
|
||||||
|
#undef ASM_APP_OFF
|
||||||
|
#define ASM_APP_OFF "#NO_APP\n"
|
||||||
|
|
||||||
|
/* Provide a STARTFILE_SPEC appropriate for GNU userspace. Here we add
|
||||||
|
the GNU userspace magical crtbegin.o file (see crtstuff.c) which
|
||||||
|
provides part of the support for getting C++ file-scope static
|
||||||
|
object constructed before entering `main'. */
|
||||||
|
|
||||||
|
#if defined HAVE_LD_PIE
|
||||||
|
#define GNU_USER_TARGET_STARTFILE_SPEC \
|
||||||
|
"%{!shared: %{pg|p|profile:gcrt1.o%s;pie:Scrt1.o%s;:crt1.o%s}} \
|
||||||
|
crti.o%s %{static:crtbeginT.o%s;shared|pie:crtbeginS.o%s;:crtbegin.o%s}"
|
||||||
|
#else
|
||||||
|
#define GNU_USER_TARGET_STARTFILE_SPEC \
|
||||||
|
"%{!shared: %{pg|p|profile:gcrt1.o%s;:crt1.o%s}} \
|
||||||
|
crti.o%s %{static:crtbeginT.o%s;shared|pie:crtbeginS.o%s;:crtbegin.o%s}"
|
||||||
|
#endif
|
||||||
|
#undef STARTFILE_SPEC
|
||||||
|
#define STARTFILE_SPEC GNU_USER_TARGET_STARTFILE_SPEC
|
||||||
|
|
||||||
|
/* Provide a ENDFILE_SPEC appropriate for GNU userspace. Here we tack on
|
||||||
|
the GNU userspace magical crtend.o file (see crtstuff.c) which
|
||||||
|
provides part of the support for getting C++ file-scope static
|
||||||
|
object constructed before entering `main', followed by a normal
|
||||||
|
GNU userspace "finalizer" file, `crtn.o'. */
|
||||||
|
|
||||||
|
#define GNU_USER_TARGET_ENDFILE_SPEC \
|
||||||
|
"%{shared|pie:crtendS.o%s;:crtend.o%s} crtn.o%s"
|
||||||
|
#undef ENDFILE_SPEC
|
||||||
|
#define ENDFILE_SPEC GNU_USER_TARGET_ENDFILE_SPEC
|
||||||
|
|
||||||
|
/* This is for -profile to use -lc_p instead of -lc. */
|
||||||
|
#define GNU_USER_TARGET_CC1_SPEC "%{profile:-p}"
|
||||||
|
#ifndef CC1_SPEC
|
||||||
|
#define CC1_SPEC GNU_USER_TARGET_CC1_SPEC
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* The GNU C++ standard library requires that these macros be defined. */
|
||||||
|
#undef CPLUSPLUS_CPP_SPEC
|
||||||
|
#define CPLUSPLUS_CPP_SPEC "-D_GNU_SOURCE %(cpp)"
|
||||||
|
|
||||||
|
#define GNU_USER_TARGET_LIB_SPEC \
|
||||||
|
"%{pthread:-lpthread} \
|
||||||
|
%{shared:-lc} \
|
||||||
|
%{!shared:%{mieee-fp:-lieee} %{profile:-lc_p}%{!profile:-lc}}"
|
||||||
|
#undef LIB_SPEC
|
||||||
|
#define LIB_SPEC GNU_USER_TARGET_LIB_SPEC
|
||||||
|
|
||||||
|
#if defined(HAVE_LD_EH_FRAME_HDR)
|
||||||
|
#define LINK_EH_SPEC "%{!static:--eh-frame-hdr} "
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#undef LINK_GCC_C_SEQUENCE_SPEC
|
||||||
|
#define LINK_GCC_C_SEQUENCE_SPEC \
|
||||||
|
"%{static:--start-group} %G %L %{static:--end-group}%{!static:%G}"
|
||||||
|
|
||||||
|
/* Use --as-needed -lgcc_s for eh support. */
|
||||||
|
#ifdef HAVE_LD_AS_NEEDED
|
||||||
|
#define USE_LD_AS_NEEDED 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define TARGET_POSIX_IO
|
||||||
|
|
||||||
|
#define TARGET_C99_FUNCTIONS 1
|
||||||
|
#define TARGET_HAS_SINCOS 1
|
||||||
|
|
||||||
|
/* Link -lasan early on the command line. For -static-libasan, don't link
|
||||||
|
it for -shared link, the executable should be compiled with -static-libasan
|
||||||
|
in that case, and for executable link link with --{,no-}whole-archive around
|
||||||
|
it to force everything into the executable. And similarly for -ltsan. */
|
||||||
|
#if defined(HAVE_LD_STATIC_DYNAMIC)
|
||||||
|
#undef LIBASAN_EARLY_SPEC
|
||||||
|
#define LIBASAN_EARLY_SPEC "%{!shared:libasan_preinit%O%s} " \
|
||||||
|
"%{static-libasan:%{!shared:" \
|
||||||
|
LD_STATIC_OPTION " --whole-archive -lasan --no-whole-archive " \
|
||||||
|
LD_DYNAMIC_OPTION "}}%{!static-libasan:-lasan}"
|
||||||
|
#undef LIBTSAN_EARLY_SPEC
|
||||||
|
#define LIBTSAN_EARLY_SPEC "%{static-libtsan:%{!shared:" \
|
||||||
|
LD_STATIC_OPTION " --whole-archive -ltsan --no-whole-archive " \
|
||||||
|
LD_DYNAMIC_OPTION "}}%{!static-libtsan:-ltsan}"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Additional libraries needed by -static-libasan. */
|
||||||
|
#undef STATIC_LIBASAN_LIBS
|
||||||
|
#define STATIC_LIBASAN_LIBS "-ldl -lpthread"
|
||||||
|
|
||||||
|
/* Additional libraries needed by -static-libtsan. */
|
||||||
|
#undef STATIC_LIBTSAN_LIBS
|
||||||
|
#define STATIC_LIBTSAN_LIBS "-ldl -lpthread"
|
|
@ -0,0 +1,91 @@
|
||||||
|
/* Definitions for AT&T assembler syntax for the Intel 80386.
|
||||||
|
Copyright (C) 1988-2013 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
Under Section 7 of GPL version 3, you are granted additional
|
||||||
|
permissions described in the GCC Runtime Library Exception, version
|
||||||
|
3.1, as published by the Free Software Foundation.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License and
|
||||||
|
a copy of the GCC Runtime Library Exception along with this program;
|
||||||
|
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
|
||||||
|
/* Define the syntax of instructions and addresses. */
|
||||||
|
|
||||||
|
/* Prefix for internally generated assembler labels. */
|
||||||
|
#define LPREFIX ".L"
|
||||||
|
|
||||||
|
/* Assembler pseudos to introduce constants of various size. */
|
||||||
|
|
||||||
|
#define ASM_BYTE "\t.byte\t"
|
||||||
|
#define ASM_SHORT "\t.value\t"
|
||||||
|
#define ASM_LONG "\t.long\t"
|
||||||
|
#define ASM_QUAD "\t.quad\t" /* Should not be used for 32bit compilation. */
|
||||||
|
|
||||||
|
/* How to output an ASCII string constant. */
|
||||||
|
|
||||||
|
#undef ASM_OUTPUT_ASCII
|
||||||
|
#define ASM_OUTPUT_ASCII(FILE, PTR, SIZE) \
|
||||||
|
do \
|
||||||
|
{ size_t i = 0, limit = (SIZE); \
|
||||||
|
while (i < limit) \
|
||||||
|
{ if (i%10 == 0) { if (i!=0) putc ('\n', (FILE)); \
|
||||||
|
fputs (ASM_BYTE, (FILE)); } \
|
||||||
|
else putc (',', (FILE)); \
|
||||||
|
fprintf ((FILE), "0x%x", ((PTR)[i++] & 0377)) ;} \
|
||||||
|
putc ('\n', (FILE)); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/* Output at beginning of assembler file. */
|
||||||
|
#define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
|
||||||
|
|
||||||
|
/* This is how to output an assembler line
|
||||||
|
that says to advance the location counter
|
||||||
|
to a multiple of 2**LOG bytes. */
|
||||||
|
|
||||||
|
#define ASM_OUTPUT_ALIGN(FILE,LOG) \
|
||||||
|
if ((LOG)!=0) fprintf ((FILE), "\t.align %d\n", 1<<(LOG))
|
||||||
|
|
||||||
|
/* This is how to output an assembler line
|
||||||
|
that says to advance the location counter by SIZE bytes. */
|
||||||
|
|
||||||
|
#undef ASM_OUTPUT_SKIP
|
||||||
|
#define ASM_OUTPUT_SKIP(FILE,SIZE) \
|
||||||
|
fprintf ((FILE), "\t.set .,.+%u\n", (int)(SIZE))
|
||||||
|
|
||||||
|
/* Can't use ASM_OUTPUT_SKIP in text section; it doesn't leave 0s. */
|
||||||
|
|
||||||
|
#define ASM_NO_SKIP_IN_TEXT 1
|
||||||
|
|
||||||
|
/* Define the syntax of labels and symbol definitions/declarations. */
|
||||||
|
|
||||||
|
/* The prefix to add for compiler private assembler symbols. */
|
||||||
|
#undef LOCAL_LABEL_PREFIX
|
||||||
|
#define LOCAL_LABEL_PREFIX "."
|
||||||
|
|
||||||
|
/* This is how to store into the string BUF
|
||||||
|
the symbol_ref name of an internal numbered label where
|
||||||
|
PREFIX is the class of label and NUM is the number within the class.
|
||||||
|
This is suitable for output with `assemble_name'. */
|
||||||
|
|
||||||
|
#undef ASM_GENERATE_INTERNAL_LABEL
|
||||||
|
#define ASM_GENERATE_INTERNAL_LABEL(BUF,PREFIX,NUMBER) \
|
||||||
|
sprintf ((BUF), LOCAL_LABEL_PREFIX "%s%ld", (PREFIX), (long)(NUMBER))
|
||||||
|
|
||||||
|
/* The prefix to add to user-visible assembler symbols. */
|
||||||
|
|
||||||
|
#undef USER_LABEL_PREFIX
|
||||||
|
#define USER_LABEL_PREFIX ""
|
|
@ -0,0 +1,29 @@
|
||||||
|
/* Make configure files to produce biarch compiler defaulting to 64bit mode.
|
||||||
|
This file must be included very first, while the OS specific file later
|
||||||
|
to overwrite otherwise wrong defaults.
|
||||||
|
Copyright (C) 2001-2013 Free Software Foundation, Inc.
|
||||||
|
Contributed by Bo Thorsen <bo@suse.de>.
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
Under Section 7 of GPL version 3, you are granted additional
|
||||||
|
permissions described in the GCC Runtime Library Exception, version
|
||||||
|
3.1, as published by the Free Software Foundation.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License and
|
||||||
|
a copy of the GCC Runtime Library Exception along with this program;
|
||||||
|
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#define TARGET_64BIT_DEFAULT (OPTION_MASK_ISA_64BIT | OPTION_MASK_ABI_64)
|
||||||
|
#define TARGET_BI_ARCH 1
|
|
@ -0,0 +1,72 @@
|
||||||
|
/* Common definitions for Intel 386 and AMD x86-64 systems using
|
||||||
|
GNU userspace. Copyright (C) 2012-2013 Free Software Foundation, Inc.
|
||||||
|
Contributed by Ilya Enkovich.
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GCC; see the file COPYING3. If not see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
/* The svr4 ABI for the i386 says that records and unions are returned
|
||||||
|
in memory. In the 64bit compilation we will turn this flag off in
|
||||||
|
ix86_option_override_internal, as we never do pcc_struct_return
|
||||||
|
scheme on this target. */
|
||||||
|
#undef DEFAULT_PCC_STRUCT_RETURN
|
||||||
|
#define DEFAULT_PCC_STRUCT_RETURN 1
|
||||||
|
|
||||||
|
/* We arrange for the whole %fs segment to map the tls area. */
|
||||||
|
#undef TARGET_TLS_DIRECT_SEG_REFS_DEFAULT
|
||||||
|
#define TARGET_TLS_DIRECT_SEG_REFS_DEFAULT MASK_TLS_DIRECT_SEG_REFS
|
||||||
|
|
||||||
|
#define TARGET_OS_CPP_BUILTINS() \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
GNU_USER_TARGET_OS_CPP_BUILTINS(); \
|
||||||
|
} \
|
||||||
|
while (0)
|
||||||
|
|
||||||
|
#undef CPP_SPEC
|
||||||
|
#define CPP_SPEC "%{posix:-D_POSIX_SOURCE} %{pthread:-D_REENTRANT}"
|
||||||
|
|
||||||
|
#undef GNU_USER_TARGET_CC1_SPEC
|
||||||
|
#define GNU_USER_TARGET_CC1_SPEC "%(cc1_cpu) %{profile:-p}"
|
||||||
|
|
||||||
|
#undef CC1_SPEC
|
||||||
|
#define CC1_SPEC GNU_USER_TARGET_CC1_SPEC
|
||||||
|
|
||||||
|
/* Similar to standard GNU userspace, but adding -ffast-math support. */
|
||||||
|
#define GNU_USER_TARGET_MATHFILE_SPEC \
|
||||||
|
"%{Ofast|ffast-math|funsafe-math-optimizations:crtfastmath.o%s} \
|
||||||
|
%{mpc32:crtprec32.o%s} \
|
||||||
|
%{mpc64:crtprec64.o%s} \
|
||||||
|
%{mpc80:crtprec80.o%s}"
|
||||||
|
|
||||||
|
#undef ENDFILE_SPEC
|
||||||
|
#define ENDFILE_SPEC \
|
||||||
|
GNU_USER_TARGET_MATHFILE_SPEC " " \
|
||||||
|
GNU_USER_TARGET_ENDFILE_SPEC
|
||||||
|
|
||||||
|
/* Put all *tf routines in libgcc. */
|
||||||
|
#undef LIBGCC2_HAS_TF_MODE
|
||||||
|
#define LIBGCC2_HAS_TF_MODE 1
|
||||||
|
#define LIBGCC2_TF_CEXT q
|
||||||
|
#define TF_SIZE 113
|
||||||
|
|
||||||
|
#define TARGET_ASM_FILE_END file_end_indicate_exec_stack
|
||||||
|
|
||||||
|
/* The stack pointer needs to be moved while checking the stack. */
|
||||||
|
#define STACK_CHECK_MOVING_SP 1
|
||||||
|
|
||||||
|
/* Static stack checking is supported by means of probes. */
|
||||||
|
#define STACK_CHECK_STATIC_BUILTIN 1
|
|
@ -0,0 +1,99 @@
|
||||||
|
/* Definitions for AMD x86-64 using GNU userspace.
|
||||||
|
Copyright (C) 2001-2013 Free Software Foundation, Inc.
|
||||||
|
Contributed by Jan Hubicka <jh@suse.cz>, based on linux.h.
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
Under Section 7 of GPL version 3, you are granted additional
|
||||||
|
permissions described in the GCC Runtime Library Exception, version
|
||||||
|
3.1, as published by the Free Software Foundation.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License and
|
||||||
|
a copy of the GCC Runtime Library Exception along with this program;
|
||||||
|
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
/* Provide a LINK_SPEC. Here we provide support for the special GCC
|
||||||
|
options -static and -shared, which allow us to link things in one
|
||||||
|
of these three modes by applying the appropriate combinations of
|
||||||
|
options at link-time.
|
||||||
|
|
||||||
|
When the -shared link option is used a final link is not being
|
||||||
|
done. */
|
||||||
|
|
||||||
|
#if TARGET_64BIT_DEFAULT
|
||||||
|
#define SPEC_32 "m32"
|
||||||
|
#if TARGET_BI_ARCH == 2
|
||||||
|
#define SPEC_64 "m64"
|
||||||
|
#define SPEC_X32 "m32|m64:;"
|
||||||
|
#else
|
||||||
|
#define SPEC_64 "m32|mx32:;"
|
||||||
|
#define SPEC_X32 "mx32"
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#define SPEC_32 "m64|mx32:;"
|
||||||
|
#define SPEC_64 "m64"
|
||||||
|
#define SPEC_X32 "mx32"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#undef ASM_SPEC
|
||||||
|
#define ASM_SPEC "%{" SPEC_32 ":--32} \
|
||||||
|
%{" SPEC_64 ":--64} \
|
||||||
|
%{" SPEC_X32 ":--x32} \
|
||||||
|
%{!mno-sse2avx:%{mavx:-msse2avx}} %{msse2avx:%{!mavx:-msse2avx}}"
|
||||||
|
|
||||||
|
#define GNU_USER_TARGET_LINK_SPEC \
|
||||||
|
"%{" SPEC_64 ":-m " GNU_USER_LINK_EMULATION64 "} \
|
||||||
|
%{" SPEC_32 ":-m " GNU_USER_LINK_EMULATION32 "} \
|
||||||
|
%{" SPEC_X32 ":-m " GNU_USER_LINK_EMULATIONX32 "} \
|
||||||
|
%{shared:-shared} \
|
||||||
|
%{!shared: \
|
||||||
|
%{!static: \
|
||||||
|
%{rdynamic:-export-dynamic} \
|
||||||
|
%{" SPEC_32 ":-dynamic-linker " GNU_USER_DYNAMIC_LINKER32 "} \
|
||||||
|
%{" SPEC_64 ":-dynamic-linker " GNU_USER_DYNAMIC_LINKER64 "} \
|
||||||
|
%{" SPEC_X32 ":-dynamic-linker " GNU_USER_DYNAMIC_LINKERX32 "}} \
|
||||||
|
%{static:-static}}"
|
||||||
|
|
||||||
|
#undef LINK_SPEC
|
||||||
|
#define LINK_SPEC GNU_USER_TARGET_LINK_SPEC
|
||||||
|
|
||||||
|
#if TARGET_64BIT_DEFAULT
|
||||||
|
#if TARGET_BI_ARCH == 2
|
||||||
|
#define MULTILIB_DEFAULTS { "mx32" }
|
||||||
|
#else
|
||||||
|
#define MULTILIB_DEFAULTS { "m64" }
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#define MULTILIB_DEFAULTS { "m32" }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TARGET_LIBC_PROVIDES_SSP
|
||||||
|
/* i386 glibc provides __stack_chk_guard in %gs:0x14,
|
||||||
|
x32 glibc provides it in %fs:0x18.
|
||||||
|
x86_64 glibc provides it in %fs:0x28. */
|
||||||
|
#define TARGET_THREAD_SSP_OFFSET \
|
||||||
|
(TARGET_64BIT ? (TARGET_X32 ? 0x18 : 0x28) : 0x14)
|
||||||
|
|
||||||
|
/* We only build the -fsplit-stack support in libgcc if the
|
||||||
|
assembler has full support for the CFI directives. */
|
||||||
|
#if HAVE_GAS_CFI_PERSONALITY_DIRECTIVE
|
||||||
|
#define TARGET_CAN_SPLIT_STACK
|
||||||
|
#endif
|
||||||
|
/* We steal the last transactional memory word. */
|
||||||
|
#define TARGET_THREAD_SPLIT_STACK_OFFSET \
|
||||||
|
(TARGET_64BIT ? (TARGET_X32 ? 0x40 : 0x70) : 0x30)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#undef WCHAR_TYPE
|
||||||
|
#define WCHAR_TYPE (TARGET_LP64 ? "int" : "long int")
|
|
@ -0,0 +1,88 @@
|
||||||
|
/* Definitions for option handling for IA-32.
|
||||||
|
Copyright (C) 1988-2013 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
Under Section 7 of GPL version 3, you are granted additional
|
||||||
|
permissions described in the GCC Runtime Library Exception, version
|
||||||
|
3.1, as published by the Free Software Foundation.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License and
|
||||||
|
a copy of the GCC Runtime Library Exception along with this program;
|
||||||
|
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#ifndef I386_OPTS_H
|
||||||
|
#define I386_OPTS_H
|
||||||
|
|
||||||
|
/* Algorithm to expand string function with. */
|
||||||
|
enum stringop_alg
|
||||||
|
{
|
||||||
|
no_stringop,
|
||||||
|
libcall,
|
||||||
|
rep_prefix_1_byte,
|
||||||
|
rep_prefix_4_byte,
|
||||||
|
rep_prefix_8_byte,
|
||||||
|
loop_1_byte,
|
||||||
|
loop,
|
||||||
|
unrolled_loop
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Available call abi. */
|
||||||
|
enum calling_abi
|
||||||
|
{
|
||||||
|
SYSV_ABI = 0,
|
||||||
|
MS_ABI = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
enum fpmath_unit
|
||||||
|
{
|
||||||
|
FPMATH_387 = 1,
|
||||||
|
FPMATH_SSE = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
enum tls_dialect
|
||||||
|
{
|
||||||
|
TLS_DIALECT_GNU,
|
||||||
|
TLS_DIALECT_GNU2,
|
||||||
|
TLS_DIALECT_SUN
|
||||||
|
};
|
||||||
|
|
||||||
|
enum cmodel {
|
||||||
|
CM_32, /* The traditional 32-bit ABI. */
|
||||||
|
CM_SMALL, /* Assumes all code and data fits in the low 31 bits. */
|
||||||
|
CM_KERNEL, /* Assumes all code and data fits in the high 31 bits. */
|
||||||
|
CM_MEDIUM, /* Assumes code fits in the low 31 bits; data unlimited. */
|
||||||
|
CM_LARGE, /* No assumptions. */
|
||||||
|
CM_SMALL_PIC, /* Assumes code+data+got/plt fits in a 31 bit region. */
|
||||||
|
CM_MEDIUM_PIC,/* Assumes code+got/plt fits in a 31 bit region. */
|
||||||
|
CM_LARGE_PIC /* No assumptions. */
|
||||||
|
};
|
||||||
|
|
||||||
|
enum pmode {
|
||||||
|
PMODE_SI, /* Pmode == SImode. */
|
||||||
|
PMODE_DI /* Pmode == DImode. */
|
||||||
|
};
|
||||||
|
|
||||||
|
enum asm_dialect {
|
||||||
|
ASM_ATT,
|
||||||
|
ASM_INTEL
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ix86_veclibabi {
|
||||||
|
ix86_veclibabi_type_none,
|
||||||
|
ix86_veclibabi_type_svml,
|
||||||
|
ix86_veclibabi_type_acml
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,326 @@
|
||||||
|
/* Definitions of target machine for GCC for IA-32.
|
||||||
|
Copyright (C) 1988-2013 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GCC; see the file COPYING3. If not see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
/* In i386-common.c. */
|
||||||
|
extern bool ix86_handle_option (struct gcc_options *opts,
|
||||||
|
struct gcc_options *opts_set ATTRIBUTE_UNUSED,
|
||||||
|
const struct cl_decoded_option *decoded,
|
||||||
|
location_t loc);
|
||||||
|
|
||||||
|
/* Functions in i386.c */
|
||||||
|
extern bool ix86_target_stack_probe (void);
|
||||||
|
extern bool ix86_can_use_return_insn_p (void);
|
||||||
|
extern void ix86_setup_frame_addresses (void);
|
||||||
|
|
||||||
|
extern HOST_WIDE_INT ix86_initial_elimination_offset (int, int);
|
||||||
|
extern void ix86_expand_prologue (void);
|
||||||
|
extern void ix86_maybe_emit_epilogue_vzeroupper (void);
|
||||||
|
extern void ix86_expand_epilogue (int);
|
||||||
|
extern void ix86_expand_split_stack_prologue (void);
|
||||||
|
|
||||||
|
extern void ix86_output_addr_vec_elt (FILE *, int);
|
||||||
|
extern void ix86_output_addr_diff_elt (FILE *, int, int);
|
||||||
|
|
||||||
|
extern enum calling_abi ix86_cfun_abi (void);
|
||||||
|
extern enum calling_abi ix86_function_type_abi (const_tree);
|
||||||
|
|
||||||
|
#ifdef RTX_CODE
|
||||||
|
extern int standard_80387_constant_p (rtx);
|
||||||
|
extern const char *standard_80387_constant_opcode (rtx);
|
||||||
|
extern rtx standard_80387_constant_rtx (int);
|
||||||
|
extern int standard_sse_constant_p (rtx);
|
||||||
|
extern const char *standard_sse_constant_opcode (rtx, rtx);
|
||||||
|
extern bool symbolic_reference_mentioned_p (rtx);
|
||||||
|
extern bool extended_reg_mentioned_p (rtx);
|
||||||
|
extern bool x86_extended_QIreg_mentioned_p (rtx);
|
||||||
|
extern bool x86_extended_reg_mentioned_p (rtx);
|
||||||
|
extern bool x86_maybe_negate_const_int (rtx *, enum machine_mode);
|
||||||
|
extern enum machine_mode ix86_cc_mode (enum rtx_code, rtx, rtx);
|
||||||
|
|
||||||
|
extern int avx_vpermilp_parallel (rtx par, enum machine_mode mode);
|
||||||
|
extern int avx_vperm2f128_parallel (rtx par, enum machine_mode mode);
|
||||||
|
|
||||||
|
extern bool ix86_expand_movmem (rtx, rtx, rtx, rtx, rtx, rtx);
|
||||||
|
extern bool ix86_expand_setmem (rtx, rtx, rtx, rtx, rtx, rtx);
|
||||||
|
extern bool ix86_expand_strlen (rtx, rtx, rtx, rtx);
|
||||||
|
|
||||||
|
extern bool constant_address_p (rtx);
|
||||||
|
extern bool legitimate_pic_operand_p (rtx);
|
||||||
|
extern bool legitimate_pic_address_disp_p (rtx);
|
||||||
|
extern bool ix86_legitimize_reload_address (rtx, enum machine_mode,
|
||||||
|
int, int, int);
|
||||||
|
extern void print_reg (rtx, int, FILE*);
|
||||||
|
extern void ix86_print_operand (FILE *, rtx, int);
|
||||||
|
|
||||||
|
extern void split_double_mode (enum machine_mode, rtx[], int, rtx[], rtx[]);
|
||||||
|
|
||||||
|
extern const char *output_set_got (rtx, rtx);
|
||||||
|
extern const char *output_387_binary_op (rtx, rtx*);
|
||||||
|
extern const char *output_387_reg_move (rtx, rtx*);
|
||||||
|
extern const char *output_fix_trunc (rtx, rtx*, bool);
|
||||||
|
extern const char *output_fp_compare (rtx, rtx*, bool, bool);
|
||||||
|
extern const char *output_adjust_stack_and_probe (rtx);
|
||||||
|
extern const char *output_probe_stack_range (rtx, rtx);
|
||||||
|
|
||||||
|
extern void ix86_expand_clear (rtx);
|
||||||
|
extern void ix86_expand_move (enum machine_mode, rtx[]);
|
||||||
|
extern void ix86_expand_vector_move (enum machine_mode, rtx[]);
|
||||||
|
extern void ix86_expand_vector_move_misalign (enum machine_mode, rtx[]);
|
||||||
|
extern void ix86_expand_push (enum machine_mode, rtx);
|
||||||
|
extern rtx ix86_fixup_binary_operands (enum rtx_code,
|
||||||
|
enum machine_mode, rtx[]);
|
||||||
|
extern void ix86_fixup_binary_operands_no_copy (enum rtx_code,
|
||||||
|
enum machine_mode, rtx[]);
|
||||||
|
extern void ix86_expand_binary_operator (enum rtx_code,
|
||||||
|
enum machine_mode, rtx[]);
|
||||||
|
extern void ix86_expand_vector_logical_operator (enum rtx_code,
|
||||||
|
enum machine_mode, rtx[]);
|
||||||
|
extern bool ix86_binary_operator_ok (enum rtx_code, enum machine_mode, rtx[]);
|
||||||
|
extern bool ix86_avoid_lea_for_add (rtx, rtx[]);
|
||||||
|
extern bool ix86_use_lea_for_mov (rtx, rtx[]);
|
||||||
|
extern bool ix86_avoid_lea_for_addr (rtx, rtx[]);
|
||||||
|
extern void ix86_split_lea_for_addr (rtx, rtx[], enum machine_mode);
|
||||||
|
extern bool ix86_lea_for_add_ok (rtx, rtx[]);
|
||||||
|
extern bool ix86_vec_interleave_v2df_operator_ok (rtx operands[3], bool high);
|
||||||
|
extern bool ix86_dep_by_shift_count (const_rtx set_insn, const_rtx use_insn);
|
||||||
|
extern bool ix86_agi_dependent (rtx set_insn, rtx use_insn);
|
||||||
|
extern void ix86_expand_unary_operator (enum rtx_code, enum machine_mode,
|
||||||
|
rtx[]);
|
||||||
|
extern rtx ix86_build_const_vector (enum machine_mode, bool, rtx);
|
||||||
|
extern rtx ix86_build_signbit_mask (enum machine_mode, bool, bool);
|
||||||
|
extern void ix86_split_convert_uns_si_sse (rtx[]);
|
||||||
|
extern void ix86_expand_convert_uns_didf_sse (rtx, rtx);
|
||||||
|
extern void ix86_expand_convert_uns_sixf_sse (rtx, rtx);
|
||||||
|
extern void ix86_expand_convert_uns_sidf_sse (rtx, rtx);
|
||||||
|
extern void ix86_expand_convert_uns_sisf_sse (rtx, rtx);
|
||||||
|
extern void ix86_expand_convert_sign_didf_sse (rtx, rtx);
|
||||||
|
extern void ix86_expand_vector_convert_uns_vsivsf (rtx, rtx);
|
||||||
|
extern rtx ix86_expand_adjust_ufix_to_sfix_si (rtx, rtx *);
|
||||||
|
extern enum ix86_fpcmp_strategy ix86_fp_comparison_strategy (enum rtx_code);
|
||||||
|
extern void ix86_expand_fp_absneg_operator (enum rtx_code, enum machine_mode,
|
||||||
|
rtx[]);
|
||||||
|
extern void ix86_expand_copysign (rtx []);
|
||||||
|
extern void ix86_split_copysign_const (rtx []);
|
||||||
|
extern void ix86_split_copysign_var (rtx []);
|
||||||
|
extern bool ix86_unary_operator_ok (enum rtx_code, enum machine_mode, rtx[]);
|
||||||
|
extern bool ix86_match_ccmode (rtx, enum machine_mode);
|
||||||
|
extern void ix86_expand_branch (enum rtx_code, rtx, rtx, rtx);
|
||||||
|
extern void ix86_expand_setcc (rtx, enum rtx_code, rtx, rtx);
|
||||||
|
extern bool ix86_expand_int_movcc (rtx[]);
|
||||||
|
extern bool ix86_expand_fp_movcc (rtx[]);
|
||||||
|
extern bool ix86_expand_fp_vcond (rtx[]);
|
||||||
|
extern bool ix86_expand_int_vcond (rtx[]);
|
||||||
|
extern void ix86_expand_vec_perm (rtx[]);
|
||||||
|
extern bool ix86_expand_vec_perm_const (rtx[]);
|
||||||
|
extern void ix86_expand_sse_unpack (rtx, rtx, bool, bool);
|
||||||
|
extern bool ix86_expand_int_addcc (rtx[]);
|
||||||
|
extern rtx ix86_expand_call (rtx, rtx, rtx, rtx, rtx, bool);
|
||||||
|
extern void ix86_split_call_vzeroupper (rtx, rtx);
|
||||||
|
extern void x86_initialize_trampoline (rtx, rtx, rtx);
|
||||||
|
extern rtx ix86_zero_extend_to_Pmode (rtx);
|
||||||
|
extern void ix86_split_long_move (rtx[]);
|
||||||
|
extern void ix86_split_ashl (rtx *, rtx, enum machine_mode);
|
||||||
|
extern void ix86_split_ashr (rtx *, rtx, enum machine_mode);
|
||||||
|
extern void ix86_split_lshr (rtx *, rtx, enum machine_mode);
|
||||||
|
extern rtx ix86_find_base_term (rtx);
|
||||||
|
extern bool ix86_check_movabs (rtx, int);
|
||||||
|
extern void ix86_split_idivmod (enum machine_mode, rtx[], bool);
|
||||||
|
|
||||||
|
extern rtx assign_386_stack_local (enum machine_mode, enum ix86_stack_slot);
|
||||||
|
extern int ix86_attr_length_immediate_default (rtx, bool);
|
||||||
|
extern int ix86_attr_length_address_default (rtx);
|
||||||
|
extern int ix86_attr_length_vex_default (rtx, bool, bool);
|
||||||
|
|
||||||
|
extern enum machine_mode ix86_fp_compare_mode (enum rtx_code);
|
||||||
|
|
||||||
|
extern rtx ix86_libcall_value (enum machine_mode);
|
||||||
|
extern bool ix86_function_arg_regno_p (int);
|
||||||
|
extern void ix86_asm_output_function_label (FILE *, const char *, tree);
|
||||||
|
extern rtx ix86_force_to_memory (enum machine_mode, rtx);
|
||||||
|
extern void ix86_free_from_memory (enum machine_mode);
|
||||||
|
extern void ix86_call_abi_override (const_tree);
|
||||||
|
extern int ix86_reg_parm_stack_space (const_tree);
|
||||||
|
|
||||||
|
extern void ix86_split_fp_branch (enum rtx_code code, rtx, rtx,
|
||||||
|
rtx, rtx, rtx, rtx);
|
||||||
|
extern bool ix86_hard_regno_mode_ok (int, enum machine_mode);
|
||||||
|
extern bool ix86_modes_tieable_p (enum machine_mode, enum machine_mode);
|
||||||
|
extern bool ix86_secondary_memory_needed (enum reg_class, enum reg_class,
|
||||||
|
enum machine_mode, int);
|
||||||
|
extern bool ix86_cannot_change_mode_class (enum machine_mode,
|
||||||
|
enum machine_mode, enum reg_class);
|
||||||
|
|
||||||
|
extern int ix86_mode_needed (int, rtx);
|
||||||
|
extern int ix86_mode_after (int, int, rtx);
|
||||||
|
extern int ix86_mode_entry (int);
|
||||||
|
extern int ix86_mode_exit (int);
|
||||||
|
|
||||||
|
#ifdef HARD_CONST
|
||||||
|
extern void ix86_emit_mode_set (int, int, HARD_REG_SET);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern void x86_order_regs_for_local_alloc (void);
|
||||||
|
extern void x86_function_profiler (FILE *, int);
|
||||||
|
extern void x86_emit_floatuns (rtx [2]);
|
||||||
|
extern void ix86_emit_fp_unordered_jump (rtx);
|
||||||
|
|
||||||
|
extern void ix86_emit_i387_log1p (rtx, rtx);
|
||||||
|
extern void ix86_emit_i387_round (rtx, rtx);
|
||||||
|
extern void ix86_emit_swdivsf (rtx, rtx, rtx, enum machine_mode);
|
||||||
|
extern void ix86_emit_swsqrtsf (rtx, rtx, enum machine_mode, bool);
|
||||||
|
|
||||||
|
extern enum rtx_code ix86_reverse_condition (enum rtx_code, enum machine_mode);
|
||||||
|
|
||||||
|
extern void ix86_expand_lround (rtx, rtx);
|
||||||
|
extern void ix86_expand_lfloorceil (rtx, rtx, bool);
|
||||||
|
extern void ix86_expand_rint (rtx, rtx);
|
||||||
|
extern void ix86_expand_floorceil (rtx, rtx, bool);
|
||||||
|
extern void ix86_expand_floorceildf_32 (rtx, rtx, bool);
|
||||||
|
extern void ix86_expand_round_sse4 (rtx, rtx);
|
||||||
|
extern void ix86_expand_round (rtx, rtx);
|
||||||
|
extern void ix86_expand_rounddf_32 (rtx, rtx);
|
||||||
|
extern void ix86_expand_trunc (rtx, rtx);
|
||||||
|
extern void ix86_expand_truncdf_32 (rtx, rtx);
|
||||||
|
|
||||||
|
extern void ix86_expand_vecop_qihi (enum rtx_code, rtx, rtx, rtx);
|
||||||
|
|
||||||
|
#ifdef TREE_CODE
|
||||||
|
extern void init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, tree, int);
|
||||||
|
#endif /* TREE_CODE */
|
||||||
|
|
||||||
|
#endif /* RTX_CODE */
|
||||||
|
|
||||||
|
#ifdef TREE_CODE
|
||||||
|
extern int ix86_data_alignment (tree, int);
|
||||||
|
extern unsigned int ix86_local_alignment (tree, enum machine_mode,
|
||||||
|
unsigned int);
|
||||||
|
extern unsigned int ix86_minimum_alignment (tree, enum machine_mode,
|
||||||
|
unsigned int);
|
||||||
|
extern int ix86_constant_alignment (tree, int);
|
||||||
|
extern tree ix86_handle_shared_attribute (tree *, tree, tree, int, bool *);
|
||||||
|
extern tree ix86_handle_selectany_attribute (tree *, tree, tree, int, bool *);
|
||||||
|
extern int x86_field_alignment (tree, int);
|
||||||
|
extern tree ix86_valid_target_attribute_tree (tree);
|
||||||
|
extern unsigned int ix86_get_callcvt (const_tree);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern rtx ix86_tls_module_base (void);
|
||||||
|
|
||||||
|
extern void ix86_expand_vector_init (bool, rtx, rtx);
|
||||||
|
extern void ix86_expand_vector_set (bool, rtx, rtx, int);
|
||||||
|
extern void ix86_expand_vector_extract (bool, rtx, rtx, int);
|
||||||
|
extern void ix86_expand_reduc (rtx (*)(rtx, rtx, rtx), rtx, rtx);
|
||||||
|
|
||||||
|
extern void ix86_expand_vec_extract_even_odd (rtx, rtx, rtx, unsigned);
|
||||||
|
extern bool ix86_expand_pinsr (rtx *);
|
||||||
|
extern void ix86_expand_mul_widen_evenodd (rtx, rtx, rtx, bool, bool);
|
||||||
|
extern void ix86_expand_mul_widen_hilo (rtx, rtx, rtx, bool, bool);
|
||||||
|
extern void ix86_expand_sse2_mulv4si3 (rtx, rtx, rtx);
|
||||||
|
extern void ix86_expand_sse2_mulvxdi3 (rtx, rtx, rtx);
|
||||||
|
|
||||||
|
/* In i386-c.c */
|
||||||
|
extern void ix86_target_macros (void);
|
||||||
|
extern void ix86_register_pragmas (void);
|
||||||
|
|
||||||
|
/* In winnt.c */
|
||||||
|
extern void i386_pe_unique_section (tree, int);
|
||||||
|
extern void i386_pe_declare_function_type (FILE *, const char *, int);
|
||||||
|
extern void i386_pe_record_external_function (tree, const char *);
|
||||||
|
extern void i386_pe_maybe_record_exported_symbol (tree, const char *, int);
|
||||||
|
extern void i386_pe_encode_section_info (tree, rtx, int);
|
||||||
|
extern bool i386_pe_binds_local_p (const_tree);
|
||||||
|
extern const char *i386_pe_strip_name_encoding_full (const char *);
|
||||||
|
extern bool i386_pe_valid_dllimport_attribute_p (const_tree);
|
||||||
|
extern unsigned int i386_pe_section_type_flags (tree, const char *, int);
|
||||||
|
extern void i386_pe_asm_named_section (const char *, unsigned int, tree);
|
||||||
|
extern void i386_pe_asm_output_aligned_decl_common (FILE *, tree,
|
||||||
|
const char *,
|
||||||
|
HOST_WIDE_INT,
|
||||||
|
HOST_WIDE_INT);
|
||||||
|
extern void i386_pe_file_end (void);
|
||||||
|
extern void i386_pe_start_function (FILE *, const char *, tree);
|
||||||
|
extern void i386_pe_end_function (FILE *, const char *, tree);
|
||||||
|
extern void i386_pe_assemble_visibility (tree, int);
|
||||||
|
extern tree i386_pe_mangle_decl_assembler_name (tree, tree);
|
||||||
|
extern tree i386_pe_mangle_assembler_name (const char *);
|
||||||
|
|
||||||
|
extern void i386_pe_seh_init (FILE *);
|
||||||
|
extern void i386_pe_seh_end_prologue (FILE *);
|
||||||
|
extern void i386_pe_seh_unwind_emit (FILE *, rtx);
|
||||||
|
extern void i386_pe_seh_emit_except_personality (rtx);
|
||||||
|
extern void i386_pe_seh_init_sections (void);
|
||||||
|
|
||||||
|
/* In winnt-cxx.c and winnt-stubs.c */
|
||||||
|
extern void i386_pe_adjust_class_at_definition (tree);
|
||||||
|
extern bool i386_pe_type_dllimport_p (tree);
|
||||||
|
extern bool i386_pe_type_dllexport_p (tree);
|
||||||
|
|
||||||
|
extern int i386_pe_reloc_rw_mask (void);
|
||||||
|
|
||||||
|
extern rtx maybe_get_pool_constant (rtx);
|
||||||
|
|
||||||
|
extern char internal_label_prefix[16];
|
||||||
|
extern int internal_label_prefix_len;
|
||||||
|
|
||||||
|
enum ix86_address_seg { SEG_DEFAULT, SEG_FS, SEG_GS };
|
||||||
|
struct ix86_address
|
||||||
|
{
|
||||||
|
rtx base, index, disp;
|
||||||
|
HOST_WIDE_INT scale;
|
||||||
|
enum ix86_address_seg seg;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern int ix86_decompose_address (rtx, struct ix86_address *);
|
||||||
|
extern int memory_address_length (rtx, bool);
|
||||||
|
extern void x86_output_aligned_bss (FILE *, tree, const char *,
|
||||||
|
unsigned HOST_WIDE_INT, int);
|
||||||
|
extern void x86_elf_aligned_common (FILE *, const char *,
|
||||||
|
unsigned HOST_WIDE_INT, int);
|
||||||
|
|
||||||
|
#ifdef RTX_CODE
|
||||||
|
extern void ix86_fp_comparison_codes (enum rtx_code code, enum rtx_code *,
|
||||||
|
enum rtx_code *, enum rtx_code *);
|
||||||
|
extern enum rtx_code ix86_fp_compare_code_to_integer (enum rtx_code);
|
||||||
|
#endif
|
||||||
|
extern int asm_preferred_eh_data_format (int, int);
|
||||||
|
|
||||||
|
#ifdef HAVE_ATTR_cpu
|
||||||
|
extern enum attr_cpu ix86_schedule;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern const char * ix86_output_call_insn (rtx insn, rtx call_op);
|
||||||
|
|
||||||
|
#ifdef RTX_CODE
|
||||||
|
/* Target data for multipass lookahead scheduling.
|
||||||
|
Currently used for Core 2/i7 tuning. */
|
||||||
|
struct ix86_first_cycle_multipass_data_
|
||||||
|
{
|
||||||
|
/* The length (in bytes) of ifetch block in this solution. */
|
||||||
|
int ifetch_block_len;
|
||||||
|
/* Number of instructions in ifetch block in this solution. */
|
||||||
|
int ifetch_block_n_insns;
|
||||||
|
/* Bitmap to remember changes to ready_try for backtracking. */
|
||||||
|
sbitmap ready_try_change;
|
||||||
|
/* Size of the bitmap. */
|
||||||
|
int ready_try_change_size;
|
||||||
|
};
|
||||||
|
# define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DATA_T \
|
||||||
|
struct ix86_first_cycle_multipass_data_
|
||||||
|
#endif /* RTX_CODE */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,55 @@
|
||||||
|
/* Definitions for Intel 386 running Linux-based GNU systems with ELF format.
|
||||||
|
Copyright (C) 2012-2013 Free Software Foundation, Inc.
|
||||||
|
Contributed by Ilya Enkovich.
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GCC; see the file COPYING3. If not see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#undef TARGET_OS_CPP_BUILTINS
|
||||||
|
#define TARGET_OS_CPP_BUILTINS() \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
GNU_USER_TARGET_OS_CPP_BUILTINS(); \
|
||||||
|
ANDROID_TARGET_OS_CPP_BUILTINS(); \
|
||||||
|
} \
|
||||||
|
while (0)
|
||||||
|
|
||||||
|
#undef CC1_SPEC
|
||||||
|
#define CC1_SPEC \
|
||||||
|
LINUX_OR_ANDROID_CC (GNU_USER_TARGET_CC1_SPEC, \
|
||||||
|
GNU_USER_TARGET_CC1_SPEC " " ANDROID_CC1_SPEC)
|
||||||
|
|
||||||
|
#undef LINK_SPEC
|
||||||
|
#define LINK_SPEC \
|
||||||
|
LINUX_OR_ANDROID_LD (GNU_USER_TARGET_LINK_SPEC, \
|
||||||
|
GNU_USER_TARGET_LINK_SPEC " " ANDROID_LINK_SPEC)
|
||||||
|
|
||||||
|
#undef LIB_SPEC
|
||||||
|
#define LIB_SPEC \
|
||||||
|
LINUX_OR_ANDROID_LD (GNU_USER_TARGET_LIB_SPEC, \
|
||||||
|
GNU_USER_TARGET_LIB_SPEC " " ANDROID_LIB_SPEC)
|
||||||
|
|
||||||
|
#undef STARTFILE_SPEC
|
||||||
|
#define STARTFILE_SPEC \
|
||||||
|
LINUX_OR_ANDROID_LD (GNU_USER_TARGET_STARTFILE_SPEC, \
|
||||||
|
ANDROID_STARTFILE_SPEC)
|
||||||
|
|
||||||
|
#undef ENDFILE_SPEC
|
||||||
|
#define ENDFILE_SPEC \
|
||||||
|
LINUX_OR_ANDROID_LD (GNU_USER_TARGET_MATHFILE_SPEC " " \
|
||||||
|
GNU_USER_TARGET_ENDFILE_SPEC, \
|
||||||
|
GNU_USER_TARGET_MATHFILE_SPEC " " \
|
||||||
|
ANDROID_ENDFILE_SPEC)
|
|
@ -0,0 +1,32 @@
|
||||||
|
/* Definitions for AMD x86-64 running Linux-based GNU systems with ELF format.
|
||||||
|
Copyright (C) 2001-2013 Free Software Foundation, Inc.
|
||||||
|
Contributed by Jan Hubicka <jh@suse.cz>, based on linux.h.
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
Under Section 7 of GPL version 3, you are granted additional
|
||||||
|
permissions described in the GCC Runtime Library Exception, version
|
||||||
|
3.1, as published by the Free Software Foundation.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License and
|
||||||
|
a copy of the GCC Runtime Library Exception along with this program;
|
||||||
|
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#define GNU_USER_LINK_EMULATION32 "elf_i386"
|
||||||
|
#define GNU_USER_LINK_EMULATION64 "elf_x86_64"
|
||||||
|
#define GNU_USER_LINK_EMULATIONX32 "elf32_x86_64"
|
||||||
|
|
||||||
|
#define GLIBC_DYNAMIC_LINKER32 "/lib/ld-linux.so.2"
|
||||||
|
#define GLIBC_DYNAMIC_LINKER64 "/lib64/ld-linux-x86-64.so.2"
|
||||||
|
#define GLIBC_DYNAMIC_LINKERX32 "/libx32/ld-linux-x32.so.2"
|
|
@ -0,0 +1,80 @@
|
||||||
|
/* Definitions for Unix assembler syntax for the Intel 80386.
|
||||||
|
Copyright (C) 1988-2013 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
Under Section 7 of GPL version 3, you are granted additional
|
||||||
|
permissions described in the GCC Runtime Library Exception, version
|
||||||
|
3.1, as published by the Free Software Foundation.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License and
|
||||||
|
a copy of the GCC Runtime Library Exception along with this program;
|
||||||
|
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
/* This file defines the aspects of assembler syntax
|
||||||
|
that are the same for all the i386 Unix systems
|
||||||
|
(though they may differ in non-Unix systems). */
|
||||||
|
|
||||||
|
/* Define macro used to output shift-double opcodes when the shift
|
||||||
|
count is in %cl. Some assemblers require %cl as an argument;
|
||||||
|
some don't. This macro controls what to do: by default, don't
|
||||||
|
print %cl. */
|
||||||
|
#define SHIFT_DOUBLE_OMITS_COUNT 1
|
||||||
|
|
||||||
|
/* Define the syntax of pseudo-ops, labels and comments. */
|
||||||
|
|
||||||
|
/* String containing the assembler's comment-starter.
|
||||||
|
Note the trailing space is necessary in case the character
|
||||||
|
that immediately follows the comment is '*'. If this happens
|
||||||
|
and the space is not there the assembler will interpret this
|
||||||
|
as the start of a C-like slash-star comment and complain when
|
||||||
|
there is no terminator. */
|
||||||
|
|
||||||
|
#define ASM_COMMENT_START "/ "
|
||||||
|
|
||||||
|
/* Output to assembler file text saying following lines
|
||||||
|
may contain character constants, extra white space, comments, etc. */
|
||||||
|
|
||||||
|
#define ASM_APP_ON "/APP\n"
|
||||||
|
|
||||||
|
/* Output to assembler file text saying following lines
|
||||||
|
no longer contain unusual constructs. */
|
||||||
|
|
||||||
|
#define ASM_APP_OFF "/NO_APP\n"
|
||||||
|
|
||||||
|
/* Output before read-only data. */
|
||||||
|
|
||||||
|
#define TEXT_SECTION_ASM_OP "\t.text"
|
||||||
|
|
||||||
|
/* Output before writable (initialized) data. */
|
||||||
|
|
||||||
|
#define DATA_SECTION_ASM_OP "\t.data"
|
||||||
|
|
||||||
|
/* Output before writable (uninitialized) data. */
|
||||||
|
|
||||||
|
#define BSS_SECTION_ASM_OP "\t.bss"
|
||||||
|
|
||||||
|
/* Globalizing directive for a label. */
|
||||||
|
#define GLOBAL_ASM_OP "\t.globl\t"
|
||||||
|
|
||||||
|
/* By default, target has a 80387, uses IEEE compatible arithmetic,
|
||||||
|
and returns float values in the 387. */
|
||||||
|
#undef TARGET_SUBTARGET_DEFAULT
|
||||||
|
#define TARGET_SUBTARGET_DEFAULT \
|
||||||
|
(MASK_80387 | MASK_IEEE_FP | MASK_FLOAT_RETURNS)
|
||||||
|
|
||||||
|
/* By default, 64-bit mode uses 128-bit long double. */
|
||||||
|
#undef TARGET_SUBTARGET64_DEFAULT
|
||||||
|
#define TARGET_SUBTARGET64_DEFAULT \
|
||||||
|
MASK_128BIT_LONG_DOUBLE
|
|
@ -0,0 +1,108 @@
|
||||||
|
/* OS independent definitions for AMD x86-64.
|
||||||
|
Copyright (C) 2001-2013 Free Software Foundation, Inc.
|
||||||
|
Contributed by Bo Thorsen <bo@suse.de>.
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
Under Section 7 of GPL version 3, you are granted additional
|
||||||
|
permissions described in the GCC Runtime Library Exception, version
|
||||||
|
3.1, as published by the Free Software Foundation.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License and
|
||||||
|
a copy of the GCC Runtime Library Exception along with this program;
|
||||||
|
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#undef ASM_COMMENT_START
|
||||||
|
#define ASM_COMMENT_START "#"
|
||||||
|
|
||||||
|
#undef DBX_REGISTER_NUMBER
|
||||||
|
#define DBX_REGISTER_NUMBER(n) \
|
||||||
|
(TARGET_64BIT ? dbx64_register_map[n] : svr4_dbx_register_map[n])
|
||||||
|
|
||||||
|
/* Output assembler code to FILE to call the profiler. */
|
||||||
|
#define NO_PROFILE_COUNTERS 1
|
||||||
|
|
||||||
|
#undef MCOUNT_NAME
|
||||||
|
#define MCOUNT_NAME "mcount"
|
||||||
|
|
||||||
|
#undef SIZE_TYPE
|
||||||
|
#define SIZE_TYPE (TARGET_LP64 ? "long unsigned int" : "unsigned int")
|
||||||
|
|
||||||
|
#undef PTRDIFF_TYPE
|
||||||
|
#define PTRDIFF_TYPE (TARGET_LP64 ? "long int" : "int")
|
||||||
|
|
||||||
|
#undef WCHAR_TYPE
|
||||||
|
#define WCHAR_TYPE "int"
|
||||||
|
|
||||||
|
#undef WCHAR_TYPE_SIZE
|
||||||
|
#define WCHAR_TYPE_SIZE 32
|
||||||
|
|
||||||
|
#undef ASM_SPEC
|
||||||
|
#define ASM_SPEC "%{m32:--32} %{m64:--64}"
|
||||||
|
|
||||||
|
#undef ASM_OUTPUT_ALIGNED_BSS
|
||||||
|
#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \
|
||||||
|
x86_output_aligned_bss (FILE, DECL, NAME, SIZE, ALIGN)
|
||||||
|
|
||||||
|
#undef ASM_OUTPUT_ALIGNED_COMMON
|
||||||
|
#define ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGN) \
|
||||||
|
x86_elf_aligned_common (FILE, NAME, SIZE, ALIGN);
|
||||||
|
|
||||||
|
/* This is used to align code labels according to Intel recommendations. */
|
||||||
|
|
||||||
|
#ifdef HAVE_GAS_MAX_SKIP_P2ALIGN
|
||||||
|
#define ASM_OUTPUT_MAX_SKIP_ALIGN(FILE,LOG,MAX_SKIP) \
|
||||||
|
do { \
|
||||||
|
if ((LOG) != 0) { \
|
||||||
|
if ((MAX_SKIP) == 0) fprintf ((FILE), "\t.p2align %d\n", (LOG)); \
|
||||||
|
else { \
|
||||||
|
fprintf ((FILE), "\t.p2align %d,,%d\n", (LOG), (MAX_SKIP)); \
|
||||||
|
/* Make sure that we have at least 8 byte alignment if > 8 byte \
|
||||||
|
alignment is preferred. */ \
|
||||||
|
if ((LOG) > 3 \
|
||||||
|
&& (1 << (LOG)) > ((MAX_SKIP) + 1) \
|
||||||
|
&& (MAX_SKIP) >= 7) \
|
||||||
|
fputs ("\t.p2align 3\n", (FILE)); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
#undef ASM_OUTPUT_MAX_SKIP_PAD
|
||||||
|
#define ASM_OUTPUT_MAX_SKIP_PAD(FILE, LOG, MAX_SKIP) \
|
||||||
|
if ((LOG) != 0) \
|
||||||
|
{ \
|
||||||
|
if ((MAX_SKIP) == 0) \
|
||||||
|
fprintf ((FILE), "\t.p2align %d\n", (LOG)); \
|
||||||
|
else \
|
||||||
|
fprintf ((FILE), "\t.p2align %d,,%d\n", (LOG), (MAX_SKIP)); \
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* i386 System V Release 4 uses DWARF debugging info.
|
||||||
|
x86-64 ABI specifies DWARF2. */
|
||||||
|
|
||||||
|
#define DWARF2_DEBUGGING_INFO 1
|
||||||
|
#define DWARF2_UNWIND_INFO 1
|
||||||
|
|
||||||
|
#undef PREFERRED_DEBUGGING_TYPE
|
||||||
|
#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
|
||||||
|
|
||||||
|
#undef TARGET_ASM_SELECT_SECTION
|
||||||
|
#define TARGET_ASM_SELECT_SECTION x86_64_elf_select_section
|
||||||
|
|
||||||
|
#undef TARGET_ASM_UNIQUE_SECTION
|
||||||
|
#define TARGET_ASM_UNIQUE_SECTION x86_64_elf_unique_section
|
||||||
|
|
||||||
|
#undef TARGET_SECTION_TYPE_FLAGS
|
||||||
|
#define TARGET_SECTION_TYPE_FLAGS x86_64_elf_section_type_flags
|
|
@ -0,0 +1,40 @@
|
||||||
|
/* Definitions for ELF systems with .init_array/.fini_array section
|
||||||
|
support.
|
||||||
|
Copyright (C) 2011-2013 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published
|
||||||
|
by the Free Software Foundation; either version 3, or (at your
|
||||||
|
option) any later version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||||
|
License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GCC; see the file COPYING3. If not see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#ifdef HAVE_INITFINI_ARRAY_SUPPORT
|
||||||
|
|
||||||
|
#define USE_INITFINI_ARRAY
|
||||||
|
|
||||||
|
#undef INIT_SECTION_ASM_OP
|
||||||
|
#undef FINI_SECTION_ASM_OP
|
||||||
|
|
||||||
|
#undef INIT_ARRAY_SECTION_ASM_OP
|
||||||
|
#define INIT_ARRAY_SECTION_ASM_OP
|
||||||
|
|
||||||
|
#undef FINI_ARRAY_SECTION_ASM_OP
|
||||||
|
#define FINI_ARRAY_SECTION_ASM_OP
|
||||||
|
|
||||||
|
/* Use .init_array/.fini_array section for constructors and destructors. */
|
||||||
|
#undef TARGET_ASM_CONSTRUCTOR
|
||||||
|
#define TARGET_ASM_CONSTRUCTOR default_elf_init_array_asm_out_constructor
|
||||||
|
#undef TARGET_ASM_DESTRUCTOR
|
||||||
|
#define TARGET_ASM_DESTRUCTOR default_elf_fini_array_asm_out_destructor
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,59 @@
|
||||||
|
/* Configuration file for Linux Android targets.
|
||||||
|
Copyright (C) 2008-2013 Free Software Foundation, Inc.
|
||||||
|
Contributed by Doug Kwan (dougkwan@google.com)
|
||||||
|
Rewritten by CodeSourcery, Inc.
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published
|
||||||
|
by the Free Software Foundation; either version 3, or (at your
|
||||||
|
option) any later version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||||
|
License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GCC; see the file COPYING3. If not see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#define ANDROID_TARGET_OS_CPP_BUILTINS() \
|
||||||
|
do { \
|
||||||
|
if (TARGET_ANDROID) \
|
||||||
|
builtin_define ("__ANDROID__"); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#if ANDROID_DEFAULT
|
||||||
|
# define NOANDROID "mno-android"
|
||||||
|
#else
|
||||||
|
# define NOANDROID "!mandroid"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define LINUX_OR_ANDROID_CC(LINUX_SPEC, ANDROID_SPEC) \
|
||||||
|
"%{" NOANDROID "|tno-android-cc:" LINUX_SPEC ";:" ANDROID_SPEC "}"
|
||||||
|
|
||||||
|
#define LINUX_OR_ANDROID_LD(LINUX_SPEC, ANDROID_SPEC) \
|
||||||
|
"%{" NOANDROID "|tno-android-ld:" LINUX_SPEC ";:" ANDROID_SPEC "}"
|
||||||
|
|
||||||
|
#define ANDROID_LINK_SPEC \
|
||||||
|
"%{shared: -Bsymbolic}"
|
||||||
|
|
||||||
|
#define ANDROID_CC1_SPEC \
|
||||||
|
"%{!mglibc:%{!muclibc:%{!mbionic: -mbionic}}} " \
|
||||||
|
"%{!fno-pic:%{!fno-PIC:%{!fpic:%{!fPIC: -fPIC}}}}"
|
||||||
|
|
||||||
|
#define ANDROID_CC1PLUS_SPEC \
|
||||||
|
"%{!fexceptions:%{!fno-exceptions: -fno-exceptions}} " \
|
||||||
|
"%{!frtti:%{!fno-rtti: -fno-rtti}}"
|
||||||
|
|
||||||
|
#define ANDROID_LIB_SPEC \
|
||||||
|
"%{!static: -ldl}"
|
||||||
|
|
||||||
|
#define ANDROID_STARTFILE_SPEC \
|
||||||
|
"%{shared: crtbegin_so%O%s;:" \
|
||||||
|
" %{static: crtbegin_static%O%s;: crtbegin_dynamic%O%s}}"
|
||||||
|
|
||||||
|
#define ANDROID_ENDFILE_SPEC \
|
||||||
|
"%{shared: crtend_so%O%s;: crtend_android%O%s}"
|
|
@ -0,0 +1,109 @@
|
||||||
|
/* Definitions for systems using the Linux kernel, with or without
|
||||||
|
MMU, using ELF at the compiler level but possibly FLT for final
|
||||||
|
linked executables and shared libraries in some no-MMU cases, and
|
||||||
|
possibly with a choice of libc implementations.
|
||||||
|
Copyright (C) 1995-2013 Free Software Foundation, Inc.
|
||||||
|
Contributed by Eric Youngdale.
|
||||||
|
Modified for stabs-in-ELF by H.J. Lu (hjl@lucon.org).
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
Under Section 7 of GPL version 3, you are granted additional
|
||||||
|
permissions described in the GCC Runtime Library Exception, version
|
||||||
|
3.1, as published by the Free Software Foundation.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License and
|
||||||
|
a copy of the GCC Runtime Library Exception along with this program;
|
||||||
|
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
/* C libraries supported on Linux. */
|
||||||
|
#ifdef SINGLE_LIBC
|
||||||
|
#define OPTION_GLIBC (DEFAULT_LIBC == LIBC_GLIBC)
|
||||||
|
#define OPTION_UCLIBC (DEFAULT_LIBC == LIBC_UCLIBC)
|
||||||
|
#define OPTION_BIONIC (DEFAULT_LIBC == LIBC_BIONIC)
|
||||||
|
#else
|
||||||
|
#define OPTION_GLIBC (linux_libc == LIBC_GLIBC)
|
||||||
|
#define OPTION_UCLIBC (linux_libc == LIBC_UCLIBC)
|
||||||
|
#define OPTION_BIONIC (linux_libc == LIBC_BIONIC)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define GNU_USER_TARGET_OS_CPP_BUILTINS() \
|
||||||
|
do { \
|
||||||
|
if (OPTION_GLIBC) \
|
||||||
|
builtin_define ("__gnu_linux__"); \
|
||||||
|
builtin_define_std ("linux"); \
|
||||||
|
builtin_define_std ("unix"); \
|
||||||
|
builtin_assert ("system=linux"); \
|
||||||
|
builtin_assert ("system=unix"); \
|
||||||
|
builtin_assert ("system=posix"); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/* Determine which dynamic linker to use depending on whether GLIBC or
|
||||||
|
uClibc or Bionic is the default C library and whether
|
||||||
|
-muclibc or -mglibc or -mbionic has been passed to change the default. */
|
||||||
|
|
||||||
|
#define CHOOSE_DYNAMIC_LINKER1(LIBC1, LIBC2, LIBC3, LD1, LD2, LD3) \
|
||||||
|
"%{" LIBC2 ":" LD2 ";:%{" LIBC3 ":" LD3 ";:" LD1 "}}"
|
||||||
|
|
||||||
|
#if DEFAULT_LIBC == LIBC_GLIBC
|
||||||
|
#define CHOOSE_DYNAMIC_LINKER(G, U, B) \
|
||||||
|
CHOOSE_DYNAMIC_LINKER1 ("mglibc", "muclibc", "mbionic", G, U, B)
|
||||||
|
#elif DEFAULT_LIBC == LIBC_UCLIBC
|
||||||
|
#define CHOOSE_DYNAMIC_LINKER(G, U, B) \
|
||||||
|
CHOOSE_DYNAMIC_LINKER1 ("muclibc", "mglibc", "mbionic", U, G, B)
|
||||||
|
#elif DEFAULT_LIBC == LIBC_BIONIC
|
||||||
|
#define CHOOSE_DYNAMIC_LINKER(G, U, B) \
|
||||||
|
CHOOSE_DYNAMIC_LINKER1 ("mbionic", "mglibc", "muclibc", B, G, U)
|
||||||
|
#else
|
||||||
|
#error "Unsupported DEFAULT_LIBC"
|
||||||
|
#endif /* DEFAULT_LIBC */
|
||||||
|
|
||||||
|
/* For most targets the following definitions suffice;
|
||||||
|
GLIBC_DYNAMIC_LINKER must be defined for each target using them, or
|
||||||
|
GLIBC_DYNAMIC_LINKER32 and GLIBC_DYNAMIC_LINKER64 for targets
|
||||||
|
supporting both 32-bit and 64-bit compilation. */
|
||||||
|
#define UCLIBC_DYNAMIC_LINKER "/lib/ld-uClibc.so.0"
|
||||||
|
#define UCLIBC_DYNAMIC_LINKER32 "/lib/ld-uClibc.so.0"
|
||||||
|
#define UCLIBC_DYNAMIC_LINKER64 "/lib/ld64-uClibc.so.0"
|
||||||
|
#define UCLIBC_DYNAMIC_LINKERX32 "/lib/ldx32-uClibc.so.0"
|
||||||
|
#define BIONIC_DYNAMIC_LINKER "/system/bin/linker"
|
||||||
|
#define BIONIC_DYNAMIC_LINKER32 "/system/bin/linker"
|
||||||
|
#define BIONIC_DYNAMIC_LINKER64 "/system/bin/linker64"
|
||||||
|
#define BIONIC_DYNAMIC_LINKERX32 "/system/bin/linkerx32"
|
||||||
|
|
||||||
|
#define GNU_USER_DYNAMIC_LINKER \
|
||||||
|
CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKER, UCLIBC_DYNAMIC_LINKER, \
|
||||||
|
BIONIC_DYNAMIC_LINKER)
|
||||||
|
#define GNU_USER_DYNAMIC_LINKER32 \
|
||||||
|
CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKER32, UCLIBC_DYNAMIC_LINKER32, \
|
||||||
|
BIONIC_DYNAMIC_LINKER32)
|
||||||
|
#define GNU_USER_DYNAMIC_LINKER64 \
|
||||||
|
CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKER64, UCLIBC_DYNAMIC_LINKER64, \
|
||||||
|
BIONIC_DYNAMIC_LINKER64)
|
||||||
|
#define GNU_USER_DYNAMIC_LINKERX32 \
|
||||||
|
CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKERX32, UCLIBC_DYNAMIC_LINKERX32, \
|
||||||
|
BIONIC_DYNAMIC_LINKERX32)
|
||||||
|
|
||||||
|
/* Determine whether the entire c99 runtime
|
||||||
|
is present in the runtime library. */
|
||||||
|
#undef TARGET_C99_FUNCTIONS
|
||||||
|
#define TARGET_C99_FUNCTIONS (OPTION_GLIBC)
|
||||||
|
|
||||||
|
/* Whether we have sincos that follows the GNU extension. */
|
||||||
|
#undef TARGET_HAS_SINCOS
|
||||||
|
#define TARGET_HAS_SINCOS (OPTION_GLIBC || OPTION_BIONIC)
|
||||||
|
|
||||||
|
/* Whether we have Bionic libc runtime */
|
||||||
|
#undef TARGET_HAS_BIONIC
|
||||||
|
#define TARGET_HAS_BIONIC (OPTION_BIONIC)
|
|
@ -0,0 +1,40 @@
|
||||||
|
/* Dummy definitions of VxWorks-related macros
|
||||||
|
Copyright (C) 2007-2013 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free
|
||||||
|
Software Foundation; either version 3, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
Under Section 7 of GPL version 3, you are granted additional
|
||||||
|
permissions described in the GCC Runtime Library Exception, version
|
||||||
|
3.1, as published by the Free Software Foundation.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License and
|
||||||
|
a copy of the GCC Runtime Library Exception along with this program;
|
||||||
|
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
/* True if we're targeting VxWorks. */
|
||||||
|
#ifndef TARGET_VXWORKS
|
||||||
|
#define TARGET_VXWORKS 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* True if generating code for a VxWorks RTP. */
|
||||||
|
#ifndef TARGET_VXWORKS_RTP
|
||||||
|
#define TARGET_VXWORKS_RTP false
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* The symbol that points to an RTP's table of GOTs. */
|
||||||
|
#define VXWORKS_GOTT_BASE (gcc_unreachable (), "")
|
||||||
|
|
||||||
|
/* The symbol that holds the index of the current module's GOT in
|
||||||
|
VXWORKS_GOTT_BASE. */
|
||||||
|
#define VXWORKS_GOTT_INDEX (gcc_unreachable (), "")
|
|
@ -0,0 +1,7 @@
|
||||||
|
/* Generated automatically. */
|
||||||
|
static const char configuration_arguments[] = "../configure --prefix=/home/zet/bin/gcc-48 --disable-bootstrap --enable-languages=c,c++ --enable-shared --enable-threads=posix --enable-lto --enable-plugin --enable-gold=yes --without-included-gettext --enable-nls --disable-libmudflap --disable-browser-plugin --disable-werror";
|
||||||
|
static const char thread_model[] = "posix";
|
||||||
|
|
||||||
|
static const struct {
|
||||||
|
const char *name, *value;
|
||||||
|
} configure_default_options[] = { { "cpu", "generic" }, { "arch", "x86-64" } };
|
|
@ -0,0 +1,208 @@
|
||||||
|
/* GCC core type declarations.
|
||||||
|
Copyright (C) 2002-2013 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free
|
||||||
|
Software Foundation; either version 3, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
Under Section 7 of GPL version 3, you are granted additional
|
||||||
|
permissions described in the GCC Runtime Library Exception, version
|
||||||
|
3.1, as published by the Free Software Foundation.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License and
|
||||||
|
a copy of the GCC Runtime Library Exception along with this program;
|
||||||
|
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
/* Provide forward declarations of core types which are referred to by
|
||||||
|
most of the compiler. This allows header files to use these types
|
||||||
|
(e.g. in function prototypes) without concern for whether the full
|
||||||
|
definitions are visible. Some other declarations that need to be
|
||||||
|
universally visible are here, too.
|
||||||
|
|
||||||
|
In the context of tconfig.h, most of these have special definitions
|
||||||
|
which prevent them from being used except in further type
|
||||||
|
declarations. This is a kludge; the right thing is to avoid
|
||||||
|
including the "tm.h" header set in the context of tconfig.h, but
|
||||||
|
we're not there yet. */
|
||||||
|
|
||||||
|
#ifndef GCC_CORETYPES_H
|
||||||
|
#define GCC_CORETYPES_H
|
||||||
|
|
||||||
|
#ifndef GTY
|
||||||
|
#define GTY(x) /* nothing - marker for gengtype */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef USED_FOR_TARGET
|
||||||
|
|
||||||
|
struct bitmap_head_def;
|
||||||
|
typedef struct bitmap_head_def *bitmap;
|
||||||
|
typedef const struct bitmap_head_def *const_bitmap;
|
||||||
|
struct simple_bitmap_def;
|
||||||
|
typedef struct simple_bitmap_def *sbitmap;
|
||||||
|
typedef const struct simple_bitmap_def *const_sbitmap;
|
||||||
|
struct rtx_def;
|
||||||
|
typedef struct rtx_def *rtx;
|
||||||
|
typedef const struct rtx_def *const_rtx;
|
||||||
|
struct rtvec_def;
|
||||||
|
typedef struct rtvec_def *rtvec;
|
||||||
|
typedef const struct rtvec_def *const_rtvec;
|
||||||
|
union tree_node;
|
||||||
|
typedef union tree_node *tree;
|
||||||
|
typedef const union tree_node *const_tree;
|
||||||
|
union gimple_statement_d;
|
||||||
|
typedef union gimple_statement_d *gimple;
|
||||||
|
typedef const union gimple_statement_d *const_gimple;
|
||||||
|
typedef gimple gimple_seq;
|
||||||
|
union section;
|
||||||
|
typedef union section section;
|
||||||
|
struct gcc_options;
|
||||||
|
struct cl_target_option;
|
||||||
|
struct cl_optimization;
|
||||||
|
struct cl_option;
|
||||||
|
struct cl_decoded_option;
|
||||||
|
struct cl_option_handlers;
|
||||||
|
struct diagnostic_context;
|
||||||
|
typedef struct diagnostic_context diagnostic_context;
|
||||||
|
struct pretty_print_info;
|
||||||
|
typedef struct pretty_print_info pretty_printer;
|
||||||
|
|
||||||
|
/* Address space number for named address space support. */
|
||||||
|
typedef unsigned char addr_space_t;
|
||||||
|
|
||||||
|
/* The value of addr_space_t that represents the generic address space. */
|
||||||
|
#define ADDR_SPACE_GENERIC 0
|
||||||
|
#define ADDR_SPACE_GENERIC_P(AS) ((AS) == ADDR_SPACE_GENERIC)
|
||||||
|
|
||||||
|
/* The major intermediate representations of GCC. */
|
||||||
|
enum ir_type {
|
||||||
|
IR_GIMPLE,
|
||||||
|
IR_RTL_CFGRTL,
|
||||||
|
IR_RTL_CFGLAYOUT
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Provide forward struct declaration so that we don't have to include
|
||||||
|
all of cpplib.h whenever a random prototype includes a pointer.
|
||||||
|
Note that the cpp_reader and cpp_token typedefs remain part of
|
||||||
|
cpplib.h. */
|
||||||
|
|
||||||
|
struct cpp_reader;
|
||||||
|
struct cpp_token;
|
||||||
|
|
||||||
|
/* The thread-local storage model associated with a given VAR_DECL
|
||||||
|
or SYMBOL_REF. This isn't used much, but both trees and RTL refer
|
||||||
|
to it, so it's here. */
|
||||||
|
enum tls_model {
|
||||||
|
TLS_MODEL_NONE,
|
||||||
|
TLS_MODEL_EMULATED,
|
||||||
|
TLS_MODEL_REAL,
|
||||||
|
TLS_MODEL_GLOBAL_DYNAMIC = TLS_MODEL_REAL,
|
||||||
|
TLS_MODEL_LOCAL_DYNAMIC,
|
||||||
|
TLS_MODEL_INITIAL_EXEC,
|
||||||
|
TLS_MODEL_LOCAL_EXEC
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Types of unwind/exception handling info that can be generated. */
|
||||||
|
|
||||||
|
enum unwind_info_type
|
||||||
|
{
|
||||||
|
UI_NONE,
|
||||||
|
UI_SJLJ,
|
||||||
|
UI_DWARF2,
|
||||||
|
UI_TARGET,
|
||||||
|
UI_SEH
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Callgraph node profile representation. */
|
||||||
|
enum node_frequency {
|
||||||
|
/* This function most likely won't be executed at all.
|
||||||
|
(set only when profile feedback is available or via function attribute). */
|
||||||
|
NODE_FREQUENCY_UNLIKELY_EXECUTED,
|
||||||
|
/* For functions that are known to be executed once (i.e. constructors, destructors
|
||||||
|
and main function. */
|
||||||
|
NODE_FREQUENCY_EXECUTED_ONCE,
|
||||||
|
/* The default value. */
|
||||||
|
NODE_FREQUENCY_NORMAL,
|
||||||
|
/* Optimize this function hard
|
||||||
|
(set only when profile feedback is available or via function attribute). */
|
||||||
|
NODE_FREQUENCY_HOT
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Possible initialization status of a variable. When requested
|
||||||
|
by the user, this information is tracked and recorded in the DWARF
|
||||||
|
debug information, along with the variable's location. */
|
||||||
|
enum var_init_status
|
||||||
|
{
|
||||||
|
VAR_INIT_STATUS_UNKNOWN,
|
||||||
|
VAR_INIT_STATUS_UNINITIALIZED,
|
||||||
|
VAR_INIT_STATUS_INITIALIZED
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct edge_def;
|
||||||
|
typedef struct edge_def *edge;
|
||||||
|
typedef const struct edge_def *const_edge;
|
||||||
|
struct basic_block_def;
|
||||||
|
typedef struct basic_block_def *basic_block;
|
||||||
|
typedef const struct basic_block_def *const_basic_block;
|
||||||
|
|
||||||
|
#define obstack_chunk_alloc ((void *(*) (long)) xmalloc)
|
||||||
|
#define obstack_chunk_free ((void (*) (void *)) free)
|
||||||
|
#define OBSTACK_CHUNK_SIZE 0
|
||||||
|
#define gcc_obstack_init(OBSTACK) \
|
||||||
|
_obstack_begin ((OBSTACK), OBSTACK_CHUNK_SIZE, 0, \
|
||||||
|
obstack_chunk_alloc, \
|
||||||
|
obstack_chunk_free)
|
||||||
|
|
||||||
|
/* enum reg_class is target specific, so it should not appear in
|
||||||
|
target-independent code or interfaces, like the target hook declarations
|
||||||
|
in target.h. */
|
||||||
|
typedef int reg_class_t;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
struct _dont_use_rtx_here_;
|
||||||
|
struct _dont_use_rtvec_here_;
|
||||||
|
union _dont_use_tree_here_;
|
||||||
|
#define rtx struct _dont_use_rtx_here_ *
|
||||||
|
#define const_rtx struct _dont_use_rtx_here_ *
|
||||||
|
#define rtvec struct _dont_use_rtvec_here *
|
||||||
|
#define const_rtvec struct _dont_use_rtvec_here *
|
||||||
|
#define tree union _dont_use_tree_here_ *
|
||||||
|
#define const_tree union _dont_use_tree_here_ *
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Memory model types for the __atomic* builtins.
|
||||||
|
This must match the order in libstdc++-v3/include/bits/atomic_base.h. */
|
||||||
|
enum memmodel
|
||||||
|
{
|
||||||
|
MEMMODEL_RELAXED = 0,
|
||||||
|
MEMMODEL_CONSUME = 1,
|
||||||
|
MEMMODEL_ACQUIRE = 2,
|
||||||
|
MEMMODEL_RELEASE = 3,
|
||||||
|
MEMMODEL_ACQ_REL = 4,
|
||||||
|
MEMMODEL_SEQ_CST = 5,
|
||||||
|
MEMMODEL_LAST = 6
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Suppose that higher bits are target dependant. */
|
||||||
|
#define MEMMODEL_MASK ((1<<16)-1)
|
||||||
|
|
||||||
|
/* Support for user-provided GGC and PCH markers. The first parameter
|
||||||
|
is a pointer to a pointer, the second a cookie. */
|
||||||
|
typedef void (*gt_pointer_operator) (void *, void *);
|
||||||
|
|
||||||
|
#if !defined (HAVE_UCHAR)
|
||||||
|
typedef unsigned char uchar;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* coretypes.h */
|
|
@ -0,0 +1,479 @@
|
||||||
|
/* This file contains the definitions and documentation for the
|
||||||
|
additional tree codes used in the GNU C++ compiler (see tree.def
|
||||||
|
for the standard codes).
|
||||||
|
Copyright (C) 1987-2013 Free Software Foundation, Inc.
|
||||||
|
Hacked by Michael Tiemann (tiemann@cygnus.com)
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GCC; see the file COPYING3. If not see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
|
||||||
|
/* An OFFSET_REF is used in two situations:
|
||||||
|
|
||||||
|
1. An expression of the form `A::m' where `A' is a class and `m' is
|
||||||
|
a non-static member. In this case, operand 0 will be a TYPE
|
||||||
|
(corresponding to `A') and operand 1 will be a FIELD_DECL,
|
||||||
|
BASELINK, or TEMPLATE_ID_EXPR (corresponding to `m').
|
||||||
|
|
||||||
|
The expression is a pointer-to-member if its address is taken,
|
||||||
|
but simply denotes a member of the object if its address is not
|
||||||
|
taken.
|
||||||
|
|
||||||
|
This form is only used during the parsing phase; once semantic
|
||||||
|
analysis has taken place they are eliminated.
|
||||||
|
|
||||||
|
2. An expression of the form `x.*p'. In this case, operand 0 will
|
||||||
|
be an expression corresponding to `x' and operand 1 will be an
|
||||||
|
expression with pointer-to-member type. */
|
||||||
|
DEFTREECODE (OFFSET_REF, "offset_ref", tcc_reference, 2)
|
||||||
|
|
||||||
|
/* A pointer-to-member constant. For a pointer-to-member constant
|
||||||
|
`X::Y' The PTRMEM_CST_CLASS is the RECORD_TYPE for `X' and the
|
||||||
|
PTRMEM_CST_MEMBER is the _DECL for `Y'. */
|
||||||
|
DEFTREECODE (PTRMEM_CST, "ptrmem_cst", tcc_constant, 0)
|
||||||
|
|
||||||
|
/* For NEW_EXPR, operand 0 is the placement list.
|
||||||
|
Operand 1 is the new-declarator.
|
||||||
|
Operand 2 is the number of elements in the array.
|
||||||
|
Operand 3 is the initializer. */
|
||||||
|
DEFTREECODE (NEW_EXPR, "nw_expr", tcc_expression, 4)
|
||||||
|
DEFTREECODE (VEC_NEW_EXPR, "vec_nw_expr", tcc_expression, 3)
|
||||||
|
|
||||||
|
/* For DELETE_EXPR, operand 0 is the store to be destroyed.
|
||||||
|
Operand 1 is the value to pass to the destroying function
|
||||||
|
saying whether the store should be deallocated as well. */
|
||||||
|
DEFTREECODE (DELETE_EXPR, "dl_expr", tcc_expression, 2)
|
||||||
|
DEFTREECODE (VEC_DELETE_EXPR, "vec_dl_expr", tcc_expression, 2)
|
||||||
|
|
||||||
|
/* Value is reference to particular overloaded class method.
|
||||||
|
Operand 0 is the class, operand 1 is the field
|
||||||
|
The COMPLEXITY field holds the class level (usually 0). */
|
||||||
|
DEFTREECODE (SCOPE_REF, "scope_ref", tcc_reference, 2)
|
||||||
|
|
||||||
|
/* When composing an object with a member, this is the result.
|
||||||
|
Operand 0 is the object. Operand 1 is the member (usually
|
||||||
|
a dereferenced pointer to member). */
|
||||||
|
DEFTREECODE (MEMBER_REF, "member_ref", tcc_reference, 2)
|
||||||
|
|
||||||
|
/* Type conversion operator in C++. TREE_TYPE is type that this
|
||||||
|
operator converts to. Operand is expression to be converted. */
|
||||||
|
DEFTREECODE (TYPE_EXPR, "type_expr", tcc_expression, 1)
|
||||||
|
|
||||||
|
/* AGGR_INIT_EXPRs have a variably-sized representation similar to
|
||||||
|
that of CALL_EXPRs. Operand 0 is an INTEGER_CST node containing the
|
||||||
|
operand count, operand 1 is the function which performs initialization,
|
||||||
|
operand 2 is the slot which was allocated for this expression, and
|
||||||
|
the remaining operands are the arguments to the initialization function. */
|
||||||
|
DEFTREECODE (AGGR_INIT_EXPR, "aggr_init_expr", tcc_vl_exp, 3)
|
||||||
|
|
||||||
|
/* Initialization of an array from another array, expressed at a high level
|
||||||
|
so that it works with TARGET_EXPR. Operand 0 is the target, operand 1
|
||||||
|
is the initializer. */
|
||||||
|
DEFTREECODE (VEC_INIT_EXPR, "vec_init_expr", tcc_expression, 2)
|
||||||
|
|
||||||
|
/* A throw expression. operand 0 is the expression, if there was one,
|
||||||
|
else it is NULL_TREE. */
|
||||||
|
DEFTREECODE (THROW_EXPR, "throw_expr", tcc_expression, 1)
|
||||||
|
|
||||||
|
/* An empty class object. The TREE_TYPE gives the class type. We use
|
||||||
|
these to avoid actually creating instances of the empty classes. */
|
||||||
|
DEFTREECODE (EMPTY_CLASS_EXPR, "empty_class_expr", tcc_expression, 0)
|
||||||
|
|
||||||
|
/* A reference to a member function or member functions from a base
|
||||||
|
class. BASELINK_FUNCTIONS gives the FUNCTION_DECL,
|
||||||
|
TEMPLATE_DECL, OVERLOAD, or TEMPLATE_ID_EXPR corresponding to the
|
||||||
|
functions. BASELINK_BINFO gives the base from which the functions
|
||||||
|
come, i.e., the base to which the `this' pointer must be converted
|
||||||
|
before the functions are called. BASELINK_ACCESS_BINFO gives the
|
||||||
|
base used to name the functions.
|
||||||
|
|
||||||
|
A BASELINK is an expression; the TREE_TYPE of the BASELINK gives
|
||||||
|
the type of the expression. This type is either a FUNCTION_TYPE,
|
||||||
|
METHOD_TYPE, or `unknown_type_node' indicating that the function is
|
||||||
|
overloaded. */
|
||||||
|
DEFTREECODE (BASELINK, "baselink", tcc_exceptional, 0)
|
||||||
|
|
||||||
|
/* Template definition. The following fields have the specified uses,
|
||||||
|
although there are other macros in cp-tree.h that should be used for
|
||||||
|
accessing this data.
|
||||||
|
DECL_ARGUMENTS template parm vector
|
||||||
|
DECL_TEMPLATE_INFO template text &c
|
||||||
|
DECL_VINDEX list of instantiations already produced;
|
||||||
|
only done for functions so far
|
||||||
|
For class template:
|
||||||
|
DECL_INITIAL associated templates (methods &c)
|
||||||
|
DECL_TEMPLATE_RESULT null
|
||||||
|
For non-class templates:
|
||||||
|
TREE_TYPE type of object to be constructed
|
||||||
|
DECL_TEMPLATE_RESULT decl for object to be created
|
||||||
|
(e.g., FUNCTION_DECL with tmpl parms used)
|
||||||
|
*/
|
||||||
|
DEFTREECODE (TEMPLATE_DECL, "template_decl", tcc_declaration, 0)
|
||||||
|
|
||||||
|
/* Index into a template parameter list. The TEMPLATE_PARM_IDX gives
|
||||||
|
the index (from 0) of the parameter, while the TEMPLATE_PARM_LEVEL
|
||||||
|
gives the level (from 1) of the parameter.
|
||||||
|
|
||||||
|
Here's an example:
|
||||||
|
|
||||||
|
template <class T> // Index 0, Level 1.
|
||||||
|
struct S
|
||||||
|
{
|
||||||
|
template <class U, // Index 0, Level 2.
|
||||||
|
class V> // Index 1, Level 2.
|
||||||
|
void f();
|
||||||
|
};
|
||||||
|
|
||||||
|
The DESCENDANTS will be a chain of TEMPLATE_PARM_INDEXs descended
|
||||||
|
from this one. The first descendant will have the same IDX, but
|
||||||
|
its LEVEL will be one less. The TREE_CHAIN field is used to chain
|
||||||
|
together the descendants. The TEMPLATE_PARM_DECL is the
|
||||||
|
declaration of this parameter, either a TYPE_DECL or CONST_DECL.
|
||||||
|
The TEMPLATE_PARM_ORIG_LEVEL is the LEVEL of the most distant
|
||||||
|
parent, i.e., the LEVEL that the parameter originally had when it
|
||||||
|
was declared. For example, if we instantiate S<int>, we will have:
|
||||||
|
|
||||||
|
struct S<int>
|
||||||
|
{
|
||||||
|
template <class U, // Index 0, Level 1, Orig Level 2
|
||||||
|
class V> // Index 1, Level 1, Orig Level 2
|
||||||
|
void f();
|
||||||
|
};
|
||||||
|
|
||||||
|
The LEVEL is the level of the parameter when we are worrying about
|
||||||
|
the types of things; the ORIG_LEVEL is the level when we are
|
||||||
|
worrying about instantiating things. */
|
||||||
|
DEFTREECODE (TEMPLATE_PARM_INDEX, "template_parm_index", tcc_exceptional, 0)
|
||||||
|
|
||||||
|
/* Index into a template parameter list for template template parameters.
|
||||||
|
This parameter must be a type. The TYPE_FIELDS value will be a
|
||||||
|
TEMPLATE_PARM_INDEX.
|
||||||
|
|
||||||
|
It is used without template arguments like TT in C<TT>,
|
||||||
|
TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO is NULL_TREE
|
||||||
|
and TYPE_NAME is a TEMPLATE_DECL. */
|
||||||
|
DEFTREECODE (TEMPLATE_TEMPLATE_PARM, "template_template_parm", tcc_type, 0)
|
||||||
|
|
||||||
|
/* The ordering of the following codes is optimized for the checking
|
||||||
|
macros in tree.h. Changing the order will degrade the speed of the
|
||||||
|
compiler. TEMPLATE_TYPE_PARM, TYPENAME_TYPE, TYPEOF_TYPE,
|
||||||
|
BOUND_TEMPLATE_TEMPLATE_PARM. */
|
||||||
|
|
||||||
|
/* Index into a template parameter list. This parameter must be a type.
|
||||||
|
The type.values field will be a TEMPLATE_PARM_INDEX. */
|
||||||
|
DEFTREECODE (TEMPLATE_TYPE_PARM, "template_type_parm", tcc_type, 0)
|
||||||
|
|
||||||
|
/* A type designated by `typename T::t'. TYPE_CONTEXT is `T',
|
||||||
|
TYPE_NAME is an IDENTIFIER_NODE for `t'. If the type was named via
|
||||||
|
template-id, TYPENAME_TYPE_FULLNAME will hold the TEMPLATE_ID_EXPR.
|
||||||
|
TREE_TYPE is always NULL. */
|
||||||
|
DEFTREECODE (TYPENAME_TYPE, "typename_type", tcc_type, 0)
|
||||||
|
|
||||||
|
/* A type designated by `__typeof (expr)'. TYPEOF_TYPE_EXPR is the
|
||||||
|
expression in question. */
|
||||||
|
DEFTREECODE (TYPEOF_TYPE, "typeof_type", tcc_type, 0)
|
||||||
|
|
||||||
|
/* Like TEMPLATE_TEMPLATE_PARM it is used with bound template arguments
|
||||||
|
like TT<int>.
|
||||||
|
In this case, TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO contains the
|
||||||
|
template name and its bound arguments. TYPE_NAME is a TYPE_DECL. */
|
||||||
|
DEFTREECODE (BOUND_TEMPLATE_TEMPLATE_PARM, "bound_template_template_parm",
|
||||||
|
tcc_type, 0)
|
||||||
|
|
||||||
|
/* For template template argument of the form `T::template C'.
|
||||||
|
TYPE_CONTEXT is `T', the template parameter dependent object.
|
||||||
|
TYPE_NAME is an IDENTIFIER_NODE for `C', the member class template. */
|
||||||
|
DEFTREECODE (UNBOUND_CLASS_TEMPLATE, "unbound_class_template", tcc_type, 0)
|
||||||
|
|
||||||
|
/* A using declaration. USING_DECL_SCOPE contains the specified
|
||||||
|
scope. In a member using decl, unless DECL_DEPENDENT_P is true,
|
||||||
|
USING_DECL_DECLS contains the _DECL or OVERLOAD so named. This is
|
||||||
|
not an alias, but is later expanded into multiple aliases. */
|
||||||
|
DEFTREECODE (USING_DECL, "using_decl", tcc_declaration, 0)
|
||||||
|
|
||||||
|
/* A using directive. The operand is USING_STMT_NAMESPACE. */
|
||||||
|
DEFTREECODE (USING_STMT, "using_stmt", tcc_statement, 1)
|
||||||
|
|
||||||
|
/* An un-parsed default argument. Holds a vector of input tokens and
|
||||||
|
a vector of places where the argument was instantiated before
|
||||||
|
parsing had occurred. */
|
||||||
|
DEFTREECODE (DEFAULT_ARG, "default_arg", tcc_exceptional, 0)
|
||||||
|
|
||||||
|
/* An uninstantiated noexcept-specification. DEFERRED_NOEXCEPT_PATTERN is
|
||||||
|
the pattern from the template, and DEFERRED_NOEXCEPT_ARGS are the
|
||||||
|
template arguments to substitute into the pattern when needed. */
|
||||||
|
DEFTREECODE (DEFERRED_NOEXCEPT, "deferred_noexcept", tcc_exceptional, 0)
|
||||||
|
|
||||||
|
/* A template-id, like foo<int>. The first operand is the template.
|
||||||
|
The second is NULL if there are no explicit arguments, or a
|
||||||
|
TREE_VEC of arguments. The template will be a FUNCTION_DECL,
|
||||||
|
TEMPLATE_DECL, or an OVERLOAD. If the template-id refers to a
|
||||||
|
member template, the template may be an IDENTIFIER_NODE. */
|
||||||
|
DEFTREECODE (TEMPLATE_ID_EXPR, "template_id_expr", tcc_expression, 2)
|
||||||
|
|
||||||
|
/* A list-like node for chaining overloading candidates. TREE_TYPE is
|
||||||
|
the original name, and the parameter is the FUNCTION_DECL. */
|
||||||
|
DEFTREECODE (OVERLOAD, "overload", tcc_exceptional, 0)
|
||||||
|
|
||||||
|
/* A pseudo-destructor, of the form "OBJECT.~DESTRUCTOR" or
|
||||||
|
"OBJECT.SCOPE::~DESTRUCTOR. The first operand is the OBJECT. The
|
||||||
|
second operand (if non-NULL) is the SCOPE. The third operand is
|
||||||
|
the TYPE node corresponding to the DESTRUCTOR. The type of the
|
||||||
|
first operand will always be a scalar type.
|
||||||
|
|
||||||
|
The type of a PSEUDO_DTOR_EXPR is always "void", even though it can
|
||||||
|
be used as if it were a zero-argument function. We handle the
|
||||||
|
function-call case specially, and giving it "void" type prevents it
|
||||||
|
being used in expressions in ways that are not permitted. */
|
||||||
|
DEFTREECODE (PSEUDO_DTOR_EXPR, "pseudo_dtor_expr", tcc_expression, 3)
|
||||||
|
|
||||||
|
/* A whole bunch of tree codes for the initial, superficial parsing of
|
||||||
|
templates. */
|
||||||
|
DEFTREECODE (MODOP_EXPR, "modop_expr", tcc_expression, 3)
|
||||||
|
DEFTREECODE (CAST_EXPR, "cast_expr", tcc_unary, 1)
|
||||||
|
DEFTREECODE (REINTERPRET_CAST_EXPR, "reinterpret_cast_expr", tcc_unary, 1)
|
||||||
|
DEFTREECODE (CONST_CAST_EXPR, "const_cast_expr", tcc_unary, 1)
|
||||||
|
DEFTREECODE (STATIC_CAST_EXPR, "static_cast_expr", tcc_unary, 1)
|
||||||
|
DEFTREECODE (DYNAMIC_CAST_EXPR, "dynamic_cast_expr", tcc_unary, 1)
|
||||||
|
DEFTREECODE (IMPLICIT_CONV_EXPR, "implicit_conv_expr", tcc_unary, 1)
|
||||||
|
DEFTREECODE (DOTSTAR_EXPR, "dotstar_expr", tcc_expression, 2)
|
||||||
|
DEFTREECODE (TYPEID_EXPR, "typeid_expr", tcc_expression, 1)
|
||||||
|
DEFTREECODE (NOEXCEPT_EXPR, "noexcept_expr", tcc_unary, 1)
|
||||||
|
|
||||||
|
/* A placeholder for an expression that is not type-dependent, but
|
||||||
|
does occur in a template. When an expression that is not
|
||||||
|
type-dependent appears in a larger expression, we must compute the
|
||||||
|
type of that larger expression. That computation would normally
|
||||||
|
modify the original expression, which would change the mangling of
|
||||||
|
that expression if it appeared in a template argument list. In
|
||||||
|
that situation, we create a NON_DEPENDENT_EXPR to take the place of
|
||||||
|
the original expression. The expression is the only operand -- it
|
||||||
|
is only needed for diagnostics. */
|
||||||
|
DEFTREECODE (NON_DEPENDENT_EXPR, "non_dependent_expr", tcc_expression, 1)
|
||||||
|
|
||||||
|
/* CTOR_INITIALIZER is a placeholder in template code for a call to
|
||||||
|
setup_vtbl_pointer (and appears in all functions, not just ctors). */
|
||||||
|
DEFTREECODE (CTOR_INITIALIZER, "ctor_initializer", tcc_expression, 1)
|
||||||
|
|
||||||
|
DEFTREECODE (TRY_BLOCK, "try_block", tcc_statement, 2)
|
||||||
|
|
||||||
|
DEFTREECODE (EH_SPEC_BLOCK, "eh_spec_block", tcc_statement, 2)
|
||||||
|
|
||||||
|
/* A HANDLER wraps a catch handler for the HANDLER_TYPE. If this is
|
||||||
|
CATCH_ALL_TYPE, then the handler catches all types. The declaration of
|
||||||
|
the catch variable is in HANDLER_PARMS, and the body block in
|
||||||
|
HANDLER_BODY. */
|
||||||
|
DEFTREECODE (HANDLER, "handler", tcc_statement, 2)
|
||||||
|
|
||||||
|
/* A MUST_NOT_THROW_EXPR wraps an expression that may not
|
||||||
|
throw, and must call terminate if it does. The second argument
|
||||||
|
is a condition, used in templates to express noexcept (condition). */
|
||||||
|
DEFTREECODE (MUST_NOT_THROW_EXPR, "must_not_throw_expr", tcc_expression, 2)
|
||||||
|
|
||||||
|
/* A CLEANUP_STMT marks the point at which a declaration is fully
|
||||||
|
constructed. The CLEANUP_EXPR is run on behalf of CLEANUP_DECL
|
||||||
|
when CLEANUP_BODY completes. */
|
||||||
|
DEFTREECODE (CLEANUP_STMT, "cleanup_stmt", tcc_statement, 3)
|
||||||
|
|
||||||
|
/* Represents an 'if' statement. The operands are IF_COND,
|
||||||
|
THEN_CLAUSE, and ELSE_CLAUSE, and the current scope, respectively. */
|
||||||
|
/* ??? It is currently still necessary to distinguish between IF_STMT
|
||||||
|
and COND_EXPR for the benefit of templates. */
|
||||||
|
DEFTREECODE (IF_STMT, "if_stmt", tcc_statement, 4)
|
||||||
|
|
||||||
|
/* Used to represent a `for' statement. The operands are
|
||||||
|
FOR_INIT_STMT, FOR_COND, FOR_EXPR, and FOR_BODY, respectively. */
|
||||||
|
DEFTREECODE (FOR_STMT, "for_stmt", tcc_statement, 5)
|
||||||
|
|
||||||
|
/* Used to represent a range-based `for' statement. The operands are
|
||||||
|
RANGE_FOR_DECL, RANGE_FOR_EXPR, RANGE_FOR_BODY, and RANGE_FOR_SCOPE,
|
||||||
|
respectively. Only used in templates. */
|
||||||
|
DEFTREECODE (RANGE_FOR_STMT, "range_for_stmt", tcc_statement, 4)
|
||||||
|
|
||||||
|
/* Used to represent a 'while' statement. The operands are WHILE_COND
|
||||||
|
and WHILE_BODY, respectively. */
|
||||||
|
DEFTREECODE (WHILE_STMT, "while_stmt", tcc_statement, 2)
|
||||||
|
|
||||||
|
/* Used to represent a 'do' statement. The operands are DO_BODY and
|
||||||
|
DO_COND, respectively. */
|
||||||
|
DEFTREECODE (DO_STMT, "do_stmt", tcc_statement, 2)
|
||||||
|
|
||||||
|
/* Used to represent a 'break' statement. */
|
||||||
|
DEFTREECODE (BREAK_STMT, "break_stmt", tcc_statement, 0)
|
||||||
|
|
||||||
|
/* Used to represent a 'continue' statement. */
|
||||||
|
DEFTREECODE (CONTINUE_STMT, "continue_stmt", tcc_statement, 0)
|
||||||
|
|
||||||
|
/* Used to represent a 'switch' statement. The operands are
|
||||||
|
SWITCH_STMT_COND, SWITCH_STMT_BODY, SWITCH_STMT_TYPE, and
|
||||||
|
SWITCH_STMT_SCOPE, respectively. */
|
||||||
|
DEFTREECODE (SWITCH_STMT, "switch_stmt", tcc_statement, 4)
|
||||||
|
|
||||||
|
/* Used to represent an expression statement. Use `EXPR_STMT_EXPR' to
|
||||||
|
obtain the expression. */
|
||||||
|
DEFTREECODE (EXPR_STMT, "expr_stmt", tcc_expression, 1)
|
||||||
|
|
||||||
|
DEFTREECODE (TAG_DEFN, "tag_defn", tcc_expression, 0)
|
||||||
|
|
||||||
|
/* Represents an 'offsetof' expression during template expansion. */
|
||||||
|
DEFTREECODE (OFFSETOF_EXPR, "offsetof_expr", tcc_expression, 1)
|
||||||
|
|
||||||
|
/* Represents the -> operator during template expansion. */
|
||||||
|
DEFTREECODE (ARROW_EXPR, "arrow_expr", tcc_expression, 1)
|
||||||
|
|
||||||
|
/* Represents an '__alignof__' expression during template
|
||||||
|
expansion. */
|
||||||
|
DEFTREECODE (ALIGNOF_EXPR, "alignof_expr", tcc_expression, 1)
|
||||||
|
|
||||||
|
/* Represents an Objective-C++ '@encode' expression during template
|
||||||
|
expansion. */
|
||||||
|
DEFTREECODE (AT_ENCODE_EXPR, "at_encode_expr", tcc_expression, 1)
|
||||||
|
|
||||||
|
/* A STMT_EXPR represents a statement-expression during template
|
||||||
|
expansion. This is the GCC extension { ( ... ) }. The
|
||||||
|
STMT_EXPR_STMT is the statement given by the expression. */
|
||||||
|
DEFTREECODE (STMT_EXPR, "stmt_expr", tcc_expression, 1)
|
||||||
|
|
||||||
|
/* Unary plus. Operand 0 is the expression to which the unary plus
|
||||||
|
is applied. */
|
||||||
|
DEFTREECODE (UNARY_PLUS_EXPR, "unary_plus_expr", tcc_unary, 1)
|
||||||
|
|
||||||
|
/** C++0x extensions. */
|
||||||
|
|
||||||
|
/* A static assertion. This is a C++0x extension.
|
||||||
|
STATIC_ASSERT_CONDITION contains the condition that is being
|
||||||
|
checked. STATIC_ASSERT_MESSAGE contains the message (a string
|
||||||
|
literal) to be displayed if the condition fails to hold. */
|
||||||
|
DEFTREECODE (STATIC_ASSERT, "static_assert", tcc_exceptional, 0)
|
||||||
|
|
||||||
|
/* Represents an argument pack of types (or templates). An argument
|
||||||
|
pack stores zero or more arguments that will be used to instantiate
|
||||||
|
a parameter pack.
|
||||||
|
|
||||||
|
ARGUMENT_PACK_ARGS retrieves the arguments stored in the argument
|
||||||
|
pack.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
template<typename... Values>
|
||||||
|
class tuple { ... };
|
||||||
|
|
||||||
|
tuple<int, float, double> t;
|
||||||
|
|
||||||
|
Values is a (template) parameter pack. When tuple<int, float,
|
||||||
|
double> is instantiated, the Values parameter pack is instantiated
|
||||||
|
with the argument pack <int, float, double>. ARGUMENT_PACK_ARGS will
|
||||||
|
be a TREE_VEC containing int, float, and double. */
|
||||||
|
DEFTREECODE (TYPE_ARGUMENT_PACK, "type_argument_pack", tcc_type, 0)
|
||||||
|
|
||||||
|
/* Represents an argument pack of values, which can be used either for
|
||||||
|
non-type template arguments or function call arguments.
|
||||||
|
|
||||||
|
NONTYPE_ARGUMENT_PACK plays precisely the same role as
|
||||||
|
TYPE_ARGUMENT_PACK, but will be used for packing non-type template
|
||||||
|
arguments (e.g., "int... Dimensions") or function arguments ("const
|
||||||
|
Args&... args"). */
|
||||||
|
DEFTREECODE (NONTYPE_ARGUMENT_PACK, "nontype_argument_pack", tcc_expression, 1)
|
||||||
|
|
||||||
|
/* Represents a type expression that will be expanded into a list of
|
||||||
|
types when instantiated with one or more argument packs.
|
||||||
|
|
||||||
|
PACK_EXPANSION_PATTERN retrieves the expansion pattern. This is
|
||||||
|
the type or expression that we will substitute into with each
|
||||||
|
argument in an argument pack.
|
||||||
|
|
||||||
|
SET_PACK_EXPANSION_PATTERN sets the expansion pattern.
|
||||||
|
|
||||||
|
PACK_EXPANSION_PARAMETER_PACKS contains a TREE_LIST of the parameter
|
||||||
|
packs that are used in this pack expansion.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
template<typename... Values>
|
||||||
|
struct tied : tuple<Values&...> {
|
||||||
|
// ...
|
||||||
|
};
|
||||||
|
|
||||||
|
The derivation from tuple contains a TYPE_PACK_EXPANSION for the
|
||||||
|
template arguments. Its PACK_EXPANSION_PATTERN is "Values&" and its
|
||||||
|
PACK_EXPANSION_PARAMETER_PACKS will contain "Values". */
|
||||||
|
DEFTREECODE (TYPE_PACK_EXPANSION, "type_pack_expansion", tcc_type, 0)
|
||||||
|
|
||||||
|
/* Represents an expression that will be expanded into a list of
|
||||||
|
expressions when instantiated with one or more argument packs.
|
||||||
|
|
||||||
|
EXPR_PACK_EXPANSION plays precisely the same role as TYPE_PACK_EXPANSION,
|
||||||
|
but will be used for expressions. */
|
||||||
|
DEFTREECODE (EXPR_PACK_EXPANSION, "expr_pack_expansion", tcc_expression, 3)
|
||||||
|
|
||||||
|
/* Selects the Ith parameter out of an argument pack. This node will
|
||||||
|
be used when instantiating pack expansions; see
|
||||||
|
tsubst_pack_expansion.
|
||||||
|
|
||||||
|
ARGUMENT_PACK_SELECT_FROM_PACK contains the *_ARGUMENT_PACK node
|
||||||
|
from which the argument will be selected.
|
||||||
|
|
||||||
|
ARGUMENT_PACK_SELECT_INDEX contains the index into the argument
|
||||||
|
pack that will be returned by this ARGUMENT_PACK_SELECT node. The
|
||||||
|
index is a machine integer. */
|
||||||
|
DEFTREECODE (ARGUMENT_PACK_SELECT, "argument_pack_select", tcc_exceptional, 0)
|
||||||
|
|
||||||
|
/** C++ extensions. */
|
||||||
|
|
||||||
|
/* Represents a trait expression during template expansion. */
|
||||||
|
DEFTREECODE (TRAIT_EXPR, "trait_expr", tcc_exceptional, 0)
|
||||||
|
|
||||||
|
/* A lambda expression. This is a C++0x extension.
|
||||||
|
LAMBDA_EXPR_DEFAULT_CAPTURE_MODE is an enum for the default, which may be
|
||||||
|
none.
|
||||||
|
LAMBDA_EXPR_CAPTURE_LIST holds the capture-list, including `this'.
|
||||||
|
LAMBDA_EXPR_THIS_CAPTURE goes straight to the capture of `this', if it exists.
|
||||||
|
LAMBDA_EXPR_PENDING_PROXIES is a vector of capture proxies which need to
|
||||||
|
be pushed once scope returns to the lambda.
|
||||||
|
LAMBDA_EXPR_MUTABLE_P signals whether this lambda was declared mutable.
|
||||||
|
LAMBDA_EXPR_RETURN_TYPE holds the return type, if it was specified. */
|
||||||
|
DEFTREECODE (LAMBDA_EXPR, "lambda_expr", tcc_exceptional, 0)
|
||||||
|
|
||||||
|
/* The declared type of an expression. This is a C++0x extension.
|
||||||
|
DECLTYPE_TYPE_EXPR is the expression whose type we are computing.
|
||||||
|
DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P states whether the
|
||||||
|
expression was parsed as an id-expression or a member access
|
||||||
|
expression. When false, it was parsed as a full expression.
|
||||||
|
DECLTYPE_FOR_LAMBDA_CAPTURE is set if we want lambda capture semantics.
|
||||||
|
DECLTYPE_FOR_LAMBDA_RETURN is set if we want lambda return deduction. */
|
||||||
|
DEFTREECODE (DECLTYPE_TYPE, "decltype_type", tcc_type, 0)
|
||||||
|
|
||||||
|
/* A type designated by `__underlying_type (type)'.
|
||||||
|
UNDERLYING_TYPE_TYPE is the type in question. */
|
||||||
|
DEFTREECODE (UNDERLYING_TYPE, "underlying_type", tcc_type, 0)
|
||||||
|
|
||||||
|
/* A type designated by one of the bases type traits.
|
||||||
|
BASES_TYPE is the type in question. */
|
||||||
|
DEFTREECODE (BASES, "bases", tcc_type, 0)
|
||||||
|
|
||||||
|
/* Used to represent the template information stored by template
|
||||||
|
specializations.
|
||||||
|
The accessors are:
|
||||||
|
TI_TEMPLATE the template declaration associated to the specialization
|
||||||
|
TI_ARGS the arguments of the template specialization
|
||||||
|
TI_TYPEDEFS_NEEDING_ACCESS_CHECKING the vector of typedefs used in
|
||||||
|
the pattern of the template for which access check is needed at template
|
||||||
|
instantiation time. */
|
||||||
|
DEFTREECODE (TEMPLATE_INFO, "template_info", tcc_exceptional, 0)
|
||||||
|
|
||||||
|
/*
|
||||||
|
Local variables:
|
||||||
|
mode:c
|
||||||
|
End:
|
||||||
|
*/
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,79 @@
|
||||||
|
/* Interface for the GNU C++ pretty-printer.
|
||||||
|
Copyright (C) 2003-2013 Free Software Foundation, Inc.
|
||||||
|
Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net>
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free
|
||||||
|
Software Foundation; either version 3, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GCC; see the file COPYING3. If not see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#ifndef GCC_CXX_PRETTY_PRINT_H
|
||||||
|
#define GCC_CXX_PRETTY_PRINT_H
|
||||||
|
|
||||||
|
#include "c-family/c-pretty-print.h"
|
||||||
|
|
||||||
|
#undef pp_c_base
|
||||||
|
#define pp_c_base(PP) (&(PP)->c_base)
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
/* Ask for a qualified-id. */
|
||||||
|
pp_cxx_flag_default_argument = 1 << pp_c_flag_last_bit
|
||||||
|
|
||||||
|
} cxx_pretty_printer_flags;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
c_pretty_printer c_base;
|
||||||
|
/* This is the enclosing scope of the entity being pretty-printed. */
|
||||||
|
tree enclosing_scope;
|
||||||
|
} cxx_pretty_printer;
|
||||||
|
|
||||||
|
#define pp_cxx_cv_qualifier_seq(PP, T) \
|
||||||
|
pp_c_type_qualifier_list (pp_c_base (PP), T)
|
||||||
|
|
||||||
|
#define pp_cxx_whitespace(PP) pp_c_whitespace (pp_c_base (PP))
|
||||||
|
#define pp_cxx_left_paren(PP) pp_c_left_paren (pp_c_base (PP))
|
||||||
|
#define pp_cxx_right_paren(PP) pp_c_right_paren (pp_c_base (PP))
|
||||||
|
#define pp_cxx_left_brace(PP) pp_c_left_brace (pp_c_base (PP))
|
||||||
|
#define pp_cxx_right_brace(PP) pp_c_right_brace (pp_c_base (PP))
|
||||||
|
#define pp_cxx_left_bracket(PP) pp_c_left_bracket (pp_c_base (PP))
|
||||||
|
#define pp_cxx_right_bracket(PP) pp_c_right_bracket (pp_c_base (PP))
|
||||||
|
#define pp_cxx_dot(PP) pp_c_dot (pp_c_base (PP))
|
||||||
|
#define pp_cxx_ampersand(PP) pp_c_ampersand (pp_c_base (PP))
|
||||||
|
#define pp_cxx_star(PP) pp_c_star (pp_c_base (PP))
|
||||||
|
#define pp_cxx_arrow(PP) pp_c_arrow (pp_c_base (PP))
|
||||||
|
#define pp_cxx_semicolon(PP) pp_c_semicolon (pp_c_base (PP))
|
||||||
|
#define pp_cxx_complement(PP) pp_c_complement (pp_c_base (PP))
|
||||||
|
|
||||||
|
#define pp_cxx_ws_string(PP, I) pp_c_ws_string (pp_c_base (PP), I)
|
||||||
|
#define pp_cxx_identifier(PP, I) pp_c_identifier (pp_c_base (PP), I)
|
||||||
|
#define pp_cxx_tree_identifier(PP, T) \
|
||||||
|
pp_c_tree_identifier (pp_c_base (PP), T)
|
||||||
|
|
||||||
|
void pp_cxx_pretty_printer_init (cxx_pretty_printer *);
|
||||||
|
void pp_cxx_begin_template_argument_list (cxx_pretty_printer *);
|
||||||
|
void pp_cxx_end_template_argument_list (cxx_pretty_printer *);
|
||||||
|
void pp_cxx_colon_colon (cxx_pretty_printer *);
|
||||||
|
void pp_cxx_separate_with (cxx_pretty_printer *, int);
|
||||||
|
|
||||||
|
void pp_cxx_declaration (cxx_pretty_printer *, tree);
|
||||||
|
void pp_cxx_canonical_template_parameter (cxx_pretty_printer *, tree);
|
||||||
|
void pp_cxx_trait_expression (cxx_pretty_printer *, tree);
|
||||||
|
void pp_cxx_va_arg_expression (cxx_pretty_printer *, tree);
|
||||||
|
void pp_cxx_offsetof_expression (cxx_pretty_printer *, tree);
|
||||||
|
void pp_cxx_userdef_literal (cxx_pretty_printer *, tree);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* GCC_CXX_PRETTY_PRINT_H */
|
|
@ -0,0 +1,369 @@
|
||||||
|
/* Declarations for C++ name lookup routines.
|
||||||
|
Copyright (C) 2003-2013 Free Software Foundation, Inc.
|
||||||
|
Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net>
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GCC; see the file COPYING3. If not see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#ifndef GCC_CP_NAME_LOOKUP_H
|
||||||
|
#define GCC_CP_NAME_LOOKUP_H
|
||||||
|
|
||||||
|
#include "c-family/c-common.h"
|
||||||
|
|
||||||
|
/* The type of dictionary used to map names to types declared at
|
||||||
|
a given scope. */
|
||||||
|
typedef struct binding_table_s *binding_table;
|
||||||
|
typedef struct binding_entry_s *binding_entry;
|
||||||
|
|
||||||
|
/* The type of a routine repeatedly called by binding_table_foreach. */
|
||||||
|
typedef void (*bt_foreach_proc) (binding_entry, void *);
|
||||||
|
|
||||||
|
struct GTY(()) binding_entry_s {
|
||||||
|
binding_entry chain;
|
||||||
|
tree name;
|
||||||
|
tree type;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* These macros indicate the initial chains count for binding_table. */
|
||||||
|
#define SCOPE_DEFAULT_HT_SIZE (1 << 3)
|
||||||
|
#define CLASS_SCOPE_HT_SIZE (1 << 3)
|
||||||
|
#define NAMESPACE_ORDINARY_HT_SIZE (1 << 5)
|
||||||
|
#define NAMESPACE_STD_HT_SIZE (1 << 8)
|
||||||
|
#define GLOBAL_SCOPE_HT_SIZE (1 << 8)
|
||||||
|
|
||||||
|
extern void binding_table_foreach (binding_table, bt_foreach_proc, void *);
|
||||||
|
extern binding_entry binding_table_find (binding_table, tree);
|
||||||
|
|
||||||
|
/* Datatype that represents binding established by a declaration between
|
||||||
|
a name and a C++ entity. */
|
||||||
|
typedef struct cxx_binding cxx_binding;
|
||||||
|
|
||||||
|
/* The datatype used to implement C++ scope. */
|
||||||
|
typedef struct cp_binding_level cp_binding_level;
|
||||||
|
|
||||||
|
/* Nonzero if this binding is for a local scope, as opposed to a class
|
||||||
|
or namespace scope. */
|
||||||
|
#define LOCAL_BINDING_P(NODE) ((NODE)->is_local)
|
||||||
|
|
||||||
|
/* True if NODE->value is from a base class of the class which is
|
||||||
|
currently being defined. */
|
||||||
|
#define INHERITED_VALUE_BINDING_P(NODE) ((NODE)->value_is_inherited)
|
||||||
|
|
||||||
|
struct GTY(()) cxx_binding {
|
||||||
|
/* Link to chain together various bindings for this name. */
|
||||||
|
cxx_binding *previous;
|
||||||
|
/* The non-type entity this name is bound to. */
|
||||||
|
tree value;
|
||||||
|
/* The type entity this name is bound to. */
|
||||||
|
tree type;
|
||||||
|
/* The scope at which this binding was made. */
|
||||||
|
cp_binding_level *scope;
|
||||||
|
unsigned value_is_inherited : 1;
|
||||||
|
unsigned is_local : 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Datatype used to temporarily save C++ bindings (for implicit
|
||||||
|
instantiations purposes and like). Implemented in decl.c. */
|
||||||
|
typedef struct GTY(()) cxx_saved_binding {
|
||||||
|
/* The name of the current binding. */
|
||||||
|
tree identifier;
|
||||||
|
/* The binding we're saving. */
|
||||||
|
cxx_binding *binding;
|
||||||
|
tree real_type_value;
|
||||||
|
} cxx_saved_binding;
|
||||||
|
|
||||||
|
|
||||||
|
extern tree identifier_type_value (tree);
|
||||||
|
extern void set_identifier_type_value (tree, tree);
|
||||||
|
extern void pop_binding (tree, tree);
|
||||||
|
extern tree constructor_name (tree);
|
||||||
|
extern bool constructor_name_p (tree, tree);
|
||||||
|
|
||||||
|
/* The kinds of scopes we recognize. */
|
||||||
|
typedef enum scope_kind {
|
||||||
|
sk_block = 0, /* An ordinary block scope. This enumerator must
|
||||||
|
have the value zero because "cp_binding_level"
|
||||||
|
is initialized by using "memset" to set the
|
||||||
|
contents to zero, and the default scope kind
|
||||||
|
is "sk_block". */
|
||||||
|
sk_cleanup, /* A scope for (pseudo-)scope for cleanup. It is
|
||||||
|
pseudo in that it is transparent to name lookup
|
||||||
|
activities. */
|
||||||
|
sk_try, /* A try-block. */
|
||||||
|
sk_catch, /* A catch-block. */
|
||||||
|
sk_for, /* The scope of the variable declared in a
|
||||||
|
for-init-statement. */
|
||||||
|
sk_cond, /* The scope of the variable declared in the condition
|
||||||
|
of an if or switch statement. */
|
||||||
|
sk_function_parms, /* The scope containing function parameters. */
|
||||||
|
sk_class, /* The scope containing the members of a class. */
|
||||||
|
sk_scoped_enum, /* The scope containing the enumertors of a C++0x
|
||||||
|
scoped enumeration. */
|
||||||
|
sk_namespace, /* The scope containing the members of a
|
||||||
|
namespace, including the global scope. */
|
||||||
|
sk_template_parms, /* A scope for template parameters. */
|
||||||
|
sk_template_spec, /* Like sk_template_parms, but for an explicit
|
||||||
|
specialization. Since, by definition, an
|
||||||
|
explicit specialization is introduced by
|
||||||
|
"template <>", this scope is always empty. */
|
||||||
|
sk_omp /* An OpenMP structured block. */
|
||||||
|
} scope_kind;
|
||||||
|
|
||||||
|
/* The scope where the class/struct/union/enum tag applies. */
|
||||||
|
typedef enum tag_scope {
|
||||||
|
ts_current = 0, /* Current scope only. This is for the
|
||||||
|
class-key identifier;
|
||||||
|
case mentioned in [basic.lookup.elab]/2,
|
||||||
|
or the class/enum definition
|
||||||
|
class-key identifier { ... }; */
|
||||||
|
ts_global = 1, /* All scopes. This is the 3.4.1
|
||||||
|
[basic.lookup.unqual] lookup mentioned
|
||||||
|
in [basic.lookup.elab]/2. */
|
||||||
|
ts_within_enclosing_non_class = 2, /* Search within enclosing non-class
|
||||||
|
only, for friend class lookup
|
||||||
|
according to [namespace.memdef]/3
|
||||||
|
and [class.friend]/9. */
|
||||||
|
ts_lambda = 3 /* Declaring a lambda closure. */
|
||||||
|
} tag_scope;
|
||||||
|
|
||||||
|
typedef struct GTY(()) cp_class_binding {
|
||||||
|
cxx_binding *base;
|
||||||
|
/* The bound name. */
|
||||||
|
tree identifier;
|
||||||
|
} cp_class_binding;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct GTY(()) cp_label_binding {
|
||||||
|
/* The bound LABEL_DECL. */
|
||||||
|
tree label;
|
||||||
|
/* The previous IDENTIFIER_LABEL_VALUE. */
|
||||||
|
tree prev_value;
|
||||||
|
} cp_label_binding;
|
||||||
|
|
||||||
|
|
||||||
|
/* For each binding contour we allocate a binding_level structure
|
||||||
|
which records the names defined in that contour.
|
||||||
|
Contours include:
|
||||||
|
0) the global one
|
||||||
|
1) one for each function definition,
|
||||||
|
where internal declarations of the parameters appear.
|
||||||
|
2) one for each compound statement,
|
||||||
|
to record its declarations.
|
||||||
|
|
||||||
|
The current meaning of a name can be found by searching the levels
|
||||||
|
from the current one out to the global one.
|
||||||
|
|
||||||
|
Off to the side, may be the class_binding_level. This exists only
|
||||||
|
to catch class-local declarations. It is otherwise nonexistent.
|
||||||
|
|
||||||
|
Also there may be binding levels that catch cleanups that must be
|
||||||
|
run when exceptions occur. Thus, to see whether a name is bound in
|
||||||
|
the current scope, it is not enough to look in the
|
||||||
|
CURRENT_BINDING_LEVEL. You should use lookup_name_current_level
|
||||||
|
instead. */
|
||||||
|
|
||||||
|
/* Note that the information in the `names' component of the global contour
|
||||||
|
is duplicated in the IDENTIFIER_GLOBAL_VALUEs of all identifiers. */
|
||||||
|
|
||||||
|
struct GTY(()) cp_binding_level {
|
||||||
|
/* A chain of _DECL nodes for all variables, constants, functions,
|
||||||
|
and typedef types. These are in the reverse of the order
|
||||||
|
supplied. There may be OVERLOADs on this list, too, but they
|
||||||
|
are wrapped in TREE_LISTs; the TREE_VALUE is the OVERLOAD. */
|
||||||
|
tree names;
|
||||||
|
|
||||||
|
/* A chain of NAMESPACE_DECL nodes. */
|
||||||
|
tree namespaces;
|
||||||
|
|
||||||
|
/* An array of static functions and variables (for namespaces only) */
|
||||||
|
vec<tree, va_gc> *static_decls;
|
||||||
|
|
||||||
|
/* A list of USING_DECL nodes. */
|
||||||
|
tree usings;
|
||||||
|
|
||||||
|
/* A list of used namespaces. PURPOSE is the namespace,
|
||||||
|
VALUE the common ancestor with this binding_level's namespace. */
|
||||||
|
tree using_directives;
|
||||||
|
|
||||||
|
/* For the binding level corresponding to a class, the entities
|
||||||
|
declared in the class or its base classes. */
|
||||||
|
vec<cp_class_binding, va_gc> *class_shadowed;
|
||||||
|
|
||||||
|
/* Similar to class_shadowed, but for IDENTIFIER_TYPE_VALUE, and
|
||||||
|
is used for all binding levels. The TREE_PURPOSE is the name of
|
||||||
|
the entity, the TREE_TYPE is the associated type. In addition
|
||||||
|
the TREE_VALUE is the IDENTIFIER_TYPE_VALUE before we entered
|
||||||
|
the class. */
|
||||||
|
tree type_shadowed;
|
||||||
|
|
||||||
|
/* Similar to class_shadowed, but for IDENTIFIER_LABEL_VALUE, and
|
||||||
|
used for all binding levels. */
|
||||||
|
vec<cp_label_binding, va_gc> *shadowed_labels;
|
||||||
|
|
||||||
|
/* For each level (except not the global one),
|
||||||
|
a chain of BLOCK nodes for all the levels
|
||||||
|
that were entered and exited one level down. */
|
||||||
|
tree blocks;
|
||||||
|
|
||||||
|
/* The entity (namespace, class, function) the scope of which this
|
||||||
|
binding contour corresponds to. Otherwise NULL. */
|
||||||
|
tree this_entity;
|
||||||
|
|
||||||
|
/* The binding level which this one is contained in (inherits from). */
|
||||||
|
cp_binding_level *level_chain;
|
||||||
|
|
||||||
|
/* List of VAR_DECLS saved from a previous for statement.
|
||||||
|
These would be dead in ISO-conforming code, but might
|
||||||
|
be referenced in ARM-era code. */
|
||||||
|
vec<tree, va_gc> *dead_vars_from_for;
|
||||||
|
|
||||||
|
/* STATEMENT_LIST for statements in this binding contour.
|
||||||
|
Only used at present for SK_CLEANUP temporary bindings. */
|
||||||
|
tree statement_list;
|
||||||
|
|
||||||
|
/* Binding depth at which this level began. */
|
||||||
|
int binding_depth;
|
||||||
|
|
||||||
|
/* The kind of scope that this object represents. However, a
|
||||||
|
SK_TEMPLATE_SPEC scope is represented with KIND set to
|
||||||
|
SK_TEMPLATE_PARMS and EXPLICIT_SPEC_P set to true. */
|
||||||
|
ENUM_BITFIELD (scope_kind) kind : 4;
|
||||||
|
|
||||||
|
/* True if this scope is an SK_TEMPLATE_SPEC scope. This field is
|
||||||
|
only valid if KIND == SK_TEMPLATE_PARMS. */
|
||||||
|
BOOL_BITFIELD explicit_spec_p : 1;
|
||||||
|
|
||||||
|
/* true means make a BLOCK for this level regardless of all else. */
|
||||||
|
unsigned keep : 1;
|
||||||
|
|
||||||
|
/* Nonzero if this level can safely have additional
|
||||||
|
cleanup-needing variables added to it. */
|
||||||
|
unsigned more_cleanups_ok : 1;
|
||||||
|
unsigned have_cleanups : 1;
|
||||||
|
|
||||||
|
/* 24 bits left to fill a 32-bit word. */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* The binding level currently in effect. */
|
||||||
|
|
||||||
|
#define current_binding_level \
|
||||||
|
(*(cfun && cp_function_chain && cp_function_chain->bindings \
|
||||||
|
? &cp_function_chain->bindings \
|
||||||
|
: &scope_chain->bindings))
|
||||||
|
|
||||||
|
/* The binding level of the current class, if any. */
|
||||||
|
|
||||||
|
#define class_binding_level scope_chain->class_bindings
|
||||||
|
|
||||||
|
/* The tree node representing the global scope. */
|
||||||
|
extern GTY(()) tree global_namespace;
|
||||||
|
extern GTY(()) tree global_scope_name;
|
||||||
|
|
||||||
|
/* Indicates that there is a type value in some namespace, although
|
||||||
|
that is not necessarily in scope at the moment. */
|
||||||
|
|
||||||
|
extern GTY(()) tree global_type_node;
|
||||||
|
|
||||||
|
/* True if SCOPE designates the global scope binding contour. */
|
||||||
|
#define global_scope_p(SCOPE) \
|
||||||
|
((SCOPE) == NAMESPACE_LEVEL (global_namespace))
|
||||||
|
|
||||||
|
extern cp_binding_level *leave_scope (void);
|
||||||
|
extern bool kept_level_p (void);
|
||||||
|
extern bool global_bindings_p (void);
|
||||||
|
extern bool toplevel_bindings_p (void);
|
||||||
|
extern bool namespace_bindings_p (void);
|
||||||
|
extern bool local_bindings_p (void);
|
||||||
|
extern bool template_parm_scope_p (void);
|
||||||
|
extern scope_kind innermost_scope_kind (void);
|
||||||
|
extern cp_binding_level *begin_scope (scope_kind, tree);
|
||||||
|
extern void print_binding_stack (void);
|
||||||
|
extern void push_to_top_level (void);
|
||||||
|
extern void pop_from_top_level (void);
|
||||||
|
extern void pop_everything (void);
|
||||||
|
extern void keep_next_level (bool);
|
||||||
|
extern bool is_ancestor (tree, tree);
|
||||||
|
extern tree push_scope (tree);
|
||||||
|
extern void pop_scope (tree);
|
||||||
|
extern tree push_inner_scope (tree);
|
||||||
|
extern void pop_inner_scope (tree, tree);
|
||||||
|
extern void push_binding_level (cp_binding_level *);
|
||||||
|
|
||||||
|
extern void push_namespace (tree);
|
||||||
|
extern void pop_namespace (void);
|
||||||
|
extern void push_nested_namespace (tree);
|
||||||
|
extern void pop_nested_namespace (tree);
|
||||||
|
extern bool handle_namespace_attrs (tree, tree);
|
||||||
|
extern void pushlevel_class (void);
|
||||||
|
extern void poplevel_class (void);
|
||||||
|
extern tree pushdecl_with_scope (tree, cp_binding_level *, bool);
|
||||||
|
extern tree lookup_name_prefer_type (tree, int);
|
||||||
|
extern tree lookup_name_real (tree, int, int, bool, int, int);
|
||||||
|
extern tree lookup_type_scope (tree, tag_scope);
|
||||||
|
extern tree namespace_binding (tree, tree);
|
||||||
|
extern void set_namespace_binding (tree, tree, tree);
|
||||||
|
extern bool hidden_name_p (tree);
|
||||||
|
extern tree remove_hidden_names (tree);
|
||||||
|
extern tree lookup_qualified_name (tree, tree, bool, bool);
|
||||||
|
extern tree lookup_name_nonclass (tree);
|
||||||
|
extern tree lookup_name_innermost_nonclass_level (tree);
|
||||||
|
extern bool is_local_extern (tree);
|
||||||
|
extern tree lookup_function_nonclass (tree, vec<tree, va_gc> *, bool);
|
||||||
|
extern void push_local_binding (tree, tree, int);
|
||||||
|
extern bool pushdecl_class_level (tree);
|
||||||
|
extern tree pushdecl_namespace_level (tree, bool);
|
||||||
|
extern bool push_class_level_binding (tree, tree);
|
||||||
|
extern tree getdecls (void);
|
||||||
|
extern int function_parm_depth (void);
|
||||||
|
extern tree cp_namespace_decls (tree);
|
||||||
|
extern void set_decl_namespace (tree, tree, bool);
|
||||||
|
extern void push_decl_namespace (tree);
|
||||||
|
extern void pop_decl_namespace (void);
|
||||||
|
extern void do_namespace_alias (tree, tree);
|
||||||
|
extern void do_toplevel_using_decl (tree, tree, tree);
|
||||||
|
extern void do_local_using_decl (tree, tree, tree);
|
||||||
|
extern tree do_class_using_decl (tree, tree);
|
||||||
|
extern void do_using_directive (tree);
|
||||||
|
extern tree lookup_arg_dependent (tree, tree, vec<tree, va_gc> *, bool);
|
||||||
|
extern bool is_associated_namespace (tree, tree);
|
||||||
|
extern void parse_using_directive (tree, tree);
|
||||||
|
extern tree innermost_non_namespace_value (tree);
|
||||||
|
extern cxx_binding *outer_binding (tree, cxx_binding *, bool);
|
||||||
|
extern void cp_emit_debug_info_for_using (tree, tree);
|
||||||
|
|
||||||
|
/* Set *DECL to the (non-hidden) declaration for ID at global scope,
|
||||||
|
if present and return true; otherwise return false. */
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
get_global_value_if_present (tree id, tree *decl)
|
||||||
|
{
|
||||||
|
tree global_value = namespace_binding (id, global_namespace);
|
||||||
|
if (global_value)
|
||||||
|
*decl = global_value;
|
||||||
|
return global_value != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* True is the binding of IDENTIFIER at global scope names a type. */
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
is_typename_at_global_scope (tree id)
|
||||||
|
{
|
||||||
|
tree global_value = namespace_binding (id, global_namespace);
|
||||||
|
|
||||||
|
return global_value && TREE_CODE (global_value) == TYPE_DECL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* GCC_CP_NAME_LOOKUP_H */
|
|
@ -0,0 +1,71 @@
|
||||||
|
/* CPP Library.
|
||||||
|
Copyright (C) 1986-2013 Free Software Foundation, Inc.
|
||||||
|
Contributed by Per Bothner, 1994-95.
|
||||||
|
Based on CCCP program by Paul Rubin, June 1986
|
||||||
|
Adapted to ANSI C, Richard Stallman, Jan 1987
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by the
|
||||||
|
Free Software Foundation; either version 3, or (at your option) any
|
||||||
|
later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; see the file COPYING3. If not see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#ifndef GCC_CPPDEFAULT_H
|
||||||
|
#define GCC_CPPDEFAULT_H
|
||||||
|
|
||||||
|
/* This is the default list of directories to search for include files.
|
||||||
|
It may be overridden by the various -I and -ixxx options.
|
||||||
|
|
||||||
|
#include "file" looks in the same directory as the current file,
|
||||||
|
then this list.
|
||||||
|
#include <file> just looks in this list.
|
||||||
|
|
||||||
|
All these directories are treated as `system' include directories
|
||||||
|
(they are not subject to pedantic warnings in some cases). */
|
||||||
|
|
||||||
|
struct default_include
|
||||||
|
{
|
||||||
|
const char *const fname; /* The name of the directory. */
|
||||||
|
const char *const component; /* The component containing the directory
|
||||||
|
(see update_path in prefix.c) */
|
||||||
|
const char cplusplus; /* Only look here if we're compiling C++. */
|
||||||
|
const char cxx_aware; /* Includes in this directory don't need to
|
||||||
|
be wrapped in extern "C" when compiling
|
||||||
|
C++. */
|
||||||
|
const char add_sysroot; /* FNAME should be prefixed by
|
||||||
|
cpp_SYSROOT. */
|
||||||
|
const char multilib; /* FNAME should have appended
|
||||||
|
- the multilib path specified with -imultilib
|
||||||
|
when set to 1,
|
||||||
|
- the multiarch path specified with
|
||||||
|
-imultiarch, when set to 2. */
|
||||||
|
};
|
||||||
|
|
||||||
|
extern const struct default_include cpp_include_defaults[];
|
||||||
|
extern const char cpp_GCC_INCLUDE_DIR[];
|
||||||
|
extern const size_t cpp_GCC_INCLUDE_DIR_len;
|
||||||
|
|
||||||
|
/* The configure-time prefix, i.e., the value supplied as the argument
|
||||||
|
to --prefix=. */
|
||||||
|
extern const char cpp_PREFIX[];
|
||||||
|
/* The length of the configure-time prefix. */
|
||||||
|
extern const size_t cpp_PREFIX_len;
|
||||||
|
/* The configure-time execution prefix. This is typically the lib/gcc
|
||||||
|
subdirectory of cpp_PREFIX. */
|
||||||
|
extern const char cpp_EXEC_PREFIX[];
|
||||||
|
/* The run-time execution prefix. This is typically the lib/gcc
|
||||||
|
subdirectory of the actual installation. */
|
||||||
|
extern const char *gcc_exec_prefix;
|
||||||
|
|
||||||
|
/* Return true if the toolchain is relocated. */
|
||||||
|
bool cpp_relocated (void);
|
||||||
|
|
||||||
|
#endif /* ! GCC_CPPDEFAULT_H */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,195 @@
|
||||||
|
/* Debug hooks for GCC.
|
||||||
|
Copyright (C) 2001-2013 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by the
|
||||||
|
Free Software Foundation; either version 3, or (at your option) any
|
||||||
|
later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; see the file COPYING3. If not see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#ifndef GCC_DEBUG_H
|
||||||
|
#define GCC_DEBUG_H
|
||||||
|
|
||||||
|
/* This structure contains hooks for the debug information output
|
||||||
|
functions, accessed through the global instance debug_hooks set in
|
||||||
|
toplev.c according to command line options. */
|
||||||
|
struct gcc_debug_hooks
|
||||||
|
{
|
||||||
|
/* Initialize debug output. MAIN_FILENAME is the name of the main
|
||||||
|
input file. */
|
||||||
|
void (* init) (const char *main_filename);
|
||||||
|
|
||||||
|
/* Output debug symbols. */
|
||||||
|
void (* finish) (const char *main_filename);
|
||||||
|
|
||||||
|
/* Called from cgraph_optimize before starting to assemble
|
||||||
|
functions/variables/toplevel asms. */
|
||||||
|
void (* assembly_start) (void);
|
||||||
|
|
||||||
|
/* Macro defined on line LINE with name and expansion TEXT. */
|
||||||
|
void (* define) (unsigned int line, const char *text);
|
||||||
|
|
||||||
|
/* MACRO undefined on line LINE. */
|
||||||
|
void (* undef) (unsigned int line, const char *macro);
|
||||||
|
|
||||||
|
/* Record the beginning of a new source file FILE from LINE number
|
||||||
|
in the previous one. */
|
||||||
|
void (* start_source_file) (unsigned int line, const char *file);
|
||||||
|
|
||||||
|
/* Record the resumption of a source file. LINE is the line number
|
||||||
|
in the source file we are returning to. */
|
||||||
|
void (* end_source_file) (unsigned int line);
|
||||||
|
|
||||||
|
/* Record the beginning of block N, counting from 1 and not
|
||||||
|
including the function-scope block, at LINE. */
|
||||||
|
void (* begin_block) (unsigned int line, unsigned int n);
|
||||||
|
|
||||||
|
/* Record the end of a block. Arguments as for begin_block. */
|
||||||
|
void (* end_block) (unsigned int line, unsigned int n);
|
||||||
|
|
||||||
|
/* Returns nonzero if it is appropriate not to emit any debugging
|
||||||
|
information for BLOCK, because it doesn't contain any
|
||||||
|
instructions. This may not be the case for blocks containing
|
||||||
|
nested functions, since we may actually call such a function even
|
||||||
|
though the BLOCK information is messed up. Defaults to true. */
|
||||||
|
bool (* ignore_block) (const_tree);
|
||||||
|
|
||||||
|
/* Record a source file location at (FILE, LINE, DISCRIMINATOR). */
|
||||||
|
void (* source_line) (unsigned int line, const char *file,
|
||||||
|
int discriminator, bool is_stmt);
|
||||||
|
|
||||||
|
/* Called at start of prologue code. LINE is the first line in the
|
||||||
|
function. */
|
||||||
|
void (* begin_prologue) (unsigned int line, const char *file);
|
||||||
|
|
||||||
|
/* Called at end of prologue code. LINE is the first line in the
|
||||||
|
function. */
|
||||||
|
void (* end_prologue) (unsigned int line, const char *file);
|
||||||
|
|
||||||
|
/* Called at beginning of epilogue code. */
|
||||||
|
void (* begin_epilogue) (unsigned int line, const char *file);
|
||||||
|
|
||||||
|
/* Record end of epilogue code. */
|
||||||
|
void (* end_epilogue) (unsigned int line, const char *file);
|
||||||
|
|
||||||
|
/* Called at start of function DECL, before it is declared. */
|
||||||
|
void (* begin_function) (tree decl);
|
||||||
|
|
||||||
|
/* Record end of function. LINE is highest line number in function. */
|
||||||
|
void (* end_function) (unsigned int line);
|
||||||
|
|
||||||
|
/* Debug information for a function DECL. This might include the
|
||||||
|
function name (a symbol), its parameters, and the block that
|
||||||
|
makes up the function's body, and the local variables of the
|
||||||
|
function. */
|
||||||
|
void (* function_decl) (tree decl);
|
||||||
|
|
||||||
|
/* Debug information for a global DECL. Called from toplev.c after
|
||||||
|
compilation proper has finished. */
|
||||||
|
void (* global_decl) (tree decl);
|
||||||
|
|
||||||
|
/* Debug information for a type DECL. Called from toplev.c after
|
||||||
|
compilation proper, also from various language front ends to
|
||||||
|
record built-in types. The second argument is properly a
|
||||||
|
boolean, which indicates whether or not the type is a "local"
|
||||||
|
type as determined by the language. (It's not a boolean for
|
||||||
|
legacy reasons.) */
|
||||||
|
void (* type_decl) (tree decl, int local);
|
||||||
|
|
||||||
|
/* Debug information for imported modules and declarations. */
|
||||||
|
void (* imported_module_or_decl) (tree decl, tree name,
|
||||||
|
tree context, bool child);
|
||||||
|
|
||||||
|
/* DECL is an inline function, whose body is present, but which is
|
||||||
|
not being output at this point. */
|
||||||
|
void (* deferred_inline_function) (tree decl);
|
||||||
|
|
||||||
|
/* DECL is an inline function which is about to be emitted out of
|
||||||
|
line. The hook is useful to, e.g., emit abstract debug info for
|
||||||
|
the inline before it gets mangled by optimization. */
|
||||||
|
void (* outlining_inline_function) (tree decl);
|
||||||
|
|
||||||
|
/* Called from final_scan_insn for any CODE_LABEL insn whose
|
||||||
|
LABEL_NAME is non-null. */
|
||||||
|
void (* label) (rtx);
|
||||||
|
|
||||||
|
/* Called after the start and before the end of writing a PCH file.
|
||||||
|
The parameter is 0 if after the start, 1 if before the end. */
|
||||||
|
void (* handle_pch) (unsigned int);
|
||||||
|
|
||||||
|
/* Called from final_scan_insn for any NOTE_INSN_VAR_LOCATION note. */
|
||||||
|
void (* var_location) (rtx);
|
||||||
|
|
||||||
|
/* Called from final_scan_insn if there is a switch between hot and cold
|
||||||
|
text sections. */
|
||||||
|
void (* switch_text_section) (void);
|
||||||
|
|
||||||
|
/* Called from grokdeclarator. Replaces the anonymous name with the
|
||||||
|
type name. */
|
||||||
|
void (* set_name) (tree, tree);
|
||||||
|
|
||||||
|
/* This is 1 if the debug writer wants to see start and end commands for the
|
||||||
|
main source files, and 0 otherwise. */
|
||||||
|
int start_end_main_source_file;
|
||||||
|
|
||||||
|
/* The type of symtab field used by these debug hooks. This is one
|
||||||
|
of the TYPE_SYMTAB_IS_xxx values defined in tree.h. */
|
||||||
|
int tree_type_symtab_field;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern const struct gcc_debug_hooks *debug_hooks;
|
||||||
|
|
||||||
|
/* The do-nothing hooks. */
|
||||||
|
extern void debug_nothing_void (void);
|
||||||
|
extern void debug_nothing_charstar (const char *);
|
||||||
|
extern void debug_nothing_int_charstar (unsigned int, const char *);
|
||||||
|
extern void debug_nothing_int_charstar_int_bool (unsigned int, const char *,
|
||||||
|
int, bool);
|
||||||
|
extern void debug_nothing_int (unsigned int);
|
||||||
|
extern void debug_nothing_int_int (unsigned int, unsigned int);
|
||||||
|
extern void debug_nothing_tree (tree);
|
||||||
|
extern void debug_nothing_tree_tree (tree, tree);
|
||||||
|
extern void debug_nothing_tree_int (tree, int);
|
||||||
|
extern void debug_nothing_tree_tree_tree_bool (tree, tree, tree, bool);
|
||||||
|
extern bool debug_true_const_tree (const_tree);
|
||||||
|
extern void debug_nothing_rtx (rtx);
|
||||||
|
extern void debug_nothing_rtx_rtx (rtx, rtx);
|
||||||
|
|
||||||
|
/* Hooks for various debug formats. */
|
||||||
|
extern const struct gcc_debug_hooks do_nothing_debug_hooks;
|
||||||
|
extern const struct gcc_debug_hooks dbx_debug_hooks;
|
||||||
|
extern const struct gcc_debug_hooks sdb_debug_hooks;
|
||||||
|
extern const struct gcc_debug_hooks xcoff_debug_hooks;
|
||||||
|
extern const struct gcc_debug_hooks dwarf2_debug_hooks;
|
||||||
|
extern const struct gcc_debug_hooks vmsdbg_debug_hooks;
|
||||||
|
|
||||||
|
/* Dwarf2 frame information. */
|
||||||
|
|
||||||
|
extern void dwarf2out_begin_prologue (unsigned int, const char *);
|
||||||
|
extern void dwarf2out_vms_end_prologue (unsigned int, const char *);
|
||||||
|
extern void dwarf2out_vms_begin_epilogue (unsigned int, const char *);
|
||||||
|
extern void dwarf2out_end_epilogue (unsigned int, const char *);
|
||||||
|
extern void dwarf2out_frame_finish (void);
|
||||||
|
/* Decide whether we want to emit frame unwind information for the current
|
||||||
|
translation unit. */
|
||||||
|
extern bool dwarf2out_do_frame (void);
|
||||||
|
extern bool dwarf2out_do_cfi_asm (void);
|
||||||
|
extern void dwarf2out_switch_text_section (void);
|
||||||
|
|
||||||
|
const char *remap_debug_filename (const char *);
|
||||||
|
void add_debug_prefix_map (const char *);
|
||||||
|
|
||||||
|
/* For -fdump-go-spec. */
|
||||||
|
|
||||||
|
extern const struct gcc_debug_hooks *
|
||||||
|
dump_go_spec_init (const char *, const struct gcc_debug_hooks *);
|
||||||
|
|
||||||
|
#endif /* !GCC_DEBUG_H */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,89 @@
|
||||||
|
/* Declarations of core diagnostic functionality for code that does
|
||||||
|
not need to deal with diagnostic contexts or diagnostic info
|
||||||
|
structures.
|
||||||
|
Copyright (C) 1998-2013 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free
|
||||||
|
Software Foundation; either version 3, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GCC; see the file COPYING3. If not see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#ifndef GCC_DIAGNOSTIC_CORE_H
|
||||||
|
#define GCC_DIAGNOSTIC_CORE_H
|
||||||
|
|
||||||
|
#include "input.h"
|
||||||
|
#include "bversion.h"
|
||||||
|
|
||||||
|
/* Constants used to discriminate diagnostics. */
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
#define DEFINE_DIAGNOSTIC_KIND(K, msgid) K,
|
||||||
|
#include "diagnostic.def"
|
||||||
|
#undef DEFINE_DIAGNOSTIC_KIND
|
||||||
|
DK_LAST_DIAGNOSTIC_KIND,
|
||||||
|
/* This is used for tagging pragma pops in the diagnostic
|
||||||
|
classification history chain. */
|
||||||
|
DK_POP
|
||||||
|
} diagnostic_t;
|
||||||
|
|
||||||
|
extern const char *progname;
|
||||||
|
|
||||||
|
extern const char *trim_filename (const char *);
|
||||||
|
|
||||||
|
/* If we haven't already defined a front-end-specific diagnostics
|
||||||
|
style, use the generic one. */
|
||||||
|
#ifndef GCC_DIAG_STYLE
|
||||||
|
#define GCC_DIAG_STYLE __gcc_tdiag__
|
||||||
|
#endif
|
||||||
|
/* None of these functions are suitable for ATTRIBUTE_PRINTF, because
|
||||||
|
each language front end can extend them with its own set of format
|
||||||
|
specifiers. We must use custom format checks. */
|
||||||
|
#if (ENABLE_CHECKING && GCC_VERSION >= 4001) || GCC_VERSION == BUILDING_GCC_VERSION
|
||||||
|
#define ATTRIBUTE_GCC_DIAG(m, n) __attribute__ ((__format__ (GCC_DIAG_STYLE, m, n))) ATTRIBUTE_NONNULL(m)
|
||||||
|
#else
|
||||||
|
#define ATTRIBUTE_GCC_DIAG(m, n) ATTRIBUTE_NONNULL(m)
|
||||||
|
#endif
|
||||||
|
extern void internal_error (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2)
|
||||||
|
ATTRIBUTE_NORETURN;
|
||||||
|
/* Pass one of the OPT_W* from options.h as the first parameter. */
|
||||||
|
extern bool warning (int, const char *, ...) ATTRIBUTE_GCC_DIAG(2,3);
|
||||||
|
extern bool warning_at (location_t, int, const char *, ...)
|
||||||
|
ATTRIBUTE_GCC_DIAG(3,4);
|
||||||
|
extern void error (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2);
|
||||||
|
extern void error_n (location_t, int, const char *, const char *, ...)
|
||||||
|
ATTRIBUTE_GCC_DIAG(3,5) ATTRIBUTE_GCC_DIAG(4,5);
|
||||||
|
extern void error_at (location_t, const char *, ...) ATTRIBUTE_GCC_DIAG(2,3);
|
||||||
|
extern void fatal_error (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2)
|
||||||
|
ATTRIBUTE_NORETURN;
|
||||||
|
/* Pass one of the OPT_W* from options.h as the second parameter. */
|
||||||
|
extern bool pedwarn (location_t, int, const char *, ...)
|
||||||
|
ATTRIBUTE_GCC_DIAG(3,4);
|
||||||
|
extern bool permerror (location_t, const char *, ...) ATTRIBUTE_GCC_DIAG(2,3);
|
||||||
|
extern void sorry (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2);
|
||||||
|
extern void inform (location_t, const char *, ...) ATTRIBUTE_GCC_DIAG(2,3);
|
||||||
|
extern void inform_n (location_t, int, const char *, const char *, ...)
|
||||||
|
ATTRIBUTE_GCC_DIAG(3,5) ATTRIBUTE_GCC_DIAG(4,5);
|
||||||
|
extern void verbatim (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2);
|
||||||
|
extern bool emit_diagnostic (diagnostic_t, location_t, int,
|
||||||
|
const char *, ...) ATTRIBUTE_GCC_DIAG(4,5);
|
||||||
|
extern bool seen_error (void);
|
||||||
|
|
||||||
|
#ifdef BUFSIZ
|
||||||
|
/* N.B. Unlike all the others, fnotice is just gettext+fprintf, and
|
||||||
|
therefore it can have ATTRIBUTE_PRINTF. */
|
||||||
|
extern void fnotice (FILE *, const char *, ...)
|
||||||
|
ATTRIBUTE_PRINTF_2;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* ! GCC_DIAGNOSTIC_CORE_H */
|
|
@ -0,0 +1,45 @@
|
||||||
|
/* Copyright (C) 2001-2013 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free
|
||||||
|
Software Foundation; either version 3, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GCC; see the file COPYING3. If not see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
/* DK_UNSPECIFIED must be first so it has a value of zero. We never
|
||||||
|
assign this kind to an actual diagnostic, we only use this in
|
||||||
|
variables that can hold a kind, to mean they have yet to have a
|
||||||
|
kind specified. I.e. they're uninitialized. Within the diagnostic
|
||||||
|
machinery, this kind also means "don't change the existing kind",
|
||||||
|
meaning "no change is specified". */
|
||||||
|
DEFINE_DIAGNOSTIC_KIND (DK_UNSPECIFIED, "")
|
||||||
|
|
||||||
|
/* If a diagnostic is set to DK_IGNORED, it won't get reported at all.
|
||||||
|
This is used by the diagnostic machinery when it wants to disable a
|
||||||
|
diagnostic without disabling the option which causes it. */
|
||||||
|
DEFINE_DIAGNOSTIC_KIND (DK_IGNORED, "")
|
||||||
|
|
||||||
|
/* The remainder are real diagnostic types. */
|
||||||
|
DEFINE_DIAGNOSTIC_KIND (DK_FATAL, "fatal error: ")
|
||||||
|
DEFINE_DIAGNOSTIC_KIND (DK_ICE, "internal compiler error: ")
|
||||||
|
DEFINE_DIAGNOSTIC_KIND (DK_ERROR, "error: ")
|
||||||
|
DEFINE_DIAGNOSTIC_KIND (DK_SORRY, "sorry, unimplemented: ")
|
||||||
|
DEFINE_DIAGNOSTIC_KIND (DK_WARNING, "warning: ")
|
||||||
|
DEFINE_DIAGNOSTIC_KIND (DK_ANACHRONISM, "anachronism: ")
|
||||||
|
DEFINE_DIAGNOSTIC_KIND (DK_NOTE, "note: ")
|
||||||
|
DEFINE_DIAGNOSTIC_KIND (DK_DEBUG, "debug: ")
|
||||||
|
/* These two would be re-classified as DK_WARNING or DK_ERROR, so the
|
||||||
|
prefix does not matter. */
|
||||||
|
DEFINE_DIAGNOSTIC_KIND (DK_PEDWARN, "pedwarn: ")
|
||||||
|
DEFINE_DIAGNOSTIC_KIND (DK_PERMERROR, "permerror: ")
|
||||||
|
|
|
@ -0,0 +1,296 @@
|
||||||
|
/* Various declarations for language-independent diagnostics subroutines.
|
||||||
|
Copyright (C) 2000-2013 Free Software Foundation, Inc.
|
||||||
|
Contributed by Gabriel Dos Reis <gdr@codesourcery.com>
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free
|
||||||
|
Software Foundation; either version 3, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GCC; see the file COPYING3. If not see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#ifndef GCC_DIAGNOSTIC_H
|
||||||
|
#define GCC_DIAGNOSTIC_H
|
||||||
|
|
||||||
|
#include "pretty-print.h"
|
||||||
|
#include "diagnostic-core.h"
|
||||||
|
|
||||||
|
/* A diagnostic is described by the MESSAGE to send, the FILE and LINE of
|
||||||
|
its context and its KIND (ice, error, warning, note, ...) See complete
|
||||||
|
list in diagnostic.def. */
|
||||||
|
typedef struct diagnostic_info
|
||||||
|
{
|
||||||
|
text_info message;
|
||||||
|
location_t location;
|
||||||
|
unsigned int override_column;
|
||||||
|
/* Auxiliary data for client. */
|
||||||
|
void *x_data;
|
||||||
|
/* The kind of diagnostic it is about. */
|
||||||
|
diagnostic_t kind;
|
||||||
|
/* Which OPT_* directly controls this diagnostic. */
|
||||||
|
int option_index;
|
||||||
|
} diagnostic_info;
|
||||||
|
|
||||||
|
/* Each time a diagnostic's classification is changed with a pragma,
|
||||||
|
we record the change and the location of the change in an array of
|
||||||
|
these structs. */
|
||||||
|
typedef struct diagnostic_classification_change_t
|
||||||
|
{
|
||||||
|
location_t location;
|
||||||
|
int option;
|
||||||
|
diagnostic_t kind;
|
||||||
|
} diagnostic_classification_change_t;
|
||||||
|
|
||||||
|
/* Forward declarations. */
|
||||||
|
typedef void (*diagnostic_starter_fn) (diagnostic_context *,
|
||||||
|
diagnostic_info *);
|
||||||
|
typedef diagnostic_starter_fn diagnostic_finalizer_fn;
|
||||||
|
|
||||||
|
/* This data structure bundles altogether any information relevant to
|
||||||
|
the context of a diagnostic message. */
|
||||||
|
struct diagnostic_context
|
||||||
|
{
|
||||||
|
/* Where most of the diagnostic formatting work is done. */
|
||||||
|
pretty_printer *printer;
|
||||||
|
|
||||||
|
/* The number of times we have issued diagnostics. */
|
||||||
|
int diagnostic_count[DK_LAST_DIAGNOSTIC_KIND];
|
||||||
|
|
||||||
|
/* True if we should display the "warnings are being tread as error"
|
||||||
|
message, usually displayed once per compiler run. */
|
||||||
|
bool some_warnings_are_errors;
|
||||||
|
|
||||||
|
/* True if it has been requested that warnings be treated as errors. */
|
||||||
|
bool warning_as_error_requested;
|
||||||
|
|
||||||
|
/* The number of option indexes that can be passed to warning() et
|
||||||
|
al. */
|
||||||
|
int n_opts;
|
||||||
|
|
||||||
|
/* For each option index that can be passed to warning() et al
|
||||||
|
(OPT_* from options.h when using this code with the core GCC
|
||||||
|
options), this array may contain a new kind that the diagnostic
|
||||||
|
should be changed to before reporting, or DK_UNSPECIFIED to leave
|
||||||
|
it as the reported kind, or DK_IGNORED to not report it at
|
||||||
|
all. */
|
||||||
|
diagnostic_t *classify_diagnostic;
|
||||||
|
|
||||||
|
/* History of all changes to the classifications above. This list
|
||||||
|
is stored in location-order, so we can search it, either
|
||||||
|
binary-wise or end-to-front, to find the most recent
|
||||||
|
classification for a given diagnostic, given the location of the
|
||||||
|
diagnostic. */
|
||||||
|
diagnostic_classification_change_t *classification_history;
|
||||||
|
|
||||||
|
/* The size of the above array. */
|
||||||
|
int n_classification_history;
|
||||||
|
|
||||||
|
/* For pragma push/pop. */
|
||||||
|
int *push_list;
|
||||||
|
int n_push;
|
||||||
|
|
||||||
|
/* True if we should print the source line with a caret indicating
|
||||||
|
the location. */
|
||||||
|
bool show_caret;
|
||||||
|
|
||||||
|
/* Maximum width of the source line printed. */
|
||||||
|
int caret_max_width;
|
||||||
|
|
||||||
|
/* True if we should print the command line option which controls
|
||||||
|
each diagnostic, if known. */
|
||||||
|
bool show_option_requested;
|
||||||
|
|
||||||
|
/* True if we should raise a SIGABRT on errors. */
|
||||||
|
bool abort_on_error;
|
||||||
|
|
||||||
|
/* True if we should show the column number on diagnostics. */
|
||||||
|
bool show_column;
|
||||||
|
|
||||||
|
/* True if pedwarns are errors. */
|
||||||
|
bool pedantic_errors;
|
||||||
|
|
||||||
|
/* True if permerrors are warnings. */
|
||||||
|
bool permissive;
|
||||||
|
|
||||||
|
/* The index of the option to associate with turning permerrors into
|
||||||
|
warnings. */
|
||||||
|
int opt_permissive;
|
||||||
|
|
||||||
|
/* True if errors are fatal. */
|
||||||
|
bool fatal_errors;
|
||||||
|
|
||||||
|
/* True if all warnings should be disabled. */
|
||||||
|
bool dc_inhibit_warnings;
|
||||||
|
|
||||||
|
/* True if warnings should be given in system headers. */
|
||||||
|
bool dc_warn_system_headers;
|
||||||
|
|
||||||
|
/* Maximum number of errors to report. */
|
||||||
|
unsigned int max_errors;
|
||||||
|
|
||||||
|
/* This function is called before any message is printed out. It is
|
||||||
|
responsible for preparing message prefix and such. For example, it
|
||||||
|
might say:
|
||||||
|
In file included from "/usr/local/include/curses.h:5:
|
||||||
|
from "/home/gdr/src/nifty_printer.h:56:
|
||||||
|
...
|
||||||
|
*/
|
||||||
|
diagnostic_starter_fn begin_diagnostic;
|
||||||
|
|
||||||
|
/* This function is called after the diagnostic message is printed. */
|
||||||
|
diagnostic_finalizer_fn end_diagnostic;
|
||||||
|
|
||||||
|
/* Client hook to report an internal error. */
|
||||||
|
void (*internal_error) (diagnostic_context *, const char *, va_list *);
|
||||||
|
|
||||||
|
/* Client hook to say whether the option controlling a diagnostic is
|
||||||
|
enabled. Returns nonzero if enabled, zero if disabled. */
|
||||||
|
int (*option_enabled) (int, void *);
|
||||||
|
|
||||||
|
/* Client information to pass as second argument to
|
||||||
|
option_enabled. */
|
||||||
|
void *option_state;
|
||||||
|
|
||||||
|
/* Client hook to return the name of an option that controls a
|
||||||
|
diagnostic. Returns malloced memory. The first diagnostic_t
|
||||||
|
argument is the kind of diagnostic before any reclassification
|
||||||
|
(of warnings as errors, etc.); the second is the kind after any
|
||||||
|
reclassification. May return NULL if no name is to be printed.
|
||||||
|
May be passed 0 as well as the index of a particular option. */
|
||||||
|
char *(*option_name) (diagnostic_context *, int, diagnostic_t, diagnostic_t);
|
||||||
|
|
||||||
|
/* Auxiliary data for client. */
|
||||||
|
void *x_data;
|
||||||
|
|
||||||
|
/* Used to detect that the last caret was printed at the same location. */
|
||||||
|
location_t last_location;
|
||||||
|
|
||||||
|
/* Used to detect when the input file stack has changed since last
|
||||||
|
described. */
|
||||||
|
const struct line_map *last_module;
|
||||||
|
|
||||||
|
int lock;
|
||||||
|
|
||||||
|
bool inhibit_notes_p;
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
diagnostic_inhibit_notes (diagnostic_context * context)
|
||||||
|
{
|
||||||
|
context->inhibit_notes_p = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Client supplied function to announce a diagnostic. */
|
||||||
|
#define diagnostic_starter(DC) (DC)->begin_diagnostic
|
||||||
|
|
||||||
|
/* Client supplied function called after a diagnostic message is
|
||||||
|
displayed. */
|
||||||
|
#define diagnostic_finalizer(DC) (DC)->end_diagnostic
|
||||||
|
|
||||||
|
/* Extension hooks for client. */
|
||||||
|
#define diagnostic_context_auxiliary_data(DC) (DC)->x_data
|
||||||
|
#define diagnostic_info_auxiliary_data(DI) (DI)->x_data
|
||||||
|
|
||||||
|
/* Same as pp_format_decoder. Works on 'diagnostic_context *'. */
|
||||||
|
#define diagnostic_format_decoder(DC) ((DC)->printer->format_decoder)
|
||||||
|
|
||||||
|
/* Same as output_prefixing_rule. Works on 'diagnostic_context *'. */
|
||||||
|
#define diagnostic_prefixing_rule(DC) ((DC)->printer->wrapping.rule)
|
||||||
|
|
||||||
|
/* Maximum characters per line in automatic line wrapping mode.
|
||||||
|
Zero means don't wrap lines. */
|
||||||
|
#define diagnostic_line_cutoff(DC) ((DC)->printer->wrapping.line_cutoff)
|
||||||
|
|
||||||
|
#define diagnostic_flush_buffer(DC) pp_base_flush ((DC)->printer)
|
||||||
|
|
||||||
|
/* True if the last module or file in which a diagnostic was reported is
|
||||||
|
different from the current one. */
|
||||||
|
#define diagnostic_last_module_changed(DC, MAP) \
|
||||||
|
((DC)->last_module != MAP)
|
||||||
|
|
||||||
|
/* Remember the current module or file as being the last one in which we
|
||||||
|
report a diagnostic. */
|
||||||
|
#define diagnostic_set_last_module(DC, MAP) \
|
||||||
|
(DC)->last_module = MAP
|
||||||
|
|
||||||
|
/* Raise SIGABRT on any diagnostic of severity DK_ERROR or higher. */
|
||||||
|
#define diagnostic_abort_on_error(DC) \
|
||||||
|
(DC)->abort_on_error = true
|
||||||
|
|
||||||
|
/* This diagnostic_context is used by front-ends that directly output
|
||||||
|
diagnostic messages without going through `error', `warning',
|
||||||
|
and similar functions. */
|
||||||
|
extern diagnostic_context *global_dc;
|
||||||
|
|
||||||
|
/* The total count of a KIND of diagnostics emitted so far. */
|
||||||
|
#define diagnostic_kind_count(DC, DK) (DC)->diagnostic_count[(int) (DK)]
|
||||||
|
|
||||||
|
/* The number of errors that have been issued so far. Ideally, these
|
||||||
|
would take a diagnostic_context as an argument. */
|
||||||
|
#define errorcount diagnostic_kind_count (global_dc, DK_ERROR)
|
||||||
|
/* Similarly, but for warnings. */
|
||||||
|
#define warningcount diagnostic_kind_count (global_dc, DK_WARNING)
|
||||||
|
/* Similarly, but for sorrys. */
|
||||||
|
#define sorrycount diagnostic_kind_count (global_dc, DK_SORRY)
|
||||||
|
|
||||||
|
/* Returns nonzero if warnings should be emitted. */
|
||||||
|
#define diagnostic_report_warnings_p(DC, LOC) \
|
||||||
|
(!(DC)->dc_inhibit_warnings \
|
||||||
|
&& !(in_system_header_at (LOC) && !(DC)->dc_warn_system_headers))
|
||||||
|
|
||||||
|
#define report_diagnostic(D) diagnostic_report_diagnostic (global_dc, D)
|
||||||
|
|
||||||
|
/* Override the column number to be used for reporting a
|
||||||
|
diagnostic. */
|
||||||
|
#define diagnostic_override_column(DI, COL) (DI)->override_column = (COL)
|
||||||
|
|
||||||
|
/* Override the option index to be used for reporting a
|
||||||
|
diagnostic. */
|
||||||
|
#define diagnostic_override_option_index(DI, OPTIDX) \
|
||||||
|
((DI)->option_index = (OPTIDX))
|
||||||
|
|
||||||
|
/* Diagnostic related functions. */
|
||||||
|
extern void diagnostic_initialize (diagnostic_context *, int);
|
||||||
|
extern void diagnostic_finish (diagnostic_context *);
|
||||||
|
extern void diagnostic_report_current_module (diagnostic_context *, location_t);
|
||||||
|
extern void diagnostic_show_locus (diagnostic_context *, const diagnostic_info *);
|
||||||
|
|
||||||
|
/* Force diagnostics controlled by OPTIDX to be kind KIND. */
|
||||||
|
extern diagnostic_t diagnostic_classify_diagnostic (diagnostic_context *,
|
||||||
|
int /* optidx */,
|
||||||
|
diagnostic_t /* kind */,
|
||||||
|
location_t);
|
||||||
|
extern void diagnostic_push_diagnostics (diagnostic_context *, location_t);
|
||||||
|
extern void diagnostic_pop_diagnostics (diagnostic_context *, location_t);
|
||||||
|
extern bool diagnostic_report_diagnostic (diagnostic_context *,
|
||||||
|
diagnostic_info *);
|
||||||
|
#ifdef ATTRIBUTE_GCC_DIAG
|
||||||
|
extern void diagnostic_set_info (diagnostic_info *, const char *, va_list *,
|
||||||
|
location_t, diagnostic_t) ATTRIBUTE_GCC_DIAG(2,0);
|
||||||
|
extern void diagnostic_set_info_translated (diagnostic_info *, const char *,
|
||||||
|
va_list *, location_t,
|
||||||
|
diagnostic_t)
|
||||||
|
ATTRIBUTE_GCC_DIAG(2,0);
|
||||||
|
extern void diagnostic_append_note (diagnostic_context *, location_t,
|
||||||
|
const char *, ...) ATTRIBUTE_GCC_DIAG(3,4);
|
||||||
|
#endif
|
||||||
|
extern char *diagnostic_build_prefix (diagnostic_context *, const diagnostic_info *);
|
||||||
|
void default_diagnostic_starter (diagnostic_context *, diagnostic_info *);
|
||||||
|
void default_diagnostic_finalizer (diagnostic_context *, diagnostic_info *);
|
||||||
|
void diagnostic_set_caret_max_width (diagnostic_context *context, int value);
|
||||||
|
|
||||||
|
|
||||||
|
/* Pure text formatting support functions. */
|
||||||
|
extern char *file_name_as_prefix (const char *);
|
||||||
|
|
||||||
|
#endif /* ! GCC_DIAGNOSTIC_H */
|
|
@ -0,0 +1,457 @@
|
||||||
|
/* Operations with long integers.
|
||||||
|
Copyright (C) 2006-2013 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by the
|
||||||
|
Free Software Foundation; either version 3, or (at your option) any
|
||||||
|
later version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GCC; see the file COPYING3. If not see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#ifndef DOUBLE_INT_H
|
||||||
|
#define DOUBLE_INT_H
|
||||||
|
|
||||||
|
/* A large integer is currently represented as a pair of HOST_WIDE_INTs.
|
||||||
|
It therefore represents a number with precision of
|
||||||
|
2 * HOST_BITS_PER_WIDE_INT bits (it is however possible that the
|
||||||
|
internal representation will change, if numbers with greater precision
|
||||||
|
are needed, so the users should not rely on it). The representation does
|
||||||
|
not contain any information about signedness of the represented value, so
|
||||||
|
it can be used to represent both signed and unsigned numbers. For
|
||||||
|
operations where the results depend on signedness (division, comparisons),
|
||||||
|
it must be specified separately. For each such operation, there are three
|
||||||
|
versions of the function -- double_int_op, that takes an extra UNS argument
|
||||||
|
giving the signedness of the values, and double_int_sop and double_int_uop
|
||||||
|
that stand for its specializations for signed and unsigned values.
|
||||||
|
|
||||||
|
You may also represent with numbers in smaller precision using double_int.
|
||||||
|
You however need to use double_int_ext (that fills in the bits of the
|
||||||
|
number over the prescribed precision with zeros or with the sign bit) before
|
||||||
|
operations that do not perform arithmetics modulo 2^precision (comparisons,
|
||||||
|
division), and possibly before storing the results, if you want to keep
|
||||||
|
them in some canonical form). In general, the signedness of double_int_ext
|
||||||
|
should match the signedness of the operation.
|
||||||
|
|
||||||
|
??? The components of double_int differ in signedness mostly for
|
||||||
|
historical reasons (they replace an older structure used to represent
|
||||||
|
numbers with precision higher than HOST_WIDE_INT). It might be less
|
||||||
|
confusing to have them both signed or both unsigned. */
|
||||||
|
|
||||||
|
struct double_int
|
||||||
|
{
|
||||||
|
/* Normally, we would define constructors to create instances.
|
||||||
|
Two things prevent us from doing so.
|
||||||
|
First, defining a constructor makes the class non-POD in C++03,
|
||||||
|
and we certainly want double_int to be a POD.
|
||||||
|
Second, the GCC conding conventions prefer explicit conversion,
|
||||||
|
and explicit conversion operators are not available until C++11. */
|
||||||
|
|
||||||
|
static double_int from_uhwi (unsigned HOST_WIDE_INT cst);
|
||||||
|
static double_int from_shwi (HOST_WIDE_INT cst);
|
||||||
|
static double_int from_pair (HOST_WIDE_INT high, unsigned HOST_WIDE_INT low);
|
||||||
|
|
||||||
|
/* Construct from a fuffer of length LEN. BUFFER will be read according
|
||||||
|
to byte endianess and word endianess. */
|
||||||
|
static double_int from_buffer (const unsigned char *buffer, int len);
|
||||||
|
|
||||||
|
/* No copy assignment operator or destructor to keep the type a POD. */
|
||||||
|
|
||||||
|
/* There are some special value-creation static member functions. */
|
||||||
|
|
||||||
|
static double_int mask (unsigned prec);
|
||||||
|
static double_int max_value (unsigned int prec, bool uns);
|
||||||
|
static double_int min_value (unsigned int prec, bool uns);
|
||||||
|
|
||||||
|
/* The following functions are mutating operations. */
|
||||||
|
|
||||||
|
double_int &operator ++ (); // prefix
|
||||||
|
double_int &operator -- (); // prefix
|
||||||
|
double_int &operator *= (double_int);
|
||||||
|
double_int &operator += (double_int);
|
||||||
|
double_int &operator -= (double_int);
|
||||||
|
double_int &operator &= (double_int);
|
||||||
|
double_int &operator ^= (double_int);
|
||||||
|
double_int &operator |= (double_int);
|
||||||
|
|
||||||
|
/* The following functions are non-mutating operations. */
|
||||||
|
|
||||||
|
/* Conversion functions. */
|
||||||
|
|
||||||
|
HOST_WIDE_INT to_shwi () const;
|
||||||
|
unsigned HOST_WIDE_INT to_uhwi () const;
|
||||||
|
|
||||||
|
/* Conversion query functions. */
|
||||||
|
|
||||||
|
bool fits_uhwi () const;
|
||||||
|
bool fits_shwi () const;
|
||||||
|
bool fits_hwi (bool uns) const;
|
||||||
|
|
||||||
|
/* Attribute query functions. */
|
||||||
|
|
||||||
|
int trailing_zeros () const;
|
||||||
|
int popcount () const;
|
||||||
|
|
||||||
|
/* Arithmetic query operations. */
|
||||||
|
|
||||||
|
bool multiple_of (double_int, bool, double_int *) const;
|
||||||
|
|
||||||
|
/* Arithmetic operation functions. */
|
||||||
|
|
||||||
|
/* The following operations perform arithmetics modulo 2^precision, so you
|
||||||
|
do not need to call .ext between them, even if you are representing
|
||||||
|
numbers with precision less than HOST_BITS_PER_DOUBLE_INT bits. */
|
||||||
|
|
||||||
|
double_int set_bit (unsigned) const;
|
||||||
|
double_int mul_with_sign (double_int, bool unsigned_p, bool *overflow) const;
|
||||||
|
double_int wide_mul_with_sign (double_int, bool unsigned_p,
|
||||||
|
double_int *higher, bool *overflow) const;
|
||||||
|
double_int add_with_sign (double_int, bool unsigned_p, bool *overflow) const;
|
||||||
|
double_int sub_with_overflow (double_int, bool *overflow) const;
|
||||||
|
double_int neg_with_overflow (bool *overflow) const;
|
||||||
|
|
||||||
|
double_int operator * (double_int) const;
|
||||||
|
double_int operator + (double_int) const;
|
||||||
|
double_int operator - (double_int) const;
|
||||||
|
double_int operator - () const;
|
||||||
|
double_int operator ~ () const;
|
||||||
|
double_int operator & (double_int) const;
|
||||||
|
double_int operator | (double_int) const;
|
||||||
|
double_int operator ^ (double_int) const;
|
||||||
|
double_int and_not (double_int) const;
|
||||||
|
|
||||||
|
double_int lshift (HOST_WIDE_INT count, unsigned int prec, bool arith) const;
|
||||||
|
double_int rshift (HOST_WIDE_INT count, unsigned int prec, bool arith) const;
|
||||||
|
double_int alshift (HOST_WIDE_INT count, unsigned int prec) const;
|
||||||
|
double_int arshift (HOST_WIDE_INT count, unsigned int prec) const;
|
||||||
|
double_int llshift (HOST_WIDE_INT count, unsigned int prec) const;
|
||||||
|
double_int lrshift (HOST_WIDE_INT count, unsigned int prec) const;
|
||||||
|
double_int lrotate (HOST_WIDE_INT count, unsigned int prec) const;
|
||||||
|
double_int rrotate (HOST_WIDE_INT count, unsigned int prec) const;
|
||||||
|
|
||||||
|
/* You must ensure that double_int::ext is called on the operands
|
||||||
|
of the following operations, if the precision of the numbers
|
||||||
|
is less than HOST_BITS_PER_DOUBLE_INT bits. */
|
||||||
|
|
||||||
|
double_int div (double_int, bool, unsigned) const;
|
||||||
|
double_int sdiv (double_int, unsigned) const;
|
||||||
|
double_int udiv (double_int, unsigned) const;
|
||||||
|
double_int mod (double_int, bool, unsigned) const;
|
||||||
|
double_int smod (double_int, unsigned) const;
|
||||||
|
double_int umod (double_int, unsigned) const;
|
||||||
|
double_int divmod_with_overflow (double_int, bool, unsigned,
|
||||||
|
double_int *, bool *) const;
|
||||||
|
double_int divmod (double_int, bool, unsigned, double_int *) const;
|
||||||
|
double_int sdivmod (double_int, unsigned, double_int *) const;
|
||||||
|
double_int udivmod (double_int, unsigned, double_int *) const;
|
||||||
|
|
||||||
|
/* Precision control functions. */
|
||||||
|
|
||||||
|
double_int ext (unsigned prec, bool uns) const;
|
||||||
|
double_int zext (unsigned prec) const;
|
||||||
|
double_int sext (unsigned prec) const;
|
||||||
|
|
||||||
|
/* Comparative functions. */
|
||||||
|
|
||||||
|
bool is_zero () const;
|
||||||
|
bool is_one () const;
|
||||||
|
bool is_minus_one () const;
|
||||||
|
bool is_negative () const;
|
||||||
|
|
||||||
|
int cmp (double_int b, bool uns) const;
|
||||||
|
int ucmp (double_int b) const;
|
||||||
|
int scmp (double_int b) const;
|
||||||
|
|
||||||
|
bool ult (double_int b) const;
|
||||||
|
bool ule (double_int b) const;
|
||||||
|
bool ugt (double_int b) const;
|
||||||
|
bool slt (double_int b) const;
|
||||||
|
bool sle (double_int b) const;
|
||||||
|
bool sgt (double_int b) const;
|
||||||
|
|
||||||
|
double_int max (double_int b, bool uns);
|
||||||
|
double_int smax (double_int b);
|
||||||
|
double_int umax (double_int b);
|
||||||
|
|
||||||
|
double_int min (double_int b, bool uns);
|
||||||
|
double_int smin (double_int b);
|
||||||
|
double_int umin (double_int b);
|
||||||
|
|
||||||
|
bool operator == (double_int cst2) const;
|
||||||
|
bool operator != (double_int cst2) const;
|
||||||
|
|
||||||
|
/* Please migrate away from using these member variables publically. */
|
||||||
|
|
||||||
|
unsigned HOST_WIDE_INT low;
|
||||||
|
HOST_WIDE_INT high;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#define HOST_BITS_PER_DOUBLE_INT (2 * HOST_BITS_PER_WIDE_INT)
|
||||||
|
|
||||||
|
/* Constructors and conversions. */
|
||||||
|
|
||||||
|
/* Constructs double_int from integer CST. The bits over the precision of
|
||||||
|
HOST_WIDE_INT are filled with the sign bit. */
|
||||||
|
|
||||||
|
inline double_int
|
||||||
|
double_int::from_shwi (HOST_WIDE_INT cst)
|
||||||
|
{
|
||||||
|
double_int r;
|
||||||
|
r.low = (unsigned HOST_WIDE_INT) cst;
|
||||||
|
r.high = cst < 0 ? -1 : 0;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Some useful constants. */
|
||||||
|
/* FIXME(crowl): Maybe remove after converting callers?
|
||||||
|
The problem is that a named constant would not be as optimizable,
|
||||||
|
while the functional syntax is more verbose. */
|
||||||
|
|
||||||
|
#define double_int_minus_one (double_int::from_shwi (-1))
|
||||||
|
#define double_int_zero (double_int::from_shwi (0))
|
||||||
|
#define double_int_one (double_int::from_shwi (1))
|
||||||
|
#define double_int_two (double_int::from_shwi (2))
|
||||||
|
#define double_int_ten (double_int::from_shwi (10))
|
||||||
|
|
||||||
|
/* Constructs double_int from unsigned integer CST. The bits over the
|
||||||
|
precision of HOST_WIDE_INT are filled with zeros. */
|
||||||
|
|
||||||
|
inline double_int
|
||||||
|
double_int::from_uhwi (unsigned HOST_WIDE_INT cst)
|
||||||
|
{
|
||||||
|
double_int r;
|
||||||
|
r.low = cst;
|
||||||
|
r.high = 0;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline double_int
|
||||||
|
double_int::from_pair (HOST_WIDE_INT high, unsigned HOST_WIDE_INT low)
|
||||||
|
{
|
||||||
|
double_int r;
|
||||||
|
r.low = low;
|
||||||
|
r.high = high;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline double_int &
|
||||||
|
double_int::operator ++ ()
|
||||||
|
{
|
||||||
|
*this += double_int_one;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline double_int &
|
||||||
|
double_int::operator -- ()
|
||||||
|
{
|
||||||
|
*this -= double_int_one;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline double_int &
|
||||||
|
double_int::operator *= (double_int b)
|
||||||
|
{
|
||||||
|
*this = *this * b;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline double_int &
|
||||||
|
double_int::operator += (double_int b)
|
||||||
|
{
|
||||||
|
*this = *this + b;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline double_int &
|
||||||
|
double_int::operator -= (double_int b)
|
||||||
|
{
|
||||||
|
*this = *this - b;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline double_int &
|
||||||
|
double_int::operator &= (double_int b)
|
||||||
|
{
|
||||||
|
*this = *this & b;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline double_int &
|
||||||
|
double_int::operator ^= (double_int b)
|
||||||
|
{
|
||||||
|
*this = *this ^ b;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline double_int &
|
||||||
|
double_int::operator |= (double_int b)
|
||||||
|
{
|
||||||
|
*this = *this | b;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns value of CST as a signed number. CST must satisfy
|
||||||
|
double_int::fits_signed. */
|
||||||
|
|
||||||
|
inline HOST_WIDE_INT
|
||||||
|
double_int::to_shwi () const
|
||||||
|
{
|
||||||
|
return (HOST_WIDE_INT) low;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns value of CST as an unsigned number. CST must satisfy
|
||||||
|
double_int::fits_unsigned. */
|
||||||
|
|
||||||
|
inline unsigned HOST_WIDE_INT
|
||||||
|
double_int::to_uhwi () const
|
||||||
|
{
|
||||||
|
return low;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns true if CST fits in unsigned HOST_WIDE_INT. */
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
double_int::fits_uhwi () const
|
||||||
|
{
|
||||||
|
return high == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Logical operations. */
|
||||||
|
|
||||||
|
/* Returns ~A. */
|
||||||
|
|
||||||
|
inline double_int
|
||||||
|
double_int::operator ~ () const
|
||||||
|
{
|
||||||
|
double_int result;
|
||||||
|
result.low = ~low;
|
||||||
|
result.high = ~high;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns A | B. */
|
||||||
|
|
||||||
|
inline double_int
|
||||||
|
double_int::operator | (double_int b) const
|
||||||
|
{
|
||||||
|
double_int result;
|
||||||
|
result.low = low | b.low;
|
||||||
|
result.high = high | b.high;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns A & B. */
|
||||||
|
|
||||||
|
inline double_int
|
||||||
|
double_int::operator & (double_int b) const
|
||||||
|
{
|
||||||
|
double_int result;
|
||||||
|
result.low = low & b.low;
|
||||||
|
result.high = high & b.high;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns A & ~B. */
|
||||||
|
|
||||||
|
inline double_int
|
||||||
|
double_int::and_not (double_int b) const
|
||||||
|
{
|
||||||
|
double_int result;
|
||||||
|
result.low = low & ~b.low;
|
||||||
|
result.high = high & ~b.high;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns A ^ B. */
|
||||||
|
|
||||||
|
inline double_int
|
||||||
|
double_int::operator ^ (double_int b) const
|
||||||
|
{
|
||||||
|
double_int result;
|
||||||
|
result.low = low ^ b.low;
|
||||||
|
result.high = high ^ b.high;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dump_double_int (FILE *, double_int, bool);
|
||||||
|
|
||||||
|
#define ALL_ONES (~((unsigned HOST_WIDE_INT) 0))
|
||||||
|
|
||||||
|
/* The operands of the following comparison functions must be processed
|
||||||
|
with double_int_ext, if their precision is less than
|
||||||
|
HOST_BITS_PER_DOUBLE_INT bits. */
|
||||||
|
|
||||||
|
/* Returns true if CST is zero. */
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
double_int::is_zero () const
|
||||||
|
{
|
||||||
|
return low == 0 && high == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns true if CST is one. */
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
double_int::is_one () const
|
||||||
|
{
|
||||||
|
return low == 1 && high == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns true if CST is minus one. */
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
double_int::is_minus_one () const
|
||||||
|
{
|
||||||
|
return low == ALL_ONES && high == -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns true if CST is negative. */
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
double_int::is_negative () const
|
||||||
|
{
|
||||||
|
return high < 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns true if CST1 == CST2. */
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
double_int::operator == (double_int cst2) const
|
||||||
|
{
|
||||||
|
return low == cst2.low && high == cst2.high;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns true if CST1 != CST2. */
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
double_int::operator != (double_int cst2) const
|
||||||
|
{
|
||||||
|
return low != cst2.low || high != cst2.high;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return number of set bits of CST. */
|
||||||
|
|
||||||
|
inline int
|
||||||
|
double_int::popcount () const
|
||||||
|
{
|
||||||
|
return popcount_hwi (high) + popcount_hwi (low);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef GENERATOR_FILE
|
||||||
|
/* Conversion to and from GMP integer representations. */
|
||||||
|
|
||||||
|
void mpz_set_double_int (mpz_t, double_int, bool);
|
||||||
|
double_int mpz_get_double_int (const_tree, mpz_t, bool);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* DOUBLE_INT_H */
|
|
@ -0,0 +1,166 @@
|
||||||
|
/* Definitions for the shared dumpfile.
|
||||||
|
Copyright (C) 2004-2013 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GCC; see the file COPYING3. If not see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef GCC_DUMPFILE_H
|
||||||
|
#define GCC_DUMPFILE_H 1
|
||||||
|
|
||||||
|
#include "line-map.h"
|
||||||
|
|
||||||
|
/* Different tree dump places. When you add new tree dump places,
|
||||||
|
extend the DUMP_FILES array in dumpfile.c. */
|
||||||
|
enum tree_dump_index
|
||||||
|
{
|
||||||
|
TDI_none, /* No dump */
|
||||||
|
TDI_cgraph, /* dump function call graph. */
|
||||||
|
TDI_tu, /* dump the whole translation unit. */
|
||||||
|
TDI_class, /* dump class hierarchy. */
|
||||||
|
TDI_original, /* dump each function before optimizing it */
|
||||||
|
TDI_generic, /* dump each function after genericizing it */
|
||||||
|
TDI_nested, /* dump each function after unnesting it */
|
||||||
|
TDI_tree_all, /* enable all the GENERIC/GIMPLE dumps. */
|
||||||
|
TDI_rtl_all, /* enable all the RTL dumps. */
|
||||||
|
TDI_ipa_all, /* enable all the IPA dumps. */
|
||||||
|
|
||||||
|
TDI_end
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Bit masks to control dumping. Not all values are applicable to all
|
||||||
|
dumps. Add new ones at the end. When you define new values, extend
|
||||||
|
the DUMP_OPTIONS array in dumpfile.c. The TDF_* flags coexist with
|
||||||
|
MSG_* flags (for -fopt-info) and the bit values must be chosen to
|
||||||
|
allow that. */
|
||||||
|
#define TDF_ADDRESS (1 << 0) /* dump node addresses */
|
||||||
|
#define TDF_SLIM (1 << 1) /* don't go wild following links */
|
||||||
|
#define TDF_RAW (1 << 2) /* don't unparse the function */
|
||||||
|
#define TDF_DETAILS (1 << 3) /* show more detailed info about
|
||||||
|
each pass */
|
||||||
|
#define TDF_STATS (1 << 4) /* dump various statistics about
|
||||||
|
each pass */
|
||||||
|
#define TDF_BLOCKS (1 << 5) /* display basic block boundaries */
|
||||||
|
#define TDF_VOPS (1 << 6) /* display virtual operands */
|
||||||
|
#define TDF_LINENO (1 << 7) /* display statement line numbers */
|
||||||
|
#define TDF_UID (1 << 8) /* display decl UIDs */
|
||||||
|
|
||||||
|
#define TDF_TREE (1 << 9) /* is a tree dump */
|
||||||
|
#define TDF_RTL (1 << 10) /* is a RTL dump */
|
||||||
|
#define TDF_IPA (1 << 11) /* is an IPA dump */
|
||||||
|
#define TDF_STMTADDR (1 << 12) /* Address of stmt. */
|
||||||
|
|
||||||
|
#define TDF_GRAPH (1 << 13) /* a graph dump is being emitted */
|
||||||
|
#define TDF_MEMSYMS (1 << 14) /* display memory symbols in expr.
|
||||||
|
Implies TDF_VOPS. */
|
||||||
|
|
||||||
|
#define TDF_DIAGNOSTIC (1 << 15) /* A dump to be put in a diagnostic
|
||||||
|
message. */
|
||||||
|
#define TDF_VERBOSE (1 << 16) /* A dump that uses the full tree
|
||||||
|
dumper to print stmts. */
|
||||||
|
#define TDF_RHS_ONLY (1 << 17) /* a flag to only print the RHS of
|
||||||
|
a gimple stmt. */
|
||||||
|
#define TDF_ASMNAME (1 << 18) /* display asm names of decls */
|
||||||
|
#define TDF_EH (1 << 19) /* display EH region number
|
||||||
|
holding this gimple statement. */
|
||||||
|
#define TDF_NOUID (1 << 20) /* omit UIDs from dumps. */
|
||||||
|
#define TDF_ALIAS (1 << 21) /* display alias information */
|
||||||
|
#define TDF_ENUMERATE_LOCALS (1 << 22) /* Enumerate locals by uid. */
|
||||||
|
#define TDF_CSELIB (1 << 23) /* Dump cselib details. */
|
||||||
|
#define TDF_SCEV (1 << 24) /* Dump SCEV details. */
|
||||||
|
#define TDF_COMMENT (1 << 25) /* Dump lines with prefix ";;" */
|
||||||
|
#define MSG_OPTIMIZED_LOCATIONS (1 << 26) /* -fopt-info optimized sources */
|
||||||
|
#define MSG_MISSED_OPTIMIZATION (1 << 27) /* missed opportunities */
|
||||||
|
#define MSG_NOTE (1 << 28) /* general optimization info */
|
||||||
|
#define MSG_ALL (MSG_OPTIMIZED_LOCATIONS | MSG_MISSED_OPTIMIZATION \
|
||||||
|
| MSG_NOTE)
|
||||||
|
|
||||||
|
|
||||||
|
/* Flags to control high-level -fopt-info dumps. Usually these flags
|
||||||
|
define a group of passes. An optimization pass can be part of
|
||||||
|
multiple groups. */
|
||||||
|
#define OPTGROUP_NONE (0)
|
||||||
|
#define OPTGROUP_IPA (1 << 1) /* IPA optimization passes */
|
||||||
|
#define OPTGROUP_LOOP (1 << 2) /* Loop optimization passes */
|
||||||
|
#define OPTGROUP_INLINE (1 << 3) /* Inlining passes */
|
||||||
|
#define OPTGROUP_VEC (1 << 4) /* Vectorization passes */
|
||||||
|
#define OPTGROUP_ALL (OPTGROUP_IPA | OPTGROUP_LOOP | OPTGROUP_INLINE \
|
||||||
|
| OPTGROUP_VEC)
|
||||||
|
|
||||||
|
/* Define a tree dump switch. */
|
||||||
|
struct dump_file_info
|
||||||
|
{
|
||||||
|
const char *suffix; /* suffix to give output file. */
|
||||||
|
const char *swtch; /* command line dump switch */
|
||||||
|
const char *glob; /* command line glob */
|
||||||
|
const char *pfilename; /* filename for the pass-specific stream */
|
||||||
|
const char *alt_filename; /* filename for the -fopt-info stream */
|
||||||
|
FILE *pstream; /* pass-specific dump stream */
|
||||||
|
FILE *alt_stream; /* -fopt-info stream */
|
||||||
|
int pflags; /* dump flags */
|
||||||
|
int optgroup_flags; /* optgroup flags for -fopt-info */
|
||||||
|
int alt_flags; /* flags for opt-info */
|
||||||
|
int pstate; /* state of pass-specific stream */
|
||||||
|
int alt_state; /* state of the -fopt-info stream */
|
||||||
|
int num; /* dump file number */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* In dumpfile.c */
|
||||||
|
extern char *get_dump_file_name (int);
|
||||||
|
extern int dump_initialized_p (int);
|
||||||
|
extern FILE *dump_begin (int, int *);
|
||||||
|
extern void dump_end (int, FILE *);
|
||||||
|
extern int dump_start (int, int *);
|
||||||
|
extern void dump_finish (int);
|
||||||
|
extern void dump_node (const_tree, int, FILE *);
|
||||||
|
extern int dump_switch_p (const char *);
|
||||||
|
extern int opt_info_switch_p (const char *);
|
||||||
|
extern const char *dump_flag_name (int);
|
||||||
|
extern void dump_printf (int, const char *, ...) ATTRIBUTE_PRINTF_2;
|
||||||
|
extern void dump_printf_loc (int, source_location,
|
||||||
|
const char *, ...) ATTRIBUTE_PRINTF_3;
|
||||||
|
extern void dump_basic_block (int, basic_block, int);
|
||||||
|
extern void dump_generic_expr_loc (int, source_location, int, tree);
|
||||||
|
extern void dump_generic_expr (int, int, tree);
|
||||||
|
extern void dump_gimple_stmt_loc (int, source_location, int, gimple, int);
|
||||||
|
extern void dump_gimple_stmt (int, int, gimple, int);
|
||||||
|
extern void print_combine_total_stats (void);
|
||||||
|
extern unsigned int dump_register (const char *, const char *, const char *,
|
||||||
|
int, int);
|
||||||
|
extern bool enable_rtl_dump_file (void);
|
||||||
|
|
||||||
|
/* In combine.c */
|
||||||
|
extern void dump_combine_total_stats (FILE *);
|
||||||
|
/* In cfghooks.c */
|
||||||
|
extern void dump_bb (FILE *, basic_block, int, int);
|
||||||
|
|
||||||
|
/* Global variables used to communicate with passes. */
|
||||||
|
extern FILE *dump_file;
|
||||||
|
extern FILE *alt_dump_file;
|
||||||
|
extern int dump_flags;
|
||||||
|
extern const char *dump_file_name;
|
||||||
|
|
||||||
|
/* Return the dump_file_info for the given phase. */
|
||||||
|
extern struct dump_file_info *get_dump_file_info (int);
|
||||||
|
|
||||||
|
/* Return true if any of the dumps is enabled, false otherwise. */
|
||||||
|
static inline bool
|
||||||
|
dump_enabled_p (void)
|
||||||
|
{
|
||||||
|
return (dump_file || alt_dump_file);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* GCC_DUMPFILE_H */
|
|
@ -0,0 +1,119 @@
|
||||||
|
/* Exported functions from emit-rtl.c
|
||||||
|
Copyright (C) 2004-2013 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free
|
||||||
|
Software Foundation; either version 3, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GCC; see the file COPYING3. If not see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#ifndef GCC_EMIT_RTL_H
|
||||||
|
#define GCC_EMIT_RTL_H
|
||||||
|
|
||||||
|
/* Return whether two MEM_ATTRs are equal. */
|
||||||
|
bool mem_attrs_eq_p (const struct mem_attrs *, const struct mem_attrs *);
|
||||||
|
|
||||||
|
/* Set the alias set of MEM to SET. */
|
||||||
|
extern void set_mem_alias_set (rtx, alias_set_type);
|
||||||
|
|
||||||
|
/* Set the alignment of MEM to ALIGN bits. */
|
||||||
|
extern void set_mem_align (rtx, unsigned int);
|
||||||
|
|
||||||
|
/* Set the address space of MEM to ADDRSPACE. */
|
||||||
|
extern void set_mem_addr_space (rtx, addr_space_t);
|
||||||
|
|
||||||
|
/* Set the expr for MEM to EXPR. */
|
||||||
|
extern void set_mem_expr (rtx, tree);
|
||||||
|
|
||||||
|
/* Set the offset for MEM to OFFSET. */
|
||||||
|
extern void set_mem_offset (rtx, HOST_WIDE_INT);
|
||||||
|
|
||||||
|
/* Clear the offset recorded for MEM. */
|
||||||
|
extern void clear_mem_offset (rtx);
|
||||||
|
|
||||||
|
/* Set the size for MEM to SIZE. */
|
||||||
|
extern void set_mem_size (rtx, HOST_WIDE_INT);
|
||||||
|
|
||||||
|
/* Clear the size recorded for MEM. */
|
||||||
|
extern void clear_mem_size (rtx);
|
||||||
|
|
||||||
|
/* Set the attributes for MEM appropriate for a spill slot. */
|
||||||
|
extern void set_mem_attrs_for_spill (rtx);
|
||||||
|
extern tree get_spill_slot_decl (bool);
|
||||||
|
|
||||||
|
/* Return a memory reference like MEMREF, but with its address changed to
|
||||||
|
ADDR. The caller is asserting that the actual piece of memory pointed
|
||||||
|
to is the same, just the form of the address is being changed, such as
|
||||||
|
by putting something into a register. */
|
||||||
|
extern rtx replace_equiv_address (rtx, rtx);
|
||||||
|
|
||||||
|
/* Likewise, but the reference is not required to be valid. */
|
||||||
|
extern rtx replace_equiv_address_nv (rtx, rtx);
|
||||||
|
|
||||||
|
extern rtx gen_blockage (void);
|
||||||
|
extern rtvec gen_rtvec (int, ...);
|
||||||
|
extern rtx copy_insn_1 (rtx);
|
||||||
|
extern rtx copy_insn (rtx);
|
||||||
|
extern rtx copy_delay_slot_insn (rtx);
|
||||||
|
extern rtx gen_int_mode (HOST_WIDE_INT, enum machine_mode);
|
||||||
|
extern rtx emit_copy_of_insn_after (rtx, rtx);
|
||||||
|
extern void set_reg_attrs_from_value (rtx, rtx);
|
||||||
|
extern void set_reg_attrs_for_parm (rtx, rtx);
|
||||||
|
extern void set_reg_attrs_for_decl_rtl (tree t, rtx x);
|
||||||
|
extern void adjust_reg_mode (rtx, enum machine_mode);
|
||||||
|
extern int mem_expr_equal_p (const_tree, const_tree);
|
||||||
|
|
||||||
|
extern bool need_atomic_barrier_p (enum memmodel, bool);
|
||||||
|
|
||||||
|
/* Return the first insn of the current sequence or current function. */
|
||||||
|
|
||||||
|
static inline rtx
|
||||||
|
get_insns (void)
|
||||||
|
{
|
||||||
|
return crtl->emit.x_first_insn;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Specify a new insn as the first in the chain. */
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
set_first_insn (rtx insn)
|
||||||
|
{
|
||||||
|
gcc_checking_assert (!insn || !PREV_INSN (insn));
|
||||||
|
crtl->emit.x_first_insn = insn;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the last insn emitted in current sequence or current function. */
|
||||||
|
|
||||||
|
static inline rtx
|
||||||
|
get_last_insn (void)
|
||||||
|
{
|
||||||
|
return crtl->emit.x_last_insn;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Specify a new insn as the last in the chain. */
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
set_last_insn (rtx insn)
|
||||||
|
{
|
||||||
|
gcc_checking_assert (!insn || !NEXT_INSN (insn));
|
||||||
|
crtl->emit.x_last_insn = insn;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return a number larger than any instruction's uid in this function. */
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
get_max_uid (void)
|
||||||
|
{
|
||||||
|
return crtl->emit.x_cur_insn_uid;
|
||||||
|
}
|
||||||
|
#endif /* GCC_EMIT_RTL_H */
|
|
@ -0,0 +1,335 @@
|
||||||
|
/* Exception Handling interface routines.
|
||||||
|
Copyright (C) 1996-2013 Free Software Foundation, Inc.
|
||||||
|
Contributed by Mike Stump <mrs@cygnus.com>.
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free
|
||||||
|
Software Foundation; either version 3, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GCC; see the file COPYING3. If not see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
/* No include guards here, but define an include file marker anyway, so
|
||||||
|
that the compiler can keep track of where this file is included. This
|
||||||
|
is e.g. used to avoid including this file in front-end specific files. */
|
||||||
|
#ifndef GCC_EXCEPT_H
|
||||||
|
# define GCC_EXCEPT_H
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "hashtab.h"
|
||||||
|
|
||||||
|
struct function;
|
||||||
|
struct eh_region_d;
|
||||||
|
struct pointer_map_t;
|
||||||
|
|
||||||
|
/* The type of an exception region. */
|
||||||
|
enum eh_region_type
|
||||||
|
{
|
||||||
|
/* CLEANUP regions implement e.g. destructors run when exiting a block.
|
||||||
|
They can be generated from both GIMPLE_TRY_FINALLY and GIMPLE_TRY_CATCH
|
||||||
|
nodes. It is expected by the runtime that cleanup regions will *not*
|
||||||
|
resume normal program flow, but will continue propagation of the
|
||||||
|
exception. */
|
||||||
|
ERT_CLEANUP,
|
||||||
|
|
||||||
|
/* TRY regions implement catching an exception. The list of types associated
|
||||||
|
with the attached catch handlers is examined in order by the runtime and
|
||||||
|
control is transferred to the appropriate handler. Note that a NULL type
|
||||||
|
list is a catch-all handler, and that it will catch *all* exceptions
|
||||||
|
including those originating from a different language. */
|
||||||
|
ERT_TRY,
|
||||||
|
|
||||||
|
/* ALLOWED_EXCEPTIONS regions implement exception filtering, e.g. the
|
||||||
|
throw(type-list) specification that can be added to C++ functions.
|
||||||
|
The runtime examines the thrown exception vs the type list, and if
|
||||||
|
the exception does not match, transfers control to the handler. The
|
||||||
|
normal handler for C++ calls __cxa_call_unexpected. */
|
||||||
|
ERT_ALLOWED_EXCEPTIONS,
|
||||||
|
|
||||||
|
/* MUST_NOT_THROW regions prevent all exceptions from propagating. This
|
||||||
|
region type is used in C++ to surround destructors being run inside a
|
||||||
|
CLEANUP region. This differs from an ALLOWED_EXCEPTIONS region with
|
||||||
|
an empty type list in that the runtime is prepared to terminate the
|
||||||
|
program directly. We only generate code for MUST_NOT_THROW regions
|
||||||
|
along control paths that are already handling an exception within the
|
||||||
|
current function. */
|
||||||
|
ERT_MUST_NOT_THROW
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* A landing pad for a given exception region. Any transfer of control
|
||||||
|
from the EH runtime to the function happens at a landing pad. */
|
||||||
|
|
||||||
|
struct GTY(()) eh_landing_pad_d
|
||||||
|
{
|
||||||
|
/* The linked list of all landing pads associated with the region. */
|
||||||
|
struct eh_landing_pad_d *next_lp;
|
||||||
|
|
||||||
|
/* The region with which this landing pad is associated. */
|
||||||
|
struct eh_region_d *region;
|
||||||
|
|
||||||
|
/* At the gimple level, the location to which control will be transferred
|
||||||
|
for this landing pad. There can be both EH and normal edges into the
|
||||||
|
block containing the post-landing-pad label. */
|
||||||
|
tree post_landing_pad;
|
||||||
|
|
||||||
|
/* At the rtl level, the location to which the runtime will transfer
|
||||||
|
control. This differs from the post-landing-pad in that the target's
|
||||||
|
EXCEPTION_RECEIVER pattern will be expanded here, as well as other
|
||||||
|
bookkeeping specific to exceptions. There must not be normal edges
|
||||||
|
into the block containing the landing-pad label. */
|
||||||
|
rtx landing_pad;
|
||||||
|
|
||||||
|
/* The index of this landing pad within fun->eh->lp_array. */
|
||||||
|
int index;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* A catch handler associated with an ERT_TRY region. */
|
||||||
|
|
||||||
|
struct GTY(()) eh_catch_d
|
||||||
|
{
|
||||||
|
/* The double-linked list of all catch handlers for the region. */
|
||||||
|
struct eh_catch_d *next_catch;
|
||||||
|
struct eh_catch_d *prev_catch;
|
||||||
|
|
||||||
|
/* A TREE_LIST of runtime type objects that this catch handler
|
||||||
|
will catch, or NULL if all exceptions are caught. */
|
||||||
|
tree type_list;
|
||||||
|
|
||||||
|
/* A TREE_LIST of INTEGER_CSTs that correspond to the type_list entries,
|
||||||
|
having been mapped by assign_filter_values. These integers are to be
|
||||||
|
compared against the __builtin_eh_filter value. */
|
||||||
|
tree filter_list;
|
||||||
|
|
||||||
|
/* The code that should be executed if this catch handler matches the
|
||||||
|
thrown exception. This label is only maintained until
|
||||||
|
pass_lower_eh_dispatch, at which point it is cleared. */
|
||||||
|
tree label;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Describes one exception region. */
|
||||||
|
|
||||||
|
struct GTY(()) eh_region_d
|
||||||
|
{
|
||||||
|
/* The immediately surrounding region. */
|
||||||
|
struct eh_region_d *outer;
|
||||||
|
|
||||||
|
/* The list of immediately contained regions. */
|
||||||
|
struct eh_region_d *inner;
|
||||||
|
struct eh_region_d *next_peer;
|
||||||
|
|
||||||
|
/* The index of this region within fun->eh->region_array. */
|
||||||
|
int index;
|
||||||
|
|
||||||
|
/* Each region does exactly one thing. */
|
||||||
|
enum eh_region_type type;
|
||||||
|
|
||||||
|
/* Holds the action to perform based on the preceding type. */
|
||||||
|
union eh_region_u {
|
||||||
|
struct eh_region_u_try {
|
||||||
|
/* The double-linked list of all catch handlers for this region. */
|
||||||
|
struct eh_catch_d *first_catch;
|
||||||
|
struct eh_catch_d *last_catch;
|
||||||
|
} GTY ((tag ("ERT_TRY"))) eh_try;
|
||||||
|
|
||||||
|
struct eh_region_u_allowed {
|
||||||
|
/* A TREE_LIST of runtime type objects allowed to pass. */
|
||||||
|
tree type_list;
|
||||||
|
/* The code that should be executed if the thrown exception does
|
||||||
|
not match the type list. This label is only maintained until
|
||||||
|
pass_lower_eh_dispatch, at which point it is cleared. */
|
||||||
|
tree label;
|
||||||
|
/* The integer that will be passed by the runtime to signal that
|
||||||
|
we should execute the code at LABEL. This integer is assigned
|
||||||
|
by assign_filter_values and is to be compared against the
|
||||||
|
__builtin_eh_filter value. */
|
||||||
|
int filter;
|
||||||
|
} GTY ((tag ("ERT_ALLOWED_EXCEPTIONS"))) allowed;
|
||||||
|
|
||||||
|
struct eh_region_u_must_not_throw {
|
||||||
|
/* A function decl to be invoked if this region is actually reachable
|
||||||
|
from within the function, rather than implementable from the runtime.
|
||||||
|
The normal way for this to happen is for there to be a CLEANUP region
|
||||||
|
contained within this MUST_NOT_THROW region. Note that if the
|
||||||
|
runtime handles the MUST_NOT_THROW region, we have no control over
|
||||||
|
what termination function is called; it will be decided by the
|
||||||
|
personality function in effect for this CIE. */
|
||||||
|
tree failure_decl;
|
||||||
|
/* The location assigned to the call of FAILURE_DECL, if expanded. */
|
||||||
|
location_t failure_loc;
|
||||||
|
} GTY ((tag ("ERT_MUST_NOT_THROW"))) must_not_throw;
|
||||||
|
} GTY ((desc ("%0.type"))) u;
|
||||||
|
|
||||||
|
/* The list of landing pads associated with this region. */
|
||||||
|
struct eh_landing_pad_d *landing_pads;
|
||||||
|
|
||||||
|
/* EXC_PTR and FILTER values copied from the runtime for this region.
|
||||||
|
Each region gets its own psuedos so that if there are nested exceptions
|
||||||
|
we do not overwrite the values of the first exception. */
|
||||||
|
rtx exc_ptr_reg, filter_reg;
|
||||||
|
|
||||||
|
/* True if this region should use __cxa_end_cleanup instead
|
||||||
|
of _Unwind_Resume. */
|
||||||
|
bool use_cxa_end_cleanup;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct eh_landing_pad_d *eh_landing_pad;
|
||||||
|
typedef struct eh_catch_d *eh_catch;
|
||||||
|
typedef struct eh_region_d *eh_region;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* The exception status for each function. */
|
||||||
|
|
||||||
|
struct GTY(()) eh_status
|
||||||
|
{
|
||||||
|
/* The tree of all regions for this function. */
|
||||||
|
eh_region region_tree;
|
||||||
|
|
||||||
|
/* The same information as an indexable array. */
|
||||||
|
vec<eh_region, va_gc> *region_array;
|
||||||
|
|
||||||
|
/* The landing pads as an indexable array. */
|
||||||
|
vec<eh_landing_pad, va_gc> *lp_array;
|
||||||
|
|
||||||
|
/* At the gimple level, a mapping from gimple statement to landing pad
|
||||||
|
or must-not-throw region. See record_stmt_eh_region. */
|
||||||
|
htab_t GTY((param_is (struct throw_stmt_node))) throw_stmt_table;
|
||||||
|
|
||||||
|
/* All of the runtime type data used by the function. These objects
|
||||||
|
are emitted to the lang-specific-data-area for the function. */
|
||||||
|
vec<tree, va_gc> *ttype_data;
|
||||||
|
|
||||||
|
/* The table of all action chains. These encode the eh_region tree in
|
||||||
|
a compact form for use by the runtime, and is also emitted to the
|
||||||
|
lang-specific-data-area. Note that the ARM EABI uses a different
|
||||||
|
format for the encoding than all other ports. */
|
||||||
|
union eh_status_u {
|
||||||
|
vec<tree, va_gc> *GTY((tag ("1"))) arm_eabi;
|
||||||
|
vec<uchar, va_gc> *GTY((tag ("0"))) other;
|
||||||
|
} GTY ((desc ("targetm.arm_eabi_unwinder"))) ehspec_data;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* Invokes CALLBACK for every exception handler label. Only used by old
|
||||||
|
loop hackery; should not be used by new code. */
|
||||||
|
extern void for_each_eh_label (void (*) (rtx));
|
||||||
|
|
||||||
|
extern void init_eh_for_function (void);
|
||||||
|
|
||||||
|
extern void remove_eh_landing_pad (eh_landing_pad);
|
||||||
|
extern void remove_eh_handler (eh_region);
|
||||||
|
extern void remove_unreachable_eh_regions (sbitmap);
|
||||||
|
|
||||||
|
extern bool current_function_has_exception_handlers (void);
|
||||||
|
extern void output_function_exception_table (const char *);
|
||||||
|
|
||||||
|
extern rtx expand_builtin_eh_pointer (tree);
|
||||||
|
extern rtx expand_builtin_eh_filter (tree);
|
||||||
|
extern rtx expand_builtin_eh_copy_values (tree);
|
||||||
|
extern void expand_builtin_unwind_init (void);
|
||||||
|
extern rtx expand_builtin_eh_return_data_regno (tree);
|
||||||
|
extern rtx expand_builtin_extract_return_addr (tree);
|
||||||
|
extern void expand_builtin_init_dwarf_reg_sizes (tree);
|
||||||
|
extern rtx expand_builtin_frob_return_addr (tree);
|
||||||
|
extern rtx expand_builtin_dwarf_sp_column (void);
|
||||||
|
extern void expand_builtin_eh_return (tree, tree);
|
||||||
|
extern void expand_eh_return (void);
|
||||||
|
extern rtx expand_builtin_extend_pointer (tree);
|
||||||
|
extern void expand_dw2_landing_pad_for_region (eh_region);
|
||||||
|
|
||||||
|
typedef tree (*duplicate_eh_regions_map) (tree, void *);
|
||||||
|
extern struct pointer_map_t *duplicate_eh_regions
|
||||||
|
(struct function *, eh_region, int, duplicate_eh_regions_map, void *);
|
||||||
|
|
||||||
|
extern void sjlj_emit_function_exit_after (rtx);
|
||||||
|
|
||||||
|
extern eh_region gen_eh_region_cleanup (eh_region);
|
||||||
|
extern eh_region gen_eh_region_try (eh_region);
|
||||||
|
extern eh_region gen_eh_region_allowed (eh_region, tree);
|
||||||
|
extern eh_region gen_eh_region_must_not_throw (eh_region);
|
||||||
|
|
||||||
|
extern eh_catch gen_eh_region_catch (eh_region, tree);
|
||||||
|
extern eh_landing_pad gen_eh_landing_pad (eh_region);
|
||||||
|
|
||||||
|
extern eh_region get_eh_region_from_number_fn (struct function *, int);
|
||||||
|
extern eh_region get_eh_region_from_number (int);
|
||||||
|
extern eh_landing_pad get_eh_landing_pad_from_number_fn (struct function*,int);
|
||||||
|
extern eh_landing_pad get_eh_landing_pad_from_number (int);
|
||||||
|
extern eh_region get_eh_region_from_lp_number_fn (struct function *, int);
|
||||||
|
extern eh_region get_eh_region_from_lp_number (int);
|
||||||
|
|
||||||
|
extern eh_region eh_region_outermost (struct function *, eh_region, eh_region);
|
||||||
|
|
||||||
|
extern void make_reg_eh_region_note (rtx insn, int ecf_flags, int lp_nr);
|
||||||
|
extern void make_reg_eh_region_note_nothrow_nononlocal (rtx);
|
||||||
|
|
||||||
|
extern void verify_eh_tree (struct function *);
|
||||||
|
extern void dump_eh_tree (FILE *, struct function *);
|
||||||
|
void debug_eh_tree (struct function *);
|
||||||
|
extern void add_type_for_runtime (tree);
|
||||||
|
extern tree lookup_type_for_runtime (tree);
|
||||||
|
extern void assign_filter_values (void);
|
||||||
|
|
||||||
|
extern eh_region get_eh_region_from_rtx (const_rtx);
|
||||||
|
extern eh_landing_pad get_eh_landing_pad_from_rtx (const_rtx);
|
||||||
|
|
||||||
|
extern void finish_eh_generation (void);
|
||||||
|
|
||||||
|
struct GTY(()) throw_stmt_node {
|
||||||
|
gimple stmt;
|
||||||
|
int lp_nr;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct htab *get_eh_throw_stmt_table (struct function *);
|
||||||
|
extern void set_eh_throw_stmt_table (struct function *, struct htab *);
|
||||||
|
|
||||||
|
enum eh_personality_kind {
|
||||||
|
eh_personality_none,
|
||||||
|
eh_personality_any,
|
||||||
|
eh_personality_lang
|
||||||
|
};
|
||||||
|
|
||||||
|
extern enum eh_personality_kind
|
||||||
|
function_needs_eh_personality (struct function *);
|
||||||
|
|
||||||
|
/* Pre-order iteration within the eh_region tree. */
|
||||||
|
|
||||||
|
static inline eh_region
|
||||||
|
ehr_next (eh_region r, eh_region start)
|
||||||
|
{
|
||||||
|
if (r->inner)
|
||||||
|
r = r->inner;
|
||||||
|
else if (r->next_peer && r != start)
|
||||||
|
r = r->next_peer;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
r = r->outer;
|
||||||
|
if (r == start)
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
while (r->next_peer == NULL);
|
||||||
|
r = r->next_peer;
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define FOR_ALL_EH_REGION_AT(R, START) \
|
||||||
|
for ((R) = (START); (R) != NULL; (R) = ehr_next (R, START))
|
||||||
|
|
||||||
|
#define FOR_ALL_EH_REGION_FN(R, FN) \
|
||||||
|
for ((R) = (FN)->eh->region_tree; (R) != NULL; (R) = ehr_next (R, NULL))
|
||||||
|
|
||||||
|
#define FOR_ALL_EH_REGION(R) FOR_ALL_EH_REGION_FN (R, cfun)
|
|
@ -0,0 +1,97 @@
|
||||||
|
/* Macros for taking apart, interpreting and processing file names.
|
||||||
|
|
||||||
|
These are here because some non-Posix (a.k.a. DOSish) systems have
|
||||||
|
drive letter brain-damage at the beginning of an absolute file name,
|
||||||
|
use forward- and back-slash in path names interchangeably, and
|
||||||
|
some of them have case-insensitive file names.
|
||||||
|
|
||||||
|
Copyright 2000, 2001, 2007, 2010 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of BFD, the Binary File Descriptor library.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||||
|
|
||||||
|
#ifndef FILENAMES_H
|
||||||
|
#define FILENAMES_H
|
||||||
|
|
||||||
|
#include "hashtab.h" /* for hashval_t */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__MSDOS__) || defined(_WIN32) || defined(__OS2__) || defined (__CYGWIN__)
|
||||||
|
# ifndef HAVE_DOS_BASED_FILE_SYSTEM
|
||||||
|
# define HAVE_DOS_BASED_FILE_SYSTEM 1
|
||||||
|
# endif
|
||||||
|
# ifndef HAVE_CASE_INSENSITIVE_FILE_SYSTEM
|
||||||
|
# define HAVE_CASE_INSENSITIVE_FILE_SYSTEM 1
|
||||||
|
# endif
|
||||||
|
# define HAS_DRIVE_SPEC(f) HAS_DOS_DRIVE_SPEC (f)
|
||||||
|
# define IS_DIR_SEPARATOR(c) IS_DOS_DIR_SEPARATOR (c)
|
||||||
|
# define IS_ABSOLUTE_PATH(f) IS_DOS_ABSOLUTE_PATH (f)
|
||||||
|
#else /* not DOSish */
|
||||||
|
# if defined(__APPLE__)
|
||||||
|
# ifndef HAVE_CASE_INSENSITIVE_FILE_SYSTEM
|
||||||
|
# define HAVE_CASE_INSENSITIVE_FILE_SYSTEM 1
|
||||||
|
# endif
|
||||||
|
# endif /* __APPLE__ */
|
||||||
|
# define HAS_DRIVE_SPEC(f) (0)
|
||||||
|
# define IS_DIR_SEPARATOR(c) IS_UNIX_DIR_SEPARATOR (c)
|
||||||
|
# define IS_ABSOLUTE_PATH(f) IS_UNIX_ABSOLUTE_PATH (f)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define IS_DIR_SEPARATOR_1(dos_based, c) \
|
||||||
|
(((c) == '/') \
|
||||||
|
|| (((c) == '\\') && (dos_based)))
|
||||||
|
|
||||||
|
#define HAS_DRIVE_SPEC_1(dos_based, f) \
|
||||||
|
((f)[0] && ((f)[1] == ':') && (dos_based))
|
||||||
|
|
||||||
|
/* Remove the drive spec from F, assuming HAS_DRIVE_SPEC (f).
|
||||||
|
The result is a pointer to the remainder of F. */
|
||||||
|
#define STRIP_DRIVE_SPEC(f) ((f) + 2)
|
||||||
|
|
||||||
|
#define IS_DOS_DIR_SEPARATOR(c) IS_DIR_SEPARATOR_1 (1, c)
|
||||||
|
#define IS_DOS_ABSOLUTE_PATH(f) IS_ABSOLUTE_PATH_1 (1, f)
|
||||||
|
#define HAS_DOS_DRIVE_SPEC(f) HAS_DRIVE_SPEC_1 (1, f)
|
||||||
|
|
||||||
|
#define IS_UNIX_DIR_SEPARATOR(c) IS_DIR_SEPARATOR_1 (0, c)
|
||||||
|
#define IS_UNIX_ABSOLUTE_PATH(f) IS_ABSOLUTE_PATH_1 (0, f)
|
||||||
|
|
||||||
|
/* Note that when DOS_BASED is true, IS_ABSOLUTE_PATH accepts d:foo as
|
||||||
|
well, although it is only semi-absolute. This is because the users
|
||||||
|
of IS_ABSOLUTE_PATH want to know whether to prepend the current
|
||||||
|
working directory to a file name, which should not be done with a
|
||||||
|
name like d:foo. */
|
||||||
|
#define IS_ABSOLUTE_PATH_1(dos_based, f) \
|
||||||
|
(IS_DIR_SEPARATOR_1 (dos_based, (f)[0]) \
|
||||||
|
|| HAS_DRIVE_SPEC_1 (dos_based, f))
|
||||||
|
|
||||||
|
extern int filename_cmp (const char *s1, const char *s2);
|
||||||
|
#define FILENAME_CMP(s1, s2) filename_cmp(s1, s2)
|
||||||
|
|
||||||
|
extern int filename_ncmp (const char *s1, const char *s2,
|
||||||
|
size_t n);
|
||||||
|
|
||||||
|
extern hashval_t filename_hash (const void *s);
|
||||||
|
|
||||||
|
extern int filename_eq (const void *s1, const void *s2);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* FILENAMES_H */
|
|
@ -0,0 +1,116 @@
|
||||||
|
/* Fixed-point arithmetic support.
|
||||||
|
Copyright (C) 2006-2013 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free
|
||||||
|
Software Foundation; either version 3, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GCC; see the file COPYING3. If not see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#ifndef GCC_FIXED_VALUE_H
|
||||||
|
#define GCC_FIXED_VALUE_H
|
||||||
|
|
||||||
|
#include "machmode.h"
|
||||||
|
#include "real.h"
|
||||||
|
#include "double-int.h"
|
||||||
|
|
||||||
|
struct GTY(()) fixed_value
|
||||||
|
{
|
||||||
|
double_int data; /* Store data up to 2 wide integers. */
|
||||||
|
enum machine_mode mode; /* Use machine mode to know IBIT and FBIT. */
|
||||||
|
};
|
||||||
|
|
||||||
|
#define FIXED_VALUE_TYPE struct fixed_value
|
||||||
|
|
||||||
|
#define MAX_FCONST0 18 /* For storing 18 fixed-point zeros per
|
||||||
|
fract, ufract, accum, and uaccum modes . */
|
||||||
|
#define MAX_FCONST1 8 /* For storing 8 fixed-point ones per accum
|
||||||
|
and uaccum modes. */
|
||||||
|
/* Constant fixed-point values 0 and 1. */
|
||||||
|
extern FIXED_VALUE_TYPE fconst0[MAX_FCONST0];
|
||||||
|
extern FIXED_VALUE_TYPE fconst1[MAX_FCONST1];
|
||||||
|
|
||||||
|
/* Macros to access fconst0 and fconst1 via machine modes. */
|
||||||
|
#define FCONST0(mode) fconst0[mode - QQmode]
|
||||||
|
#define FCONST1(mode) fconst1[mode - HAmode]
|
||||||
|
|
||||||
|
/* Return a CONST_FIXED with value R and mode M. */
|
||||||
|
#define CONST_FIXED_FROM_FIXED_VALUE(r, m) \
|
||||||
|
const_fixed_from_fixed_value (r, m)
|
||||||
|
extern rtx const_fixed_from_fixed_value (FIXED_VALUE_TYPE, enum machine_mode);
|
||||||
|
|
||||||
|
/* Construct a FIXED_VALUE from a bit payload and machine mode MODE.
|
||||||
|
The bits in PAYLOAD are sign-extended/zero-extended according to MODE. */
|
||||||
|
extern FIXED_VALUE_TYPE fixed_from_double_int (double_int,
|
||||||
|
enum machine_mode);
|
||||||
|
|
||||||
|
/* Return a CONST_FIXED from a bit payload and machine mode MODE.
|
||||||
|
The bits in PAYLOAD are sign-extended/zero-extended according to MODE. */
|
||||||
|
static inline rtx
|
||||||
|
const_fixed_from_double_int (double_int payload,
|
||||||
|
enum machine_mode mode)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
const_fixed_from_fixed_value (fixed_from_double_int (payload, mode),
|
||||||
|
mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize from a decimal or hexadecimal string. */
|
||||||
|
extern void fixed_from_string (FIXED_VALUE_TYPE *, const char *,
|
||||||
|
enum machine_mode);
|
||||||
|
|
||||||
|
/* In tree.c: wrap up a FIXED_VALUE_TYPE in a tree node. */
|
||||||
|
extern tree build_fixed (tree, FIXED_VALUE_TYPE);
|
||||||
|
|
||||||
|
/* Extend or truncate to a new mode. */
|
||||||
|
extern bool fixed_convert (FIXED_VALUE_TYPE *, enum machine_mode,
|
||||||
|
const FIXED_VALUE_TYPE *, bool);
|
||||||
|
|
||||||
|
/* Convert to a fixed-point mode from an integer. */
|
||||||
|
extern bool fixed_convert_from_int (FIXED_VALUE_TYPE *, enum machine_mode,
|
||||||
|
double_int, bool, bool);
|
||||||
|
|
||||||
|
/* Convert to a fixed-point mode from a real. */
|
||||||
|
extern bool fixed_convert_from_real (FIXED_VALUE_TYPE *, enum machine_mode,
|
||||||
|
const REAL_VALUE_TYPE *, bool);
|
||||||
|
|
||||||
|
/* Convert to a real mode from a fixed-point. */
|
||||||
|
extern void real_convert_from_fixed (REAL_VALUE_TYPE *, enum machine_mode,
|
||||||
|
const FIXED_VALUE_TYPE *);
|
||||||
|
|
||||||
|
/* Compare two fixed-point objects for bitwise identity. */
|
||||||
|
extern bool fixed_identical (const FIXED_VALUE_TYPE *, const FIXED_VALUE_TYPE *);
|
||||||
|
|
||||||
|
/* Calculate a hash value. */
|
||||||
|
extern unsigned int fixed_hash (const FIXED_VALUE_TYPE *);
|
||||||
|
|
||||||
|
#define FIXED_VALUES_IDENTICAL(x, y) fixed_identical (&(x), &(y))
|
||||||
|
|
||||||
|
/* Determine whether a fixed-point value X is negative. */
|
||||||
|
#define FIXED_VALUE_NEGATIVE(x) fixed_isneg (&(x))
|
||||||
|
|
||||||
|
/* Render F as a decimal floating point constant. */
|
||||||
|
extern void fixed_to_decimal (char *str, const FIXED_VALUE_TYPE *, size_t);
|
||||||
|
|
||||||
|
/* Binary or unary arithmetic on tree_code. */
|
||||||
|
extern bool fixed_arithmetic (FIXED_VALUE_TYPE *, int, const FIXED_VALUE_TYPE *,
|
||||||
|
const FIXED_VALUE_TYPE *, bool);
|
||||||
|
|
||||||
|
/* Compare fixed-point values by tree_code. */
|
||||||
|
extern bool fixed_compare (int, const FIXED_VALUE_TYPE *,
|
||||||
|
const FIXED_VALUE_TYPE *);
|
||||||
|
|
||||||
|
/* Determine whether a fixed-point value X is negative. */
|
||||||
|
extern bool fixed_isneg (const FIXED_VALUE_TYPE *);
|
||||||
|
|
||||||
|
#endif /* GCC_FIXED_VALUE_H */
|
|
@ -0,0 +1,194 @@
|
||||||
|
/* Compilation switch flag type definitions for GCC.
|
||||||
|
Copyright (C) 1987-2013 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free
|
||||||
|
Software Foundation; either version 3, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GCC; see the file COPYING3. If not see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#ifndef GCC_FLAG_TYPES_H
|
||||||
|
#define GCC_FLAG_TYPES_H
|
||||||
|
|
||||||
|
enum debug_info_type
|
||||||
|
{
|
||||||
|
NO_DEBUG, /* Write no debug info. */
|
||||||
|
DBX_DEBUG, /* Write BSD .stabs for DBX (using dbxout.c). */
|
||||||
|
SDB_DEBUG, /* Write COFF for (old) SDB (using sdbout.c). */
|
||||||
|
DWARF2_DEBUG, /* Write Dwarf v2 debug info (using dwarf2out.c). */
|
||||||
|
XCOFF_DEBUG, /* Write IBM/Xcoff debug info (using dbxout.c). */
|
||||||
|
VMS_DEBUG, /* Write VMS debug info (using vmsdbgout.c). */
|
||||||
|
VMS_AND_DWARF2_DEBUG /* Write VMS debug info (using vmsdbgout.c).
|
||||||
|
and DWARF v2 debug info (using dwarf2out.c). */
|
||||||
|
};
|
||||||
|
|
||||||
|
enum debug_info_levels
|
||||||
|
{
|
||||||
|
DINFO_LEVEL_NONE, /* Write no debugging info. */
|
||||||
|
DINFO_LEVEL_TERSE, /* Write minimal info to support tracebacks only. */
|
||||||
|
DINFO_LEVEL_NORMAL, /* Write info for all declarations (and line table). */
|
||||||
|
DINFO_LEVEL_VERBOSE /* Write normal info plus #define/#undef info. */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* A major contribution to object and executable size is debug
|
||||||
|
information size. A major contribution to debug information
|
||||||
|
size is struct descriptions replicated in several object files.
|
||||||
|
The following function determines whether or not debug information
|
||||||
|
should be generated for a given struct. The indirect parameter
|
||||||
|
indicates that the struct is being handled indirectly, via
|
||||||
|
a pointer. See opts.c for the implementation. */
|
||||||
|
|
||||||
|
enum debug_info_usage
|
||||||
|
{
|
||||||
|
DINFO_USAGE_DFN, /* A struct definition. */
|
||||||
|
DINFO_USAGE_DIR_USE, /* A direct use, such as the type of a variable. */
|
||||||
|
DINFO_USAGE_IND_USE, /* An indirect use, such as through a pointer. */
|
||||||
|
DINFO_USAGE_NUM_ENUMS /* The number of enumerators. */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* A major contribution to object and executable size is debug
|
||||||
|
information size. A major contribution to debug information size
|
||||||
|
is struct descriptions replicated in several object files. The
|
||||||
|
following flags attempt to reduce this information. The basic
|
||||||
|
idea is to not emit struct debugging information in the current
|
||||||
|
compilation unit when that information will be generated by
|
||||||
|
another compilation unit.
|
||||||
|
|
||||||
|
Debug information for a struct defined in the current source
|
||||||
|
file should be generated in the object file. Likewise the
|
||||||
|
debug information for a struct defined in a header should be
|
||||||
|
generated in the object file of the corresponding source file.
|
||||||
|
Both of these case are handled when the base name of the file of
|
||||||
|
the struct definition matches the base name of the source file
|
||||||
|
of the current compilation unit. This matching emits minimal
|
||||||
|
struct debugging information.
|
||||||
|
|
||||||
|
The base file name matching rule above will fail to emit debug
|
||||||
|
information for structs defined in system headers. So a second
|
||||||
|
category of files includes system headers in addition to files
|
||||||
|
with matching bases.
|
||||||
|
|
||||||
|
The remaining types of files are library headers and application
|
||||||
|
headers. We cannot currently distinguish these two types. */
|
||||||
|
|
||||||
|
enum debug_struct_file
|
||||||
|
{
|
||||||
|
DINFO_STRUCT_FILE_NONE, /* Debug no structs. */
|
||||||
|
DINFO_STRUCT_FILE_BASE, /* Debug structs defined in files with the
|
||||||
|
same base name as the compilation unit. */
|
||||||
|
DINFO_STRUCT_FILE_SYS, /* Also debug structs defined in system
|
||||||
|
header files. */
|
||||||
|
DINFO_STRUCT_FILE_ANY /* Debug structs defined in all files. */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Enumerate visibility settings. This is deliberately ordered from most
|
||||||
|
to least visibility. */
|
||||||
|
#ifndef SYMBOL_VISIBILITY_DEFINED
|
||||||
|
#define SYMBOL_VISIBILITY_DEFINED
|
||||||
|
enum symbol_visibility
|
||||||
|
{
|
||||||
|
VISIBILITY_DEFAULT,
|
||||||
|
VISIBILITY_PROTECTED,
|
||||||
|
VISIBILITY_HIDDEN,
|
||||||
|
VISIBILITY_INTERNAL
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* The stack reuse level. */
|
||||||
|
enum stack_reuse_level
|
||||||
|
{
|
||||||
|
SR_NONE,
|
||||||
|
SR_NAMED_VARS,
|
||||||
|
SR_ALL
|
||||||
|
};
|
||||||
|
|
||||||
|
/* The algorithm used for the integrated register allocator (IRA). */
|
||||||
|
enum ira_algorithm
|
||||||
|
{
|
||||||
|
IRA_ALGORITHM_CB,
|
||||||
|
IRA_ALGORITHM_PRIORITY
|
||||||
|
};
|
||||||
|
|
||||||
|
/* The regions used for the integrated register allocator (IRA). */
|
||||||
|
enum ira_region
|
||||||
|
{
|
||||||
|
IRA_REGION_ONE,
|
||||||
|
IRA_REGION_ALL,
|
||||||
|
IRA_REGION_MIXED,
|
||||||
|
/* This value means that there were no options -fira-region on the
|
||||||
|
command line and that we should choose a value depending on the
|
||||||
|
used -O option. */
|
||||||
|
IRA_REGION_AUTODETECT
|
||||||
|
};
|
||||||
|
|
||||||
|
/* The options for excess precision. */
|
||||||
|
enum excess_precision
|
||||||
|
{
|
||||||
|
EXCESS_PRECISION_DEFAULT,
|
||||||
|
EXCESS_PRECISION_FAST,
|
||||||
|
EXCESS_PRECISION_STANDARD
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Type of stack check. */
|
||||||
|
enum stack_check_type
|
||||||
|
{
|
||||||
|
/* Do not check the stack. */
|
||||||
|
NO_STACK_CHECK = 0,
|
||||||
|
|
||||||
|
/* Check the stack generically, i.e. assume no specific support
|
||||||
|
from the target configuration files. */
|
||||||
|
GENERIC_STACK_CHECK,
|
||||||
|
|
||||||
|
/* Check the stack and rely on the target configuration files to
|
||||||
|
check the static frame of functions, i.e. use the generic
|
||||||
|
mechanism only for dynamic stack allocations. */
|
||||||
|
STATIC_BUILTIN_STACK_CHECK,
|
||||||
|
|
||||||
|
/* Check the stack and entirely rely on the target configuration
|
||||||
|
files, i.e. do not use the generic mechanism at all. */
|
||||||
|
FULL_BUILTIN_STACK_CHECK
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Names for the different levels of -Wstrict-overflow=N. The numeric
|
||||||
|
values here correspond to N. */
|
||||||
|
|
||||||
|
enum warn_strict_overflow_code
|
||||||
|
{
|
||||||
|
/* Overflow warning that should be issued with -Wall: a questionable
|
||||||
|
construct that is easy to avoid even when using macros. Example:
|
||||||
|
folding (x + CONSTANT > x) to 1. */
|
||||||
|
WARN_STRICT_OVERFLOW_ALL = 1,
|
||||||
|
/* Overflow warning about folding a comparison to a constant because
|
||||||
|
of undefined signed overflow, other than cases covered by
|
||||||
|
WARN_STRICT_OVERFLOW_ALL. Example: folding (abs (x) >= 0) to 1
|
||||||
|
(this is false when x == INT_MIN). */
|
||||||
|
WARN_STRICT_OVERFLOW_CONDITIONAL = 2,
|
||||||
|
/* Overflow warning about changes to comparisons other than folding
|
||||||
|
them to a constant. Example: folding (x + 1 > 1) to (x > 0). */
|
||||||
|
WARN_STRICT_OVERFLOW_COMPARISON = 3,
|
||||||
|
/* Overflow warnings not covered by the above cases. Example:
|
||||||
|
folding ((x * 10) / 5) to (x * 2). */
|
||||||
|
WARN_STRICT_OVERFLOW_MISC = 4,
|
||||||
|
/* Overflow warnings about reducing magnitude of constants in
|
||||||
|
comparison. Example: folding (x + 2 > y) to (x + 1 >= y). */
|
||||||
|
WARN_STRICT_OVERFLOW_MAGNITUDE = 5
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Floating-point contraction mode. */
|
||||||
|
enum fp_contract_mode {
|
||||||
|
FP_CONTRACT_OFF = 0,
|
||||||
|
FP_CONTRACT_ON = 1,
|
||||||
|
FP_CONTRACT_FAST = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* ! GCC_FLAG_TYPES_H */
|
|
@ -0,0 +1,101 @@
|
||||||
|
/* Compilation switch flag definitions for GCC.
|
||||||
|
Copyright (C) 1987-2013 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free
|
||||||
|
Software Foundation; either version 3, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GCC; see the file COPYING3. If not see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#ifndef GCC_FLAGS_H
|
||||||
|
#define GCC_FLAGS_H
|
||||||
|
|
||||||
|
#include "flag-types.h"
|
||||||
|
#include "options.h"
|
||||||
|
|
||||||
|
#if !defined(IN_LIBGCC2) && !defined(IN_TARGET_LIBS) && !defined(IN_RTS)
|
||||||
|
|
||||||
|
/* Names of debug_info_type, for error messages. */
|
||||||
|
extern const char *const debug_type_names[];
|
||||||
|
|
||||||
|
extern void strip_off_ending (char *, int);
|
||||||
|
extern int base_of_path (const char *path, const char **base_out);
|
||||||
|
|
||||||
|
/* Return true iff flags are set as if -ffast-math. */
|
||||||
|
extern bool fast_math_flags_set_p (const struct gcc_options *);
|
||||||
|
extern bool fast_math_flags_struct_set_p (struct cl_optimization *);
|
||||||
|
|
||||||
|
|
||||||
|
/* Now the symbols that are set with `-f' switches. */
|
||||||
|
|
||||||
|
/* True if printing into -fdump-final-insns= dump. */
|
||||||
|
|
||||||
|
extern bool final_insns_dump_p;
|
||||||
|
|
||||||
|
|
||||||
|
/* Other basic status info about current function. */
|
||||||
|
|
||||||
|
/* Target-dependent global state. */
|
||||||
|
struct target_flag_state {
|
||||||
|
/* Values of the -falign-* flags: how much to align labels in code.
|
||||||
|
0 means `use default', 1 means `don't align'.
|
||||||
|
For each variable, there is an _log variant which is the power
|
||||||
|
of two not less than the variable, for .align output. */
|
||||||
|
int x_align_loops_log;
|
||||||
|
int x_align_loops_max_skip;
|
||||||
|
int x_align_jumps_log;
|
||||||
|
int x_align_jumps_max_skip;
|
||||||
|
int x_align_labels_log;
|
||||||
|
int x_align_labels_max_skip;
|
||||||
|
int x_align_functions_log;
|
||||||
|
|
||||||
|
/* The excess precision currently in effect. */
|
||||||
|
enum excess_precision x_flag_excess_precision;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct target_flag_state default_target_flag_state;
|
||||||
|
#if SWITCHABLE_TARGET
|
||||||
|
extern struct target_flag_state *this_target_flag_state;
|
||||||
|
#else
|
||||||
|
#define this_target_flag_state (&default_target_flag_state)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define align_loops_log \
|
||||||
|
(this_target_flag_state->x_align_loops_log)
|
||||||
|
#define align_loops_max_skip \
|
||||||
|
(this_target_flag_state->x_align_loops_max_skip)
|
||||||
|
#define align_jumps_log \
|
||||||
|
(this_target_flag_state->x_align_jumps_log)
|
||||||
|
#define align_jumps_max_skip \
|
||||||
|
(this_target_flag_state->x_align_jumps_max_skip)
|
||||||
|
#define align_labels_log \
|
||||||
|
(this_target_flag_state->x_align_labels_log)
|
||||||
|
#define align_labels_max_skip \
|
||||||
|
(this_target_flag_state->x_align_labels_max_skip)
|
||||||
|
#define align_functions_log \
|
||||||
|
(this_target_flag_state->x_align_functions_log)
|
||||||
|
#define flag_excess_precision \
|
||||||
|
(this_target_flag_state->x_flag_excess_precision)
|
||||||
|
|
||||||
|
/* Returns TRUE if generated code should match ABI version N or
|
||||||
|
greater is in use. */
|
||||||
|
|
||||||
|
#define abi_version_at_least(N) \
|
||||||
|
(flag_abi_version == 0 || flag_abi_version >= (N))
|
||||||
|
|
||||||
|
/* Whether to emit an overflow warning whose code is C. */
|
||||||
|
#define issue_strict_overflow_warning(c) (warn_strict_overflow >= (int) (c))
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* ! GCC_FLAGS_H */
|
|
@ -0,0 +1,782 @@
|
||||||
|
/* Structure for saving state for a nested function.
|
||||||
|
Copyright (C) 1989-2013 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free
|
||||||
|
Software Foundation; either version 3, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GCC; see the file COPYING3. If not see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#ifndef GCC_FUNCTION_H
|
||||||
|
#define GCC_FUNCTION_H
|
||||||
|
|
||||||
|
#include "hashtab.h"
|
||||||
|
#include "vec.h"
|
||||||
|
#include "machmode.h"
|
||||||
|
#include "tm.h" /* For CUMULATIVE_ARGS. */
|
||||||
|
#include "hard-reg-set.h" /* For HARD_REG_SET in struct rtl_data. */
|
||||||
|
#include "input.h" /* For location_t. */
|
||||||
|
|
||||||
|
/* Stack of pending (incomplete) sequences saved by `start_sequence'.
|
||||||
|
Each element describes one pending sequence.
|
||||||
|
The main insn-chain is saved in the last element of the chain,
|
||||||
|
unless the chain is empty. */
|
||||||
|
|
||||||
|
struct GTY(()) sequence_stack {
|
||||||
|
/* First and last insns in the chain of the saved sequence. */
|
||||||
|
rtx first;
|
||||||
|
rtx last;
|
||||||
|
struct sequence_stack *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GTY(()) emit_status {
|
||||||
|
/* This is reset to LAST_VIRTUAL_REGISTER + 1 at the start of each function.
|
||||||
|
After rtl generation, it is 1 plus the largest register number used. */
|
||||||
|
int x_reg_rtx_no;
|
||||||
|
|
||||||
|
/* Lowest label number in current function. */
|
||||||
|
int x_first_label_num;
|
||||||
|
|
||||||
|
/* The ends of the doubly-linked chain of rtl for the current function.
|
||||||
|
Both are reset to null at the start of rtl generation for the function.
|
||||||
|
|
||||||
|
start_sequence saves both of these on `sequence_stack' and then starts
|
||||||
|
a new, nested sequence of insns. */
|
||||||
|
rtx x_first_insn;
|
||||||
|
rtx x_last_insn;
|
||||||
|
|
||||||
|
/* Stack of pending (incomplete) sequences saved by `start_sequence'.
|
||||||
|
Each element describes one pending sequence.
|
||||||
|
The main insn-chain is saved in the last element of the chain,
|
||||||
|
unless the chain is empty. */
|
||||||
|
struct sequence_stack *sequence_stack;
|
||||||
|
|
||||||
|
/* INSN_UID for next insn emitted.
|
||||||
|
Reset to 1 for each function compiled. */
|
||||||
|
int x_cur_insn_uid;
|
||||||
|
|
||||||
|
/* INSN_UID for next debug insn emitted. Only used if
|
||||||
|
--param min-nondebug-insn-uid=<value> is given with nonzero value. */
|
||||||
|
int x_cur_debug_insn_uid;
|
||||||
|
|
||||||
|
/* The length of the regno_pointer_align, regno_decl, and x_regno_reg_rtx
|
||||||
|
vectors. Since these vectors are needed during the expansion phase when
|
||||||
|
the total number of registers in the function is not yet known, the
|
||||||
|
vectors are copied and made bigger when necessary. */
|
||||||
|
int regno_pointer_align_length;
|
||||||
|
|
||||||
|
/* Indexed by pseudo register number, if nonzero gives the known alignment
|
||||||
|
for that pseudo (if REG_POINTER is set in x_regno_reg_rtx).
|
||||||
|
Allocated in parallel with x_regno_reg_rtx. */
|
||||||
|
unsigned char * GTY((skip)) regno_pointer_align;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* Indexed by register number, gives an rtx for that register (and only
|
||||||
|
that register). For pseudo registers, it is the unique rtx for
|
||||||
|
that pseudo. For hard registers, it is an rtx of the mode specified
|
||||||
|
by reg_raw_mode.
|
||||||
|
|
||||||
|
FIXME: We could put it into emit_status struct, but gengtype is not
|
||||||
|
able to deal with length attribute nested in top level structures. */
|
||||||
|
|
||||||
|
extern GTY ((length ("crtl->emit.x_reg_rtx_no"))) rtx * regno_reg_rtx;
|
||||||
|
|
||||||
|
/* For backward compatibility... eventually these should all go away. */
|
||||||
|
#define reg_rtx_no (crtl->emit.x_reg_rtx_no)
|
||||||
|
#define seq_stack (crtl->emit.sequence_stack)
|
||||||
|
|
||||||
|
#define REGNO_POINTER_ALIGN(REGNO) (crtl->emit.regno_pointer_align[REGNO])
|
||||||
|
|
||||||
|
struct GTY(()) expr_status {
|
||||||
|
/* Number of units that we should eventually pop off the stack.
|
||||||
|
These are the arguments to function calls that have already returned. */
|
||||||
|
int x_pending_stack_adjust;
|
||||||
|
|
||||||
|
/* Under some ABIs, it is the caller's responsibility to pop arguments
|
||||||
|
pushed for function calls. A naive implementation would simply pop
|
||||||
|
the arguments immediately after each call. However, if several
|
||||||
|
function calls are made in a row, it is typically cheaper to pop
|
||||||
|
all the arguments after all of the calls are complete since a
|
||||||
|
single pop instruction can be used. Therefore, GCC attempts to
|
||||||
|
defer popping the arguments until absolutely necessary. (For
|
||||||
|
example, at the end of a conditional, the arguments must be popped,
|
||||||
|
since code outside the conditional won't know whether or not the
|
||||||
|
arguments need to be popped.)
|
||||||
|
|
||||||
|
When INHIBIT_DEFER_POP is nonzero, however, the compiler does not
|
||||||
|
attempt to defer pops. Instead, the stack is popped immediately
|
||||||
|
after each call. Rather then setting this variable directly, use
|
||||||
|
NO_DEFER_POP and OK_DEFER_POP. */
|
||||||
|
int x_inhibit_defer_pop;
|
||||||
|
|
||||||
|
/* If PREFERRED_STACK_BOUNDARY and PUSH_ROUNDING are defined, the stack
|
||||||
|
boundary can be momentarily unaligned while pushing the arguments.
|
||||||
|
Record the delta since last aligned boundary here in order to get
|
||||||
|
stack alignment in the nested function calls working right. */
|
||||||
|
int x_stack_pointer_delta;
|
||||||
|
|
||||||
|
/* Nonzero means __builtin_saveregs has already been done in this function.
|
||||||
|
The value is the pseudoreg containing the value __builtin_saveregs
|
||||||
|
returned. */
|
||||||
|
rtx x_saveregs_value;
|
||||||
|
|
||||||
|
/* Similarly for __builtin_apply_args. */
|
||||||
|
rtx x_apply_args_value;
|
||||||
|
|
||||||
|
/* List of labels that must never be deleted. */
|
||||||
|
rtx x_forced_labels;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct call_site_record_d *call_site_record;
|
||||||
|
|
||||||
|
/* RTL representation of exception handling. */
|
||||||
|
struct GTY(()) rtl_eh {
|
||||||
|
rtx ehr_stackadj;
|
||||||
|
rtx ehr_handler;
|
||||||
|
rtx ehr_label;
|
||||||
|
|
||||||
|
rtx sjlj_fc;
|
||||||
|
rtx sjlj_exit_after;
|
||||||
|
|
||||||
|
vec<uchar, va_gc> *action_record_data;
|
||||||
|
|
||||||
|
vec<call_site_record, va_gc> *call_site_record_v[2];
|
||||||
|
};
|
||||||
|
|
||||||
|
#define pending_stack_adjust (crtl->expr.x_pending_stack_adjust)
|
||||||
|
#define inhibit_defer_pop (crtl->expr.x_inhibit_defer_pop)
|
||||||
|
#define saveregs_value (crtl->expr.x_saveregs_value)
|
||||||
|
#define apply_args_value (crtl->expr.x_apply_args_value)
|
||||||
|
#define forced_labels (crtl->expr.x_forced_labels)
|
||||||
|
#define stack_pointer_delta (crtl->expr.x_stack_pointer_delta)
|
||||||
|
|
||||||
|
struct gimple_df;
|
||||||
|
struct temp_slot;
|
||||||
|
typedef struct temp_slot *temp_slot_p;
|
||||||
|
struct call_site_record_d;
|
||||||
|
struct dw_fde_struct;
|
||||||
|
|
||||||
|
struct ipa_opt_pass_d;
|
||||||
|
typedef struct ipa_opt_pass_d *ipa_opt_pass;
|
||||||
|
|
||||||
|
|
||||||
|
struct GTY(()) varasm_status {
|
||||||
|
/* If we're using a per-function constant pool, this is it. */
|
||||||
|
struct rtx_constant_pool *pool;
|
||||||
|
|
||||||
|
/* Number of tree-constants deferred during the expansion of this
|
||||||
|
function. */
|
||||||
|
unsigned int deferred_constants;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Information mainlined about RTL representation of incoming arguments. */
|
||||||
|
struct GTY(()) incoming_args {
|
||||||
|
/* Number of bytes of args popped by function being compiled on its return.
|
||||||
|
Zero if no bytes are to be popped.
|
||||||
|
May affect compilation of return insn or of function epilogue. */
|
||||||
|
int pops_args;
|
||||||
|
|
||||||
|
/* If function's args have a fixed size, this is that size, in bytes.
|
||||||
|
Otherwise, it is -1.
|
||||||
|
May affect compilation of return insn or of function epilogue. */
|
||||||
|
int size;
|
||||||
|
|
||||||
|
/* # bytes the prologue should push and pretend that the caller pushed them.
|
||||||
|
The prologue must do this, but only if parms can be passed in
|
||||||
|
registers. */
|
||||||
|
int pretend_args_size;
|
||||||
|
|
||||||
|
/* This is the offset from the arg pointer to the place where the first
|
||||||
|
anonymous arg can be found, if there is one. */
|
||||||
|
rtx arg_offset_rtx;
|
||||||
|
|
||||||
|
/* Quantities of various kinds of registers
|
||||||
|
used for the current function's args. */
|
||||||
|
CUMULATIVE_ARGS info;
|
||||||
|
|
||||||
|
/* The arg pointer hard register, or the pseudo into which it was copied. */
|
||||||
|
rtx internal_arg_pointer;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Data for function partitioning. */
|
||||||
|
struct GTY(()) function_subsections {
|
||||||
|
/* Assembly labels for the hot and cold text sections, to
|
||||||
|
be used by debugger functions for determining the size of text
|
||||||
|
sections. */
|
||||||
|
|
||||||
|
const char *hot_section_label;
|
||||||
|
const char *cold_section_label;
|
||||||
|
const char *hot_section_end_label;
|
||||||
|
const char *cold_section_end_label;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Describe an empty area of space in the stack frame. These can be chained
|
||||||
|
into a list; this is used to keep track of space wasted for alignment
|
||||||
|
reasons. */
|
||||||
|
struct GTY(()) frame_space
|
||||||
|
{
|
||||||
|
struct frame_space *next;
|
||||||
|
|
||||||
|
HOST_WIDE_INT start;
|
||||||
|
HOST_WIDE_INT length;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Datastructures maintained for currently processed function in RTL form. */
|
||||||
|
struct GTY(()) rtl_data {
|
||||||
|
struct expr_status expr;
|
||||||
|
struct emit_status emit;
|
||||||
|
struct varasm_status varasm;
|
||||||
|
struct incoming_args args;
|
||||||
|
struct function_subsections subsections;
|
||||||
|
struct rtl_eh eh;
|
||||||
|
|
||||||
|
/* For function.c */
|
||||||
|
|
||||||
|
/* # of bytes of outgoing arguments. If ACCUMULATE_OUTGOING_ARGS is
|
||||||
|
defined, the needed space is pushed by the prologue. */
|
||||||
|
int outgoing_args_size;
|
||||||
|
|
||||||
|
/* If nonzero, an RTL expression for the location at which the current
|
||||||
|
function returns its result. If the current function returns its
|
||||||
|
result in a register, current_function_return_rtx will always be
|
||||||
|
the hard register containing the result. */
|
||||||
|
rtx return_rtx;
|
||||||
|
|
||||||
|
/* Vector of initial-value pairs. Each pair consists of a pseudo
|
||||||
|
register of approprite mode that stores the initial value a hard
|
||||||
|
register REGNO, and that hard register itself. */
|
||||||
|
/* ??? This could be a VEC but there is currently no way to define an
|
||||||
|
opaque VEC type. */
|
||||||
|
struct initial_value_struct *hard_reg_initial_vals;
|
||||||
|
|
||||||
|
/* A variable living at the top of the frame that holds a known value.
|
||||||
|
Used for detecting stack clobbers. */
|
||||||
|
tree stack_protect_guard;
|
||||||
|
|
||||||
|
/* List (chain of EXPR_LIST) of labels heading the current handlers for
|
||||||
|
nonlocal gotos. */
|
||||||
|
rtx x_nonlocal_goto_handler_labels;
|
||||||
|
|
||||||
|
/* Label that will go on function epilogue.
|
||||||
|
Jumping to this label serves as a "return" instruction
|
||||||
|
on machines which require execution of the epilogue on all returns. */
|
||||||
|
rtx x_return_label;
|
||||||
|
|
||||||
|
/* Label that will go on the end of function epilogue.
|
||||||
|
Jumping to this label serves as a "naked return" instruction
|
||||||
|
on machines which require execution of the epilogue on all returns. */
|
||||||
|
rtx x_naked_return_label;
|
||||||
|
|
||||||
|
/* List (chain of EXPR_LISTs) of all stack slots in this function.
|
||||||
|
Made for the sake of unshare_all_rtl. */
|
||||||
|
rtx x_stack_slot_list;
|
||||||
|
|
||||||
|
/* List of empty areas in the stack frame. */
|
||||||
|
struct frame_space *frame_space_list;
|
||||||
|
|
||||||
|
/* Place after which to insert the tail_recursion_label if we need one. */
|
||||||
|
rtx x_stack_check_probe_note;
|
||||||
|
|
||||||
|
/* Location at which to save the argument pointer if it will need to be
|
||||||
|
referenced. There are two cases where this is done: if nonlocal gotos
|
||||||
|
exist, or if vars stored at an offset from the argument pointer will be
|
||||||
|
needed by inner routines. */
|
||||||
|
rtx x_arg_pointer_save_area;
|
||||||
|
|
||||||
|
/* Dynamic Realign Argument Pointer used for realigning stack. */
|
||||||
|
rtx drap_reg;
|
||||||
|
|
||||||
|
/* Offset to end of allocated area of stack frame.
|
||||||
|
If stack grows down, this is the address of the last stack slot allocated.
|
||||||
|
If stack grows up, this is the address for the next slot. */
|
||||||
|
HOST_WIDE_INT x_frame_offset;
|
||||||
|
|
||||||
|
/* Insn after which register parms and SAVE_EXPRs are born, if nonopt. */
|
||||||
|
rtx x_parm_birth_insn;
|
||||||
|
|
||||||
|
/* List of all used temporaries allocated, by level. */
|
||||||
|
vec<temp_slot_p, va_gc> *x_used_temp_slots;
|
||||||
|
|
||||||
|
/* List of available temp slots. */
|
||||||
|
struct temp_slot *x_avail_temp_slots;
|
||||||
|
|
||||||
|
/* Current nesting level for temporaries. */
|
||||||
|
int x_temp_slot_level;
|
||||||
|
|
||||||
|
/* The largest alignment needed on the stack, including requirement
|
||||||
|
for outgoing stack alignment. */
|
||||||
|
unsigned int stack_alignment_needed;
|
||||||
|
|
||||||
|
/* Preferred alignment of the end of stack frame, which is preferred
|
||||||
|
to call other functions. */
|
||||||
|
unsigned int preferred_stack_boundary;
|
||||||
|
|
||||||
|
/* The minimum alignment of parameter stack. */
|
||||||
|
unsigned int parm_stack_boundary;
|
||||||
|
|
||||||
|
/* The largest alignment of slot allocated on the stack. */
|
||||||
|
unsigned int max_used_stack_slot_alignment;
|
||||||
|
|
||||||
|
/* The stack alignment estimated before reload, with consideration of
|
||||||
|
following factors:
|
||||||
|
1. Alignment of local stack variables (max_used_stack_slot_alignment)
|
||||||
|
2. Alignment requirement to call other functions
|
||||||
|
(preferred_stack_boundary)
|
||||||
|
3. Alignment of non-local stack variables but might be spilled in
|
||||||
|
local stack. */
|
||||||
|
unsigned int stack_alignment_estimated;
|
||||||
|
|
||||||
|
/* For reorg. */
|
||||||
|
|
||||||
|
/* Nonzero if function being compiled called builtin_return_addr or
|
||||||
|
builtin_frame_address with nonzero count. */
|
||||||
|
bool accesses_prior_frames;
|
||||||
|
|
||||||
|
/* Nonzero if the function calls __builtin_eh_return. */
|
||||||
|
bool calls_eh_return;
|
||||||
|
|
||||||
|
/* Nonzero if function saves all registers, e.g. if it has a nonlocal
|
||||||
|
label that can reach the exit block via non-exceptional paths. */
|
||||||
|
bool saves_all_registers;
|
||||||
|
|
||||||
|
/* Nonzero if function being compiled has nonlocal gotos to parent
|
||||||
|
function. */
|
||||||
|
bool has_nonlocal_goto;
|
||||||
|
|
||||||
|
/* Nonzero if function being compiled has an asm statement. */
|
||||||
|
bool has_asm_statement;
|
||||||
|
|
||||||
|
/* This bit is used by the exception handling logic. It is set if all
|
||||||
|
calls (if any) are sibling calls. Such functions do not have to
|
||||||
|
have EH tables generated, as they cannot throw. A call to such a
|
||||||
|
function, however, should be treated as throwing if any of its callees
|
||||||
|
can throw. */
|
||||||
|
bool all_throwers_are_sibcalls;
|
||||||
|
|
||||||
|
/* Nonzero if stack limit checking should be enabled in the current
|
||||||
|
function. */
|
||||||
|
bool limit_stack;
|
||||||
|
|
||||||
|
/* Nonzero if profiling code should be generated. */
|
||||||
|
bool profile;
|
||||||
|
|
||||||
|
/* Nonzero if the current function uses the constant pool. */
|
||||||
|
bool uses_const_pool;
|
||||||
|
|
||||||
|
/* Nonzero if the current function uses pic_offset_table_rtx. */
|
||||||
|
bool uses_pic_offset_table;
|
||||||
|
|
||||||
|
/* Nonzero if the current function needs an lsda for exception handling. */
|
||||||
|
bool uses_eh_lsda;
|
||||||
|
|
||||||
|
/* Set when the tail call has been produced. */
|
||||||
|
bool tail_call_emit;
|
||||||
|
|
||||||
|
/* Nonzero if code to initialize arg_pointer_save_area has been emitted. */
|
||||||
|
bool arg_pointer_save_area_init;
|
||||||
|
|
||||||
|
/* Nonzero if current function must be given a frame pointer.
|
||||||
|
Set in reload1.c or lra-eliminations.c if anything is allocated
|
||||||
|
on the stack there. */
|
||||||
|
bool frame_pointer_needed;
|
||||||
|
|
||||||
|
/* When set, expand should optimize for speed. */
|
||||||
|
bool maybe_hot_insn_p;
|
||||||
|
|
||||||
|
/* Nonzero if function stack realignment is needed. This flag may be
|
||||||
|
set twice: before and after reload. It is set before reload wrt
|
||||||
|
stack alignment estimation before reload. It will be changed after
|
||||||
|
reload if by then criteria of stack realignment is different.
|
||||||
|
The value set after reload is the accurate one and is finalized. */
|
||||||
|
bool stack_realign_needed;
|
||||||
|
|
||||||
|
/* Nonzero if function stack realignment is tried. This flag is set
|
||||||
|
only once before reload. It affects register elimination. This
|
||||||
|
is used to generate DWARF debug info for stack variables. */
|
||||||
|
bool stack_realign_tried;
|
||||||
|
|
||||||
|
/* Nonzero if function being compiled needs dynamic realigned
|
||||||
|
argument pointer (drap) if stack needs realigning. */
|
||||||
|
bool need_drap;
|
||||||
|
|
||||||
|
/* Nonzero if function stack realignment estimation is done, namely
|
||||||
|
stack_realign_needed flag has been set before reload wrt estimated
|
||||||
|
stack alignment info. */
|
||||||
|
bool stack_realign_processed;
|
||||||
|
|
||||||
|
/* Nonzero if function stack realignment has been finalized, namely
|
||||||
|
stack_realign_needed flag has been set and finalized after reload. */
|
||||||
|
bool stack_realign_finalized;
|
||||||
|
|
||||||
|
/* True if dbr_schedule has already been called for this function. */
|
||||||
|
bool dbr_scheduled_p;
|
||||||
|
|
||||||
|
/* True if current function can not throw. Unlike
|
||||||
|
TREE_NOTHROW (current_function_decl) it is set even for overwritable
|
||||||
|
function where currently compiled version of it is nothrow. */
|
||||||
|
bool nothrow;
|
||||||
|
|
||||||
|
/* True if we performed shrink-wrapping for the current function. */
|
||||||
|
bool shrink_wrapped;
|
||||||
|
|
||||||
|
/* Nonzero if function being compiled doesn't modify the stack pointer
|
||||||
|
(ignoring the prologue and epilogue). This is only valid after
|
||||||
|
pass_stack_ptr_mod has run. */
|
||||||
|
bool sp_is_unchanging;
|
||||||
|
|
||||||
|
/* Nonzero if function being compiled doesn't contain any calls
|
||||||
|
(ignoring the prologue and epilogue). This is set prior to
|
||||||
|
local register allocation and is valid for the remaining
|
||||||
|
compiler passes. */
|
||||||
|
bool is_leaf;
|
||||||
|
|
||||||
|
/* Nonzero if the function being compiled is a leaf function which only
|
||||||
|
uses leaf registers. This is valid after reload (specifically after
|
||||||
|
sched2) and is useful only if the port defines LEAF_REGISTERS. */
|
||||||
|
bool uses_only_leaf_regs;
|
||||||
|
|
||||||
|
/* Like regs_ever_live, but 1 if a reg is set or clobbered from an
|
||||||
|
asm. Unlike regs_ever_live, elements of this array corresponding
|
||||||
|
to eliminable regs (like the frame pointer) are set if an asm
|
||||||
|
sets them. */
|
||||||
|
HARD_REG_SET asm_clobbers;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define return_label (crtl->x_return_label)
|
||||||
|
#define naked_return_label (crtl->x_naked_return_label)
|
||||||
|
#define stack_slot_list (crtl->x_stack_slot_list)
|
||||||
|
#define parm_birth_insn (crtl->x_parm_birth_insn)
|
||||||
|
#define frame_offset (crtl->x_frame_offset)
|
||||||
|
#define stack_check_probe_note (crtl->x_stack_check_probe_note)
|
||||||
|
#define arg_pointer_save_area (crtl->x_arg_pointer_save_area)
|
||||||
|
#define used_temp_slots (crtl->x_used_temp_slots)
|
||||||
|
#define avail_temp_slots (crtl->x_avail_temp_slots)
|
||||||
|
#define temp_slot_level (crtl->x_temp_slot_level)
|
||||||
|
#define nonlocal_goto_handler_labels (crtl->x_nonlocal_goto_handler_labels)
|
||||||
|
#define frame_pointer_needed (crtl->frame_pointer_needed)
|
||||||
|
#define stack_realign_fp (crtl->stack_realign_needed && !crtl->need_drap)
|
||||||
|
#define stack_realign_drap (crtl->stack_realign_needed && crtl->need_drap)
|
||||||
|
|
||||||
|
extern GTY(()) struct rtl_data x_rtl;
|
||||||
|
|
||||||
|
/* Accessor to RTL datastructures. We keep them statically allocated now since
|
||||||
|
we never keep multiple functions. For threaded compiler we might however
|
||||||
|
want to do differently. */
|
||||||
|
#define crtl (&x_rtl)
|
||||||
|
|
||||||
|
struct GTY(()) stack_usage
|
||||||
|
{
|
||||||
|
/* # of bytes of static stack space allocated by the function. */
|
||||||
|
HOST_WIDE_INT static_stack_size;
|
||||||
|
|
||||||
|
/* # of bytes of dynamic stack space allocated by the function. This is
|
||||||
|
meaningful only if has_unbounded_dynamic_stack_size is zero. */
|
||||||
|
HOST_WIDE_INT dynamic_stack_size;
|
||||||
|
|
||||||
|
/* # of bytes of space pushed onto the stack after the prologue. If
|
||||||
|
!ACCUMULATE_OUTGOING_ARGS, it contains the outgoing arguments. */
|
||||||
|
int pushed_stack_size;
|
||||||
|
|
||||||
|
/* Nonzero if the amount of stack space allocated dynamically cannot
|
||||||
|
be bounded at compile-time. */
|
||||||
|
unsigned int has_unbounded_dynamic_stack_size : 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define current_function_static_stack_size (cfun->su->static_stack_size)
|
||||||
|
#define current_function_dynamic_stack_size (cfun->su->dynamic_stack_size)
|
||||||
|
#define current_function_pushed_stack_size (cfun->su->pushed_stack_size)
|
||||||
|
#define current_function_has_unbounded_dynamic_stack_size \
|
||||||
|
(cfun->su->has_unbounded_dynamic_stack_size)
|
||||||
|
#define current_function_allocates_dynamic_stack_space \
|
||||||
|
(current_function_dynamic_stack_size != 0 \
|
||||||
|
|| current_function_has_unbounded_dynamic_stack_size)
|
||||||
|
|
||||||
|
/* This structure can save all the important global and static variables
|
||||||
|
describing the status of the current function. */
|
||||||
|
|
||||||
|
struct GTY(()) function {
|
||||||
|
struct eh_status *eh;
|
||||||
|
|
||||||
|
/* The control flow graph for this function. */
|
||||||
|
struct control_flow_graph *cfg;
|
||||||
|
|
||||||
|
/* GIMPLE body for this function. */
|
||||||
|
gimple_seq gimple_body;
|
||||||
|
|
||||||
|
/* SSA and dataflow information. */
|
||||||
|
struct gimple_df *gimple_df;
|
||||||
|
|
||||||
|
/* The loops in this function. */
|
||||||
|
struct loops *x_current_loops;
|
||||||
|
|
||||||
|
/* The stack usage of this function. */
|
||||||
|
struct stack_usage *su;
|
||||||
|
|
||||||
|
/* Value histograms attached to particular statements. */
|
||||||
|
htab_t GTY((skip)) value_histograms;
|
||||||
|
|
||||||
|
/* For function.c. */
|
||||||
|
|
||||||
|
/* Points to the FUNCTION_DECL of this function. */
|
||||||
|
tree decl;
|
||||||
|
|
||||||
|
/* A PARM_DECL that should contain the static chain for this function.
|
||||||
|
It will be initialized at the beginning of the function. */
|
||||||
|
tree static_chain_decl;
|
||||||
|
|
||||||
|
/* An expression that contains the non-local goto save area. The first
|
||||||
|
word is the saved frame pointer and the second is the saved stack
|
||||||
|
pointer. */
|
||||||
|
tree nonlocal_goto_save_area;
|
||||||
|
|
||||||
|
/* Vector of function local variables, functions, types and constants. */
|
||||||
|
vec<tree, va_gc> *local_decls;
|
||||||
|
|
||||||
|
/* For md files. */
|
||||||
|
|
||||||
|
/* tm.h can use this to store whatever it likes. */
|
||||||
|
struct machine_function * GTY ((maybe_undef)) machine;
|
||||||
|
|
||||||
|
/* Language-specific code can use this to store whatever it likes. */
|
||||||
|
struct language_function * language;
|
||||||
|
|
||||||
|
/* Used types hash table. */
|
||||||
|
htab_t GTY ((param_is (union tree_node))) used_types_hash;
|
||||||
|
|
||||||
|
/* Dwarf2 Frame Description Entry, containing the Call Frame Instructions
|
||||||
|
used for unwinding. Only set when either dwarf2 unwinding or dwarf2
|
||||||
|
debugging is enabled. */
|
||||||
|
struct dw_fde_struct *fde;
|
||||||
|
|
||||||
|
/* Last statement uid. */
|
||||||
|
int last_stmt_uid;
|
||||||
|
|
||||||
|
/* Function sequence number for profiling, debugging, etc. */
|
||||||
|
int funcdef_no;
|
||||||
|
|
||||||
|
/* Line number of the start of the function for debugging purposes. */
|
||||||
|
location_t function_start_locus;
|
||||||
|
|
||||||
|
/* Line number of the end of the function. */
|
||||||
|
location_t function_end_locus;
|
||||||
|
|
||||||
|
/* Properties used by the pass manager. */
|
||||||
|
unsigned int curr_properties;
|
||||||
|
unsigned int last_verified;
|
||||||
|
|
||||||
|
/* Non-null if the function does something that would prevent it from
|
||||||
|
being copied; this applies to both versioning and inlining. Set to
|
||||||
|
a string describing the reason for failure. */
|
||||||
|
const char * GTY((skip)) cannot_be_copied_reason;
|
||||||
|
|
||||||
|
/* Collected bit flags. */
|
||||||
|
|
||||||
|
/* Number of units of general registers that need saving in stdarg
|
||||||
|
function. What unit is depends on the backend, either it is number
|
||||||
|
of bytes, or it can be number of registers. */
|
||||||
|
unsigned int va_list_gpr_size : 8;
|
||||||
|
|
||||||
|
/* Number of units of floating point registers that need saving in stdarg
|
||||||
|
function. */
|
||||||
|
unsigned int va_list_fpr_size : 8;
|
||||||
|
|
||||||
|
/* Nonzero if function being compiled can call setjmp. */
|
||||||
|
unsigned int calls_setjmp : 1;
|
||||||
|
|
||||||
|
/* Nonzero if function being compiled can call alloca,
|
||||||
|
either as a subroutine or builtin. */
|
||||||
|
unsigned int calls_alloca : 1;
|
||||||
|
|
||||||
|
/* Nonzero if function being compiled receives nonlocal gotos
|
||||||
|
from nested functions. */
|
||||||
|
unsigned int has_nonlocal_label : 1;
|
||||||
|
|
||||||
|
/* Nonzero if we've set cannot_be_copied_reason. I.e. if
|
||||||
|
(cannot_be_copied_set && !cannot_be_copied_reason), the function
|
||||||
|
can in fact be copied. */
|
||||||
|
unsigned int cannot_be_copied_set : 1;
|
||||||
|
|
||||||
|
/* Nonzero if current function uses stdarg.h or equivalent. */
|
||||||
|
unsigned int stdarg : 1;
|
||||||
|
|
||||||
|
unsigned int after_inlining : 1;
|
||||||
|
unsigned int always_inline_functions_inlined : 1;
|
||||||
|
|
||||||
|
/* Nonzero if function being compiled can throw synchronous non-call
|
||||||
|
exceptions. */
|
||||||
|
unsigned int can_throw_non_call_exceptions : 1;
|
||||||
|
|
||||||
|
/* Nonzero if instructions that may throw exceptions but don't otherwise
|
||||||
|
contribute to the execution of the program can be deleted. */
|
||||||
|
unsigned int can_delete_dead_exceptions : 1;
|
||||||
|
|
||||||
|
/* Fields below this point are not set for abstract functions; see
|
||||||
|
allocate_struct_function. */
|
||||||
|
|
||||||
|
/* Nonzero if function being compiled needs to be given an address
|
||||||
|
where the value should be stored. */
|
||||||
|
unsigned int returns_struct : 1;
|
||||||
|
|
||||||
|
/* Nonzero if function being compiled needs to
|
||||||
|
return the address of where it has put a structure value. */
|
||||||
|
unsigned int returns_pcc_struct : 1;
|
||||||
|
|
||||||
|
/* Nonzero if this function has local DECL_HARD_REGISTER variables.
|
||||||
|
In this case code motion has to be done more carefully. */
|
||||||
|
unsigned int has_local_explicit_reg_vars : 1;
|
||||||
|
|
||||||
|
/* Nonzero if the current function is a thunk, i.e., a lightweight
|
||||||
|
function implemented by the output_mi_thunk hook) that just
|
||||||
|
adjusts one of its arguments and forwards to another
|
||||||
|
function. */
|
||||||
|
unsigned int is_thunk : 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Add the decl D to the local_decls list of FUN. */
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
add_local_decl (struct function *fun, tree d)
|
||||||
|
{
|
||||||
|
vec_safe_push (fun->local_decls, d);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define FOR_EACH_LOCAL_DECL(FUN, I, D) \
|
||||||
|
FOR_EACH_VEC_SAFE_ELT_REVERSE ((FUN)->local_decls, I, D)
|
||||||
|
|
||||||
|
/* If va_list_[gf]pr_size is set to this, it means we don't know how
|
||||||
|
many units need to be saved. */
|
||||||
|
#define VA_LIST_MAX_GPR_SIZE 255
|
||||||
|
#define VA_LIST_MAX_FPR_SIZE 255
|
||||||
|
|
||||||
|
/* The function currently being compiled. */
|
||||||
|
extern GTY(()) struct function *cfun;
|
||||||
|
|
||||||
|
/* In order to ensure that cfun is not set directly, we redefine it so
|
||||||
|
that it is not an lvalue. Rather than assign to cfun, use
|
||||||
|
push_cfun or set_cfun. */
|
||||||
|
#define cfun (cfun + 0)
|
||||||
|
|
||||||
|
/* Nonzero if we've already converted virtual regs to hard regs. */
|
||||||
|
extern int virtuals_instantiated;
|
||||||
|
|
||||||
|
/* Nonzero if at least one trampoline has been created. */
|
||||||
|
extern int trampolines_created;
|
||||||
|
|
||||||
|
struct GTY(()) types_used_by_vars_entry {
|
||||||
|
tree type;
|
||||||
|
tree var_decl;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Hash table making the relationship between a global variable
|
||||||
|
and the types it references in its initializer. The key of the
|
||||||
|
entry is a referenced type, and the value is the DECL of the global
|
||||||
|
variable. types_use_by_vars_do_hash and types_used_by_vars_eq below are
|
||||||
|
the hash and equality functions to use for this hash table. */
|
||||||
|
extern GTY((param_is (struct types_used_by_vars_entry))) htab_t
|
||||||
|
types_used_by_vars_hash;
|
||||||
|
|
||||||
|
hashval_t types_used_by_vars_do_hash (const void*);
|
||||||
|
int types_used_by_vars_eq (const void *, const void *);
|
||||||
|
void types_used_by_var_decl_insert (tree type, tree var_decl);
|
||||||
|
|
||||||
|
/* During parsing of a global variable, this vector contains the types
|
||||||
|
referenced by the global variable. */
|
||||||
|
extern GTY(()) vec<tree, va_gc> *types_used_by_cur_var_decl;
|
||||||
|
|
||||||
|
/* cfun shouldn't be set directly; use one of these functions instead. */
|
||||||
|
extern void set_cfun (struct function *new_cfun);
|
||||||
|
extern void push_cfun (struct function *new_cfun);
|
||||||
|
extern void pop_cfun (void);
|
||||||
|
extern void instantiate_decl_rtl (rtx x);
|
||||||
|
|
||||||
|
/* For backward compatibility... eventually these should all go away. */
|
||||||
|
#define current_function_funcdef_no (cfun->funcdef_no)
|
||||||
|
|
||||||
|
#define current_loops (cfun->x_current_loops)
|
||||||
|
#define dom_computed (cfun->cfg->x_dom_computed)
|
||||||
|
#define n_bbs_in_dom_tree (cfun->cfg->x_n_bbs_in_dom_tree)
|
||||||
|
#define VALUE_HISTOGRAMS(fun) (fun)->value_histograms
|
||||||
|
|
||||||
|
/* Identify BLOCKs referenced by more than one NOTE_INSN_BLOCK_{BEG,END},
|
||||||
|
and create duplicate blocks. */
|
||||||
|
extern void reorder_blocks (void);
|
||||||
|
|
||||||
|
/* Set BLOCK_NUMBER for all the blocks in FN. */
|
||||||
|
extern void number_blocks (tree);
|
||||||
|
|
||||||
|
extern void clear_block_marks (tree);
|
||||||
|
extern tree blocks_nreverse (tree);
|
||||||
|
extern tree block_chainon (tree, tree);
|
||||||
|
|
||||||
|
/* Return size needed for stack frame based on slots so far allocated.
|
||||||
|
This size counts from zero. It is not rounded to STACK_BOUNDARY;
|
||||||
|
the caller may have to do that. */
|
||||||
|
extern HOST_WIDE_INT get_frame_size (void);
|
||||||
|
|
||||||
|
/* Issue an error message and return TRUE if frame OFFSET overflows in
|
||||||
|
the signed target pointer arithmetics for function FUNC. Otherwise
|
||||||
|
return FALSE. */
|
||||||
|
extern bool frame_offset_overflow (HOST_WIDE_INT, tree);
|
||||||
|
|
||||||
|
/* A pointer to a function to create target specific, per-function
|
||||||
|
data structures. */
|
||||||
|
extern struct machine_function * (*init_machine_status) (void);
|
||||||
|
|
||||||
|
/* Save and restore status information for a nested function. */
|
||||||
|
extern void free_after_parsing (struct function *);
|
||||||
|
extern void free_after_compilation (struct function *);
|
||||||
|
|
||||||
|
extern void init_varasm_status (void);
|
||||||
|
|
||||||
|
#ifdef RTX_CODE
|
||||||
|
extern void diddle_return_value (void (*)(rtx, void*), void*);
|
||||||
|
extern void clobber_return_register (void);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern rtx get_arg_pointer_save_area (void);
|
||||||
|
|
||||||
|
/* Returns the name of the current function. */
|
||||||
|
extern const char *fndecl_name (tree);
|
||||||
|
extern const char *function_name (struct function *);
|
||||||
|
extern const char *current_function_name (void);
|
||||||
|
|
||||||
|
extern void do_warn_unused_parameter (tree);
|
||||||
|
|
||||||
|
extern bool pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
|
||||||
|
tree, bool);
|
||||||
|
extern bool reference_callee_copied (CUMULATIVE_ARGS *, enum machine_mode,
|
||||||
|
tree, bool);
|
||||||
|
|
||||||
|
extern void used_types_insert (tree);
|
||||||
|
|
||||||
|
extern int get_next_funcdef_no (void);
|
||||||
|
extern int get_last_funcdef_no (void);
|
||||||
|
|
||||||
|
#ifdef HAVE_simple_return
|
||||||
|
extern bool requires_stack_frame_p (rtx, HARD_REG_SET, HARD_REG_SET);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern rtx get_hard_reg_initial_val (enum machine_mode, unsigned int);
|
||||||
|
extern rtx has_hard_reg_initial_val (enum machine_mode, unsigned int);
|
||||||
|
extern rtx get_hard_reg_initial_reg (rtx);
|
||||||
|
extern bool initial_value_entry (int i, rtx *, rtx *);
|
||||||
|
|
||||||
|
/* Called from gimple_expand_cfg. */
|
||||||
|
extern unsigned int emit_initial_value_sets (void);
|
||||||
|
|
||||||
|
/* In predict.c */
|
||||||
|
extern bool optimize_function_for_size_p (struct function *);
|
||||||
|
extern bool optimize_function_for_speed_p (struct function *);
|
||||||
|
|
||||||
|
#endif /* GCC_FUNCTION_H */
|
|
@ -0,0 +1,166 @@
|
||||||
|
/* Public header file for plugins to include.
|
||||||
|
Copyright (C) 2009-2013 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GCC; see the file COPYING3. If not see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#ifndef GCC_PLUGIN_H
|
||||||
|
#define GCC_PLUGIN_H
|
||||||
|
|
||||||
|
#ifndef IN_GCC
|
||||||
|
#define IN_GCC
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
#include "system.h"
|
||||||
|
#include "coretypes.h"
|
||||||
|
#include "highlev-plugin-common.h"
|
||||||
|
#include "hashtab.h"
|
||||||
|
|
||||||
|
/* Event names. */
|
||||||
|
enum plugin_event
|
||||||
|
{
|
||||||
|
# define DEFEVENT(NAME) NAME,
|
||||||
|
# include "plugin.def"
|
||||||
|
# undef DEFEVENT
|
||||||
|
PLUGIN_EVENT_FIRST_DYNAMIC
|
||||||
|
};
|
||||||
|
|
||||||
|
/* All globals declared here have C linkage to reduce link compatibility
|
||||||
|
issues with implementation language choice and mangling. */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern const char **plugin_event_name;
|
||||||
|
|
||||||
|
struct plugin_argument
|
||||||
|
{
|
||||||
|
char *key; /* key of the argument. */
|
||||||
|
char *value; /* value is optional and can be NULL. */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Additional information about the plugin. Used by --help and --version. */
|
||||||
|
|
||||||
|
struct plugin_info
|
||||||
|
{
|
||||||
|
const char *version;
|
||||||
|
const char *help;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Represents the gcc version. Used to avoid using an incompatible plugin. */
|
||||||
|
|
||||||
|
struct plugin_gcc_version
|
||||||
|
{
|
||||||
|
const char *basever;
|
||||||
|
const char *datestamp;
|
||||||
|
const char *devphase;
|
||||||
|
const char *revision;
|
||||||
|
const char *configuration_arguments;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Object that keeps track of the plugin name and its arguments. */
|
||||||
|
struct plugin_name_args
|
||||||
|
{
|
||||||
|
char *base_name; /* Short name of the plugin (filename without
|
||||||
|
.so suffix). */
|
||||||
|
const char *full_name; /* Path to the plugin as specified with
|
||||||
|
-fplugin=. */
|
||||||
|
int argc; /* Number of arguments specified with
|
||||||
|
-fplugin-arg-... */
|
||||||
|
struct plugin_argument *argv; /* Array of ARGC key-value pairs. */
|
||||||
|
const char *version; /* Version string provided by plugin. */
|
||||||
|
const char *help; /* Help string provided by plugin. */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* The default version check. Compares every field in VERSION. */
|
||||||
|
|
||||||
|
extern bool plugin_default_version_check (struct plugin_gcc_version *,
|
||||||
|
struct plugin_gcc_version *);
|
||||||
|
|
||||||
|
/* Function type for the plugin initialization routine. Each plugin module
|
||||||
|
should define this as an externally-visible function with name
|
||||||
|
"plugin_init."
|
||||||
|
|
||||||
|
PLUGIN_INFO - plugin invocation information.
|
||||||
|
VERSION - the plugin_gcc_version symbol of GCC.
|
||||||
|
|
||||||
|
Returns 0 if initialization finishes successfully. */
|
||||||
|
|
||||||
|
typedef int (*plugin_init_func) (struct plugin_name_args *plugin_info,
|
||||||
|
struct plugin_gcc_version *version);
|
||||||
|
|
||||||
|
/* Declaration for "plugin_init" function so that it doesn't need to be
|
||||||
|
duplicated in every plugin. */
|
||||||
|
extern int plugin_init (struct plugin_name_args *plugin_info,
|
||||||
|
struct plugin_gcc_version *version);
|
||||||
|
|
||||||
|
/* Function type for a plugin callback routine.
|
||||||
|
|
||||||
|
GCC_DATA - event-specific data provided by GCC
|
||||||
|
USER_DATA - plugin-specific data provided by the plugin */
|
||||||
|
|
||||||
|
typedef void (*plugin_callback_func) (void *gcc_data, void *user_data);
|
||||||
|
|
||||||
|
/* Called from the plugin's initialization code. Register a single callback.
|
||||||
|
This function can be called multiple times.
|
||||||
|
|
||||||
|
PLUGIN_NAME - display name for this plugin
|
||||||
|
EVENT - which event the callback is for
|
||||||
|
CALLBACK - the callback to be called at the event
|
||||||
|
USER_DATA - plugin-provided data.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Number of event ids / names registered so far. */
|
||||||
|
|
||||||
|
extern int get_event_last (void);
|
||||||
|
|
||||||
|
int get_named_event_id (const char *name, enum insert_option insert);
|
||||||
|
|
||||||
|
/* This is also called without a callback routine for the
|
||||||
|
PLUGIN_PASS_MANAGER_SETUP, PLUGIN_INFO, PLUGIN_REGISTER_GGC_ROOTS and
|
||||||
|
PLUGIN_REGISTER_GGC_CACHES pseudo-events, with a specific user_data.
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern void register_callback (const char *plugin_name,
|
||||||
|
int event,
|
||||||
|
plugin_callback_func callback,
|
||||||
|
void *user_data);
|
||||||
|
|
||||||
|
extern int unregister_callback (const char *plugin_name, int event);
|
||||||
|
|
||||||
|
|
||||||
|
/* Retrieve the plugin directory name, as returned by the
|
||||||
|
-fprint-file-name=plugin argument to the gcc program, which is the
|
||||||
|
-iplugindir program argument to cc1. */
|
||||||
|
extern const char* default_plugin_dir_name (void);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* In case the C++ compiler does name mangling for globals, declare
|
||||||
|
plugin_is_GPL_compatible extern "C" so that a later definition
|
||||||
|
in a plugin file will have this linkage. */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
extern int plugin_is_GPL_compatible;
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* GCC_PLUGIN_H */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,279 @@
|
||||||
|
/* Garbage collection for the GNU compiler.
|
||||||
|
|
||||||
|
Copyright (C) 1998-2013 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free
|
||||||
|
Software Foundation; either version 3, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GCC; see the file COPYING3. If not see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#ifndef GCC_GGC_H
|
||||||
|
#define GCC_GGC_H
|
||||||
|
#include "statistics.h"
|
||||||
|
|
||||||
|
/* Symbols are marked with `ggc' for `gcc gc' so as not to interfere with
|
||||||
|
an external gc library that might be linked in. */
|
||||||
|
|
||||||
|
/* Constants for general use. */
|
||||||
|
extern const char empty_string[]; /* empty string */
|
||||||
|
|
||||||
|
/* Internal functions and data structures used by the GTY
|
||||||
|
machinery, including the generated gt*.[hc] files. */
|
||||||
|
|
||||||
|
#include "gtype-desc.h"
|
||||||
|
|
||||||
|
/* One of these applies its third parameter (with cookie in the fourth
|
||||||
|
parameter) to each pointer in the object pointed to by the first
|
||||||
|
parameter, using the second parameter. */
|
||||||
|
typedef void (*gt_note_pointers) (void *, void *, gt_pointer_operator,
|
||||||
|
void *);
|
||||||
|
|
||||||
|
/* One of these is called before objects are re-ordered in memory.
|
||||||
|
The first parameter is the original object, the second is the
|
||||||
|
subobject that has had its pointers reordered, the third parameter
|
||||||
|
can compute the new values of a pointer when given the cookie in
|
||||||
|
the fourth parameter. */
|
||||||
|
typedef void (*gt_handle_reorder) (void *, void *, gt_pointer_operator,
|
||||||
|
void *);
|
||||||
|
|
||||||
|
/* Used by the gt_pch_n_* routines. Register an object in the hash table. */
|
||||||
|
extern int gt_pch_note_object (void *, void *, gt_note_pointers);
|
||||||
|
|
||||||
|
/* Used by the gt_pch_n_* routines. Register that an object has a reorder
|
||||||
|
function. */
|
||||||
|
extern void gt_pch_note_reorder (void *, void *, gt_handle_reorder);
|
||||||
|
|
||||||
|
/* Mark the object in the first parameter and anything it points to. */
|
||||||
|
typedef void (*gt_pointer_walker) (void *);
|
||||||
|
|
||||||
|
/* Structures for the easy way to mark roots.
|
||||||
|
In an array, terminated by having base == NULL. */
|
||||||
|
struct ggc_root_tab {
|
||||||
|
void *base;
|
||||||
|
size_t nelt;
|
||||||
|
size_t stride;
|
||||||
|
gt_pointer_walker cb;
|
||||||
|
gt_pointer_walker pchw;
|
||||||
|
};
|
||||||
|
#define LAST_GGC_ROOT_TAB { NULL, 0, 0, NULL, NULL }
|
||||||
|
/* Pointers to arrays of ggc_root_tab, terminated by NULL. */
|
||||||
|
extern const struct ggc_root_tab * const gt_ggc_rtab[];
|
||||||
|
extern const struct ggc_root_tab * const gt_ggc_deletable_rtab[];
|
||||||
|
extern const struct ggc_root_tab * const gt_pch_cache_rtab[];
|
||||||
|
extern const struct ggc_root_tab * const gt_pch_scalar_rtab[];
|
||||||
|
|
||||||
|
/* Structure for hash table cache marking. */
|
||||||
|
struct htab;
|
||||||
|
struct ggc_cache_tab {
|
||||||
|
struct htab * *base;
|
||||||
|
size_t nelt;
|
||||||
|
size_t stride;
|
||||||
|
gt_pointer_walker cb;
|
||||||
|
gt_pointer_walker pchw;
|
||||||
|
int (*marked_p) (const void *);
|
||||||
|
};
|
||||||
|
#define LAST_GGC_CACHE_TAB { NULL, 0, 0, NULL, NULL, NULL }
|
||||||
|
/* Pointers to arrays of ggc_cache_tab, terminated by NULL. */
|
||||||
|
extern const struct ggc_cache_tab * const gt_ggc_cache_rtab[];
|
||||||
|
|
||||||
|
/* If EXPR is not NULL and previously unmarked, mark it and evaluate
|
||||||
|
to true. Otherwise evaluate to false. */
|
||||||
|
#define ggc_test_and_set_mark(EXPR) \
|
||||||
|
((EXPR) != NULL && ((void *) (EXPR)) != (void *) 1 && ! ggc_set_mark (EXPR))
|
||||||
|
|
||||||
|
#define ggc_mark(EXPR) \
|
||||||
|
do { \
|
||||||
|
const void *const a__ = (EXPR); \
|
||||||
|
if (a__ != NULL && a__ != (void *) 1) \
|
||||||
|
ggc_set_mark (a__); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/* Actually set the mark on a particular region of memory, but don't
|
||||||
|
follow pointers. This function is called by ggc_mark_*. It
|
||||||
|
returns zero if the object was not previously marked; nonzero if
|
||||||
|
the object was already marked, or if, for any other reason,
|
||||||
|
pointers in this data structure should not be traversed. */
|
||||||
|
extern int ggc_set_mark (const void *);
|
||||||
|
|
||||||
|
/* Return 1 if P has been marked, zero otherwise.
|
||||||
|
P must have been allocated by the GC allocator; it mustn't point to
|
||||||
|
static objects, stack variables, or memory allocated with malloc. */
|
||||||
|
extern int ggc_marked_p (const void *);
|
||||||
|
|
||||||
|
/* PCH and GGC handling for strings, mostly trivial. */
|
||||||
|
extern void gt_pch_n_S (const void *);
|
||||||
|
extern void gt_ggc_m_S (const void *);
|
||||||
|
|
||||||
|
/* End of GTY machinery API. */
|
||||||
|
|
||||||
|
/* Initialize the string pool. */
|
||||||
|
extern void init_stringpool (void);
|
||||||
|
|
||||||
|
/* Initialize the garbage collector. */
|
||||||
|
extern void init_ggc (void);
|
||||||
|
|
||||||
|
/* When true, identifier nodes are considered as GC roots. When
|
||||||
|
false, identifier nodes are treated like any other GC-allocated
|
||||||
|
object, and the identifier hash table is treated as a weak
|
||||||
|
hash. */
|
||||||
|
extern bool ggc_protect_identifiers;
|
||||||
|
|
||||||
|
/* Write out all GCed objects to F. */
|
||||||
|
extern void gt_pch_save (FILE *f);
|
||||||
|
|
||||||
|
|
||||||
|
/* Allocation. */
|
||||||
|
|
||||||
|
/* The internal primitive. */
|
||||||
|
extern void *ggc_internal_alloc_stat (size_t MEM_STAT_DECL)
|
||||||
|
ATTRIBUTE_MALLOC;
|
||||||
|
|
||||||
|
extern size_t ggc_round_alloc_size (size_t requested_size);
|
||||||
|
|
||||||
|
#define ggc_internal_alloc(s) ggc_internal_alloc_stat (s MEM_STAT_INFO)
|
||||||
|
|
||||||
|
/* Allocates cleared memory. */
|
||||||
|
extern void *ggc_internal_cleared_alloc_stat (size_t MEM_STAT_DECL)
|
||||||
|
ATTRIBUTE_MALLOC;
|
||||||
|
|
||||||
|
/* Resize a block. */
|
||||||
|
extern void *ggc_realloc_stat (void *, size_t MEM_STAT_DECL);
|
||||||
|
|
||||||
|
/* Free a block. To be used when known for certain it's not reachable. */
|
||||||
|
extern void ggc_free (void *);
|
||||||
|
|
||||||
|
extern void dump_ggc_loc_statistics (bool);
|
||||||
|
|
||||||
|
/* Reallocators. */
|
||||||
|
#define GGC_RESIZEVEC(T, P, N) \
|
||||||
|
((T *) ggc_realloc_stat ((P), (N) * sizeof (T) MEM_STAT_INFO))
|
||||||
|
|
||||||
|
#define GGC_RESIZEVAR(T, P, N) \
|
||||||
|
((T *) ggc_realloc_stat ((P), (N) MEM_STAT_INFO))
|
||||||
|
|
||||||
|
static inline void *
|
||||||
|
ggc_internal_vec_alloc_stat (size_t s, size_t c MEM_STAT_DECL)
|
||||||
|
{
|
||||||
|
return ggc_internal_alloc_stat (c * s PASS_MEM_STAT);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void *
|
||||||
|
ggc_internal_cleared_vec_alloc_stat (size_t s, size_t c MEM_STAT_DECL)
|
||||||
|
{
|
||||||
|
return ggc_internal_cleared_alloc_stat (c * s PASS_MEM_STAT);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ggc_internal_cleared_vec_alloc(s, c) \
|
||||||
|
(ggc_internal_cleared_vec_alloc_stat ((s), (c) MEM_STAT_INFO))
|
||||||
|
|
||||||
|
static inline void *
|
||||||
|
ggc_alloc_atomic_stat (size_t s MEM_STAT_DECL)
|
||||||
|
{
|
||||||
|
return ggc_internal_alloc_stat (s PASS_MEM_STAT);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ggc_alloc_atomic(S) (ggc_alloc_atomic_stat ((S) MEM_STAT_INFO))
|
||||||
|
|
||||||
|
#define ggc_alloc_cleared_atomic(S) \
|
||||||
|
(ggc_internal_cleared_alloc_stat ((S) MEM_STAT_INFO))
|
||||||
|
|
||||||
|
extern void *ggc_cleared_alloc_htab_ignore_args (size_t, size_t)
|
||||||
|
ATTRIBUTE_MALLOC;
|
||||||
|
|
||||||
|
extern void *ggc_cleared_alloc_ptr_array_two_args (size_t, size_t)
|
||||||
|
ATTRIBUTE_MALLOC;
|
||||||
|
|
||||||
|
#define htab_create_ggc(SIZE, HASH, EQ, DEL) \
|
||||||
|
htab_create_typed_alloc (SIZE, HASH, EQ, DEL, \
|
||||||
|
ggc_cleared_alloc_htab_ignore_args, \
|
||||||
|
ggc_cleared_alloc_ptr_array_two_args, \
|
||||||
|
ggc_free)
|
||||||
|
|
||||||
|
#define splay_tree_new_ggc(COMPARE, ALLOC_TREE, ALLOC_NODE) \
|
||||||
|
splay_tree_new_typed_alloc (COMPARE, NULL, NULL, &ALLOC_TREE, &ALLOC_NODE, \
|
||||||
|
&ggc_splay_dont_free, NULL)
|
||||||
|
|
||||||
|
extern void *ggc_splay_alloc (int, void *)
|
||||||
|
ATTRIBUTE_MALLOC;
|
||||||
|
|
||||||
|
extern void ggc_splay_dont_free (void *, void *);
|
||||||
|
|
||||||
|
/* Allocate a gc-able string, and fill it with LENGTH bytes from CONTENTS.
|
||||||
|
If LENGTH is -1, then CONTENTS is assumed to be a
|
||||||
|
null-terminated string and the memory sized accordingly. */
|
||||||
|
extern const char *ggc_alloc_string_stat (const char *contents, int length
|
||||||
|
MEM_STAT_DECL);
|
||||||
|
|
||||||
|
#define ggc_alloc_string(c, l) ggc_alloc_string_stat (c, l MEM_STAT_INFO)
|
||||||
|
|
||||||
|
/* Make a copy of S, in GC-able memory. */
|
||||||
|
#define ggc_strdup(S) ggc_alloc_string_stat ((S), -1 MEM_STAT_INFO)
|
||||||
|
|
||||||
|
/* Invoke the collector. Garbage collection occurs only when this
|
||||||
|
function is called, not during allocations. */
|
||||||
|
extern void ggc_collect (void);
|
||||||
|
|
||||||
|
/* Register an additional root table. This can be useful for some
|
||||||
|
plugins. Does nothing if the passed pointer is NULL. */
|
||||||
|
extern void ggc_register_root_tab (const struct ggc_root_tab *);
|
||||||
|
|
||||||
|
/* Register an additional cache table. This can be useful for some
|
||||||
|
plugins. Does nothing if the passed pointer is NULL. */
|
||||||
|
extern void ggc_register_cache_tab (const struct ggc_cache_tab *);
|
||||||
|
|
||||||
|
/* Read objects previously saved with gt_pch_save from F. */
|
||||||
|
extern void gt_pch_restore (FILE *f);
|
||||||
|
|
||||||
|
/* Statistics. */
|
||||||
|
|
||||||
|
/* Print allocation statistics. */
|
||||||
|
extern void ggc_print_statistics (void);
|
||||||
|
|
||||||
|
extern void stringpool_statistics (void);
|
||||||
|
|
||||||
|
/* Heuristics. */
|
||||||
|
extern void init_ggc_heuristics (void);
|
||||||
|
|
||||||
|
#define ggc_alloc_rtvec_sized(NELT) \
|
||||||
|
ggc_alloc_rtvec_def (sizeof (struct rtvec_def) \
|
||||||
|
+ ((NELT) - 1) * sizeof (rtx)) \
|
||||||
|
|
||||||
|
/* Memory statistics passing versions of some allocators. Too few of them to
|
||||||
|
make gengtype produce them, so just define the needed ones here. */
|
||||||
|
static inline struct rtx_def *
|
||||||
|
ggc_alloc_rtx_def_stat (size_t s MEM_STAT_DECL)
|
||||||
|
{
|
||||||
|
return (struct rtx_def *) ggc_internal_alloc_stat (s PASS_MEM_STAT);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline union tree_node *
|
||||||
|
ggc_alloc_tree_node_stat (size_t s MEM_STAT_DECL)
|
||||||
|
{
|
||||||
|
return (union tree_node *) ggc_internal_alloc_stat (s PASS_MEM_STAT);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline union tree_node *
|
||||||
|
ggc_alloc_cleared_tree_node_stat (size_t s MEM_STAT_DECL)
|
||||||
|
{
|
||||||
|
return (union tree_node *) ggc_internal_cleared_alloc_stat (s PASS_MEM_STAT);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline union gimple_statement_d *
|
||||||
|
ggc_alloc_cleared_gimple_statement_d_stat (size_t s MEM_STAT_DECL)
|
||||||
|
{
|
||||||
|
return (union gimple_statement_d *)
|
||||||
|
ggc_internal_cleared_alloc_stat (s PASS_MEM_STAT);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,36 @@
|
||||||
|
/* Various declarations for pretty formatting of GIMPLE statements and
|
||||||
|
expressions.
|
||||||
|
Copyright (C) 2000-2013 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free
|
||||||
|
Software Foundation; either version 3, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GCC; see the file COPYING3. If not see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#ifndef GCC_GIMPLE_PRETTY_PRINT_H
|
||||||
|
#define GCC_GIMPLE_PRETTY_PRINT_H
|
||||||
|
|
||||||
|
#include "pretty-print.h"
|
||||||
|
#include "tree-pretty-print.h"
|
||||||
|
|
||||||
|
/* In gimple-pretty-print.c */
|
||||||
|
extern void debug_gimple_stmt (gimple);
|
||||||
|
extern void debug_gimple_seq (gimple_seq);
|
||||||
|
extern void print_gimple_seq (FILE *, gimple_seq, int, int);
|
||||||
|
extern void print_gimple_stmt (FILE *, gimple, int, int);
|
||||||
|
extern void print_gimple_expr (FILE *, gimple, int, int);
|
||||||
|
extern void pp_gimple_stmt_1 (pretty_printer *, gimple, int, int);
|
||||||
|
extern void gimple_dump_bb_for_graph (pretty_printer *, basic_block);
|
||||||
|
|
||||||
|
#endif /* ! GCC_GIMPLE_PRETTY_PRINT_H */
|
|
@ -0,0 +1,364 @@
|
||||||
|
/* This file contains the definitions of the GIMPLE IR tuples used in GCC.
|
||||||
|
|
||||||
|
Copyright (C) 2007-2013 Free Software Foundation, Inc.
|
||||||
|
Contributed by Aldy Hernandez <aldyh@redhat.com>
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free
|
||||||
|
Software Foundation; either version 3, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GCC; see the file COPYING3. If not see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
/* The format of this file is
|
||||||
|
DEFGSCODE(GIMPLE_symbol, printable name, GSS_symbol). */
|
||||||
|
|
||||||
|
|
||||||
|
/* Error marker. This is used in similar ways as ERROR_MARK in tree.def. */
|
||||||
|
DEFGSCODE(GIMPLE_ERROR_MARK, "gimple_error_mark", GSS_BASE)
|
||||||
|
|
||||||
|
/* IMPORTANT. Do not rearrange the codes between GIMPLE_COND and
|
||||||
|
GIMPLE_RETURN. The ordering is exposed by gimple_has_ops calls.
|
||||||
|
These are all the GIMPLE statements with register operands. */
|
||||||
|
|
||||||
|
/* GIMPLE_COND <COND_CODE, OP1, OP2, TRUE_LABEL, FALSE_LABEL>
|
||||||
|
represents the conditional jump:
|
||||||
|
|
||||||
|
if (OP1 COND_CODE OP2) goto TRUE_LABEL else goto FALSE_LABEL
|
||||||
|
|
||||||
|
COND_CODE is the tree code used as the comparison predicate. It
|
||||||
|
must be of class tcc_comparison.
|
||||||
|
|
||||||
|
OP1 and OP2 are the operands used in the comparison. They must be
|
||||||
|
accepted by is_gimple_operand.
|
||||||
|
|
||||||
|
TRUE_LABEL and FALSE_LABEL are the LABEL_DECL nodes used as the
|
||||||
|
jump target for the comparison. */
|
||||||
|
DEFGSCODE(GIMPLE_COND, "gimple_cond", GSS_WITH_OPS)
|
||||||
|
|
||||||
|
/* GIMPLE_DEBUG represents a debug statement. */
|
||||||
|
DEFGSCODE(GIMPLE_DEBUG, "gimple_debug", GSS_WITH_OPS)
|
||||||
|
|
||||||
|
/* GIMPLE_GOTO <TARGET> represents unconditional jumps.
|
||||||
|
TARGET is a LABEL_DECL or an expression node for computed GOTOs. */
|
||||||
|
DEFGSCODE(GIMPLE_GOTO, "gimple_goto", GSS_WITH_OPS)
|
||||||
|
|
||||||
|
/* GIMPLE_LABEL <LABEL> represents label statements. LABEL is a
|
||||||
|
LABEL_DECL representing a jump target. */
|
||||||
|
DEFGSCODE(GIMPLE_LABEL, "gimple_label", GSS_WITH_OPS)
|
||||||
|
|
||||||
|
/* GIMPLE_SWITCH <INDEX, DEFAULT_LAB, LAB1, ..., LABN> represents the
|
||||||
|
multiway branch:
|
||||||
|
|
||||||
|
switch (INDEX)
|
||||||
|
{
|
||||||
|
case LAB1: ...; break;
|
||||||
|
...
|
||||||
|
case LABN: ...; break;
|
||||||
|
default: ...
|
||||||
|
}
|
||||||
|
|
||||||
|
INDEX is the variable evaluated to decide which label to jump to.
|
||||||
|
|
||||||
|
DEFAULT_LAB, LAB1 ... LABN are the tree nodes representing case labels.
|
||||||
|
They must be CASE_LABEL_EXPR nodes. */
|
||||||
|
DEFGSCODE(GIMPLE_SWITCH, "gimple_switch", GSS_WITH_OPS)
|
||||||
|
|
||||||
|
/* IMPORTANT.
|
||||||
|
|
||||||
|
Do not rearrange the codes between GIMPLE_ASSIGN and GIMPLE_RETURN.
|
||||||
|
It's exposed by GIMPLE_RANGE_CHECK calls. These are all the GIMPLE
|
||||||
|
statements with memory and register operands. */
|
||||||
|
|
||||||
|
/* GIMPLE_ASSIGN <SUBCODE, LHS, RHS1[, RHS2]> represents the assignment
|
||||||
|
statement
|
||||||
|
|
||||||
|
LHS = RHS1 SUBCODE RHS2.
|
||||||
|
|
||||||
|
SUBCODE is the tree code for the expression computed by the RHS of the
|
||||||
|
assignment. It must be one of the tree codes accepted by
|
||||||
|
get_gimple_rhs_class. If LHS is not a gimple register according to
|
||||||
|
is_gimple_reg, SUBCODE must be of class GIMPLE_SINGLE_RHS.
|
||||||
|
|
||||||
|
LHS is the operand on the LHS of the assignment. It must be a tree node
|
||||||
|
accepted by is_gimple_lvalue.
|
||||||
|
|
||||||
|
RHS1 is the first operand on the RHS of the assignment. It must always be
|
||||||
|
present. It must be a tree node accepted by is_gimple_val.
|
||||||
|
|
||||||
|
RHS2 is the second operand on the RHS of the assignment. It must be a tree
|
||||||
|
node accepted by is_gimple_val. This argument exists only if SUBCODE is
|
||||||
|
of class GIMPLE_BINARY_RHS. */
|
||||||
|
DEFGSCODE(GIMPLE_ASSIGN, "gimple_assign", GSS_WITH_MEM_OPS)
|
||||||
|
|
||||||
|
/* GIMPLE_ASM <STRING, I1, ..., IN, O1, ... OM, C1, ..., CP>
|
||||||
|
represents inline assembly statements.
|
||||||
|
|
||||||
|
STRING is the string containing the assembly statements.
|
||||||
|
I1 ... IN are the N input operands.
|
||||||
|
O1 ... OM are the M output operands.
|
||||||
|
C1 ... CP are the P clobber operands.
|
||||||
|
L1 ... LQ are the Q label operands. */
|
||||||
|
DEFGSCODE(GIMPLE_ASM, "gimple_asm", GSS_ASM)
|
||||||
|
|
||||||
|
/* GIMPLE_CALL <FN, LHS, ARG1, ..., ARGN[, CHAIN]> represents function
|
||||||
|
calls.
|
||||||
|
|
||||||
|
FN is the callee. It must be accepted by is_gimple_call_addr.
|
||||||
|
|
||||||
|
LHS is the operand where the return value from FN is stored. It may
|
||||||
|
be NULL.
|
||||||
|
|
||||||
|
ARG1 ... ARGN are the arguments. They must all be accepted by
|
||||||
|
is_gimple_operand.
|
||||||
|
|
||||||
|
CHAIN is the optional static chain link for nested functions. */
|
||||||
|
DEFGSCODE(GIMPLE_CALL, "gimple_call", GSS_CALL)
|
||||||
|
|
||||||
|
/* GIMPLE_TRANSACTION <BODY, LABEL> represents __transaction_atomic and
|
||||||
|
__transaction_relaxed blocks.
|
||||||
|
BODY is the sequence of statements inside the transaction.
|
||||||
|
LABEL is a label for the statement immediately following the
|
||||||
|
transaction. This is before RETURN so that it has MEM_OPS,
|
||||||
|
so that it can clobber global memory. */
|
||||||
|
DEFGSCODE(GIMPLE_TRANSACTION, "gimple_transaction", GSS_TRANSACTION)
|
||||||
|
|
||||||
|
/* GIMPLE_RETURN <RETVAL> represents return statements.
|
||||||
|
|
||||||
|
RETVAL is the value to return or NULL. If a value is returned it
|
||||||
|
must be accepted by is_gimple_operand. */
|
||||||
|
DEFGSCODE(GIMPLE_RETURN, "gimple_return", GSS_WITH_MEM_OPS)
|
||||||
|
|
||||||
|
/* GIMPLE_BIND <VARS, BLOCK, BODY> represents a lexical scope.
|
||||||
|
VARS is the set of variables declared in that scope.
|
||||||
|
BLOCK is the symbol binding block used for debug information.
|
||||||
|
BODY is the sequence of statements in the scope. */
|
||||||
|
DEFGSCODE(GIMPLE_BIND, "gimple_bind", GSS_BIND)
|
||||||
|
|
||||||
|
/* GIMPLE_CATCH <TYPES, HANDLER> represents a typed exception handler.
|
||||||
|
TYPES is the type (or list of types) handled. HANDLER is the
|
||||||
|
sequence of statements that handle these types. */
|
||||||
|
DEFGSCODE(GIMPLE_CATCH, "gimple_catch", GSS_CATCH)
|
||||||
|
|
||||||
|
/* GIMPLE_EH_FILTER <TYPES, FAILURE> represents an exception
|
||||||
|
specification. TYPES is a list of allowed types and FAILURE is the
|
||||||
|
sequence of statements to execute on failure. */
|
||||||
|
DEFGSCODE(GIMPLE_EH_FILTER, "gimple_eh_filter", GSS_EH_FILTER)
|
||||||
|
|
||||||
|
/* GIMPLE_EH_MUST_NOT_THROW <DECL> represents an exception barrier.
|
||||||
|
DECL is a noreturn function decl taking no arguments that will
|
||||||
|
be invoked if an exception propagates to this point. */
|
||||||
|
DEFGSCODE(GIMPLE_EH_MUST_NOT_THROW, "gimple_eh_must_not_throw", GSS_EH_MNT)
|
||||||
|
|
||||||
|
/* GIMPLE_EH_ELSE <N_BODY, E_BODY> must be the sole contents of
|
||||||
|
a GIMPLE_TRY_FINALLY node. For all normal exits from the try block,
|
||||||
|
N_BODY is run; for all exception exits from the try block,
|
||||||
|
E_BODY is run. */
|
||||||
|
DEFGSCODE(GIMPLE_EH_ELSE, "gimple_eh_else", GSS_EH_ELSE)
|
||||||
|
|
||||||
|
/* GIMPLE_RESX resumes execution after an exception. */
|
||||||
|
DEFGSCODE(GIMPLE_RESX, "gimple_resx", GSS_EH_CTRL)
|
||||||
|
|
||||||
|
/* GIMPLE_EH_DISPATCH demultiplexes an exception edge based on
|
||||||
|
the FILTER argument. */
|
||||||
|
DEFGSCODE(GIMPLE_EH_DISPATCH, "gimple_eh_dispatch", GSS_EH_CTRL)
|
||||||
|
|
||||||
|
/* GIMPLE_PHI <RESULT, ARG1, ..., ARGN> represents the PHI node
|
||||||
|
|
||||||
|
RESULT = PHI <ARG1, ..., ARGN>
|
||||||
|
|
||||||
|
RESULT is the SSA name created by this PHI node.
|
||||||
|
|
||||||
|
ARG1 ... ARGN are the arguments to the PHI node. N must be
|
||||||
|
exactly the same as the number of incoming edges to the basic block
|
||||||
|
holding the PHI node. Every argument is either an SSA name or a
|
||||||
|
tree node of class tcc_constant. */
|
||||||
|
DEFGSCODE(GIMPLE_PHI, "gimple_phi", GSS_PHI)
|
||||||
|
|
||||||
|
/* GIMPLE_TRY <TRY_KIND, EVAL, CLEANUP>
|
||||||
|
represents a try/catch or a try/finally statement.
|
||||||
|
|
||||||
|
TRY_KIND is either GIMPLE_TRY_CATCH or GIMPLE_TRY_FINALLY.
|
||||||
|
|
||||||
|
EVAL is the sequence of statements to execute on entry to GIMPLE_TRY.
|
||||||
|
|
||||||
|
CLEANUP is the sequence of statements to execute according to
|
||||||
|
TRY_KIND. If TRY_KIND is GIMPLE_TRY_CATCH, CLEANUP is only exected
|
||||||
|
if an exception is thrown during execution of EVAL. If TRY_KIND is
|
||||||
|
GIMPLE_TRY_FINALLY, CLEANUP is always executed after executing EVAL
|
||||||
|
(regardless of whether EVAL finished normally, or jumped out or an
|
||||||
|
exception was thrown). */
|
||||||
|
DEFGSCODE(GIMPLE_TRY, "gimple_try", GSS_TRY)
|
||||||
|
|
||||||
|
/* GIMPLE_NOP represents the "do nothing" statement. */
|
||||||
|
DEFGSCODE(GIMPLE_NOP, "gimple_nop", GSS_BASE)
|
||||||
|
|
||||||
|
|
||||||
|
/* IMPORTANT.
|
||||||
|
|
||||||
|
Do not rearrange any of the GIMPLE_OMP_* codes. This ordering is
|
||||||
|
exposed by the range check in gimple_omp_subcode(). */
|
||||||
|
|
||||||
|
|
||||||
|
/* Tuples used for lowering of OMP_ATOMIC. Although the form of the OMP_ATOMIC
|
||||||
|
expression is very simple (just in form mem op= expr), various implicit
|
||||||
|
conversions may cause the expression to become more complex, so that it does
|
||||||
|
not fit the gimple grammar very well. To overcome this problem, OMP_ATOMIC
|
||||||
|
is rewritten as a sequence of two codes in gimplification:
|
||||||
|
|
||||||
|
GIMPLE_OMP_LOAD (tmp, mem)
|
||||||
|
val = some computations involving tmp;
|
||||||
|
GIMPLE_OMP_STORE (val). */
|
||||||
|
DEFGSCODE(GIMPLE_OMP_ATOMIC_LOAD, "gimple_omp_atomic_load",
|
||||||
|
GSS_OMP_ATOMIC_LOAD)
|
||||||
|
DEFGSCODE(GIMPLE_OMP_ATOMIC_STORE, "gimple_omp_atomic_store",
|
||||||
|
GSS_OMP_ATOMIC_STORE)
|
||||||
|
|
||||||
|
/* GIMPLE_OMP_CONTINUE marks the location of the loop or sections
|
||||||
|
iteration in partially lowered OpenMP code. */
|
||||||
|
DEFGSCODE(GIMPLE_OMP_CONTINUE, "gimple_omp_continue", GSS_OMP_CONTINUE)
|
||||||
|
|
||||||
|
/* GIMPLE_OMP_CRITICAL <NAME, BODY> represents
|
||||||
|
|
||||||
|
#pragma omp critical [name]
|
||||||
|
|
||||||
|
NAME is the name given to the critical section.
|
||||||
|
BODY is the sequence of statements that are inside the critical section. */
|
||||||
|
DEFGSCODE(GIMPLE_OMP_CRITICAL, "gimple_omp_critical", GSS_OMP_CRITICAL)
|
||||||
|
|
||||||
|
/* GIMPLE_OMP_FOR <BODY, CLAUSES, INDEX, INITIAL, FINAL, COND, INCR, PRE_BODY>
|
||||||
|
represents
|
||||||
|
|
||||||
|
PRE_BODY
|
||||||
|
#pragma omp for [clause1 ... clauseN]
|
||||||
|
for (INDEX = INITIAL; INDEX COND FINAL; INDEX {+=,-=} INCR)
|
||||||
|
BODY
|
||||||
|
|
||||||
|
BODY is the loop body.
|
||||||
|
|
||||||
|
CLAUSES is the list of clauses.
|
||||||
|
|
||||||
|
INDEX must be an integer or pointer variable, which is implicitly thread
|
||||||
|
private. It must be accepted by is_gimple_operand.
|
||||||
|
|
||||||
|
INITIAL is the initial value given to INDEX. It must be
|
||||||
|
accepted by is_gimple_operand.
|
||||||
|
|
||||||
|
FINAL is the final value that INDEX should take. It must
|
||||||
|
be accepted by is_gimple_operand.
|
||||||
|
|
||||||
|
COND is the condition code for the controlling predicate. It must
|
||||||
|
be one of { <, >, <=, >= }
|
||||||
|
|
||||||
|
INCR is the loop index increment. It must be tree node of type
|
||||||
|
tcc_constant.
|
||||||
|
|
||||||
|
PRE_BODY is a landing pad filled by the gimplifier with things from
|
||||||
|
INIT, COND, and INCR that are technically part of the OMP_FOR
|
||||||
|
structured block, but are evaluated before the loop body begins.
|
||||||
|
|
||||||
|
INITIAL, FINAL and INCR are required to be loop invariant integer
|
||||||
|
expressions that are evaluated without any synchronization.
|
||||||
|
The evaluation order, frequency of evaluation and side-effects are
|
||||||
|
unspecified by the standard. */
|
||||||
|
DEFGSCODE(GIMPLE_OMP_FOR, "gimple_omp_for", GSS_OMP_FOR)
|
||||||
|
|
||||||
|
/* GIMPLE_OMP_MASTER <BODY> represents #pragma omp master.
|
||||||
|
BODY is the sequence of statements to execute in the master section. */
|
||||||
|
DEFGSCODE(GIMPLE_OMP_MASTER, "gimple_omp_master", GSS_OMP)
|
||||||
|
|
||||||
|
/* GIMPLE_OMP_ORDERED <BODY> represents #pragma omp ordered.
|
||||||
|
BODY is the sequence of statements to execute in the ordered section. */
|
||||||
|
DEFGSCODE(GIMPLE_OMP_ORDERED, "gimple_omp_ordered", GSS_OMP)
|
||||||
|
|
||||||
|
/* GIMPLE_OMP_PARALLEL <BODY, CLAUSES, CHILD_FN, DATA_ARG> represents
|
||||||
|
|
||||||
|
#pragma omp parallel [CLAUSES]
|
||||||
|
BODY
|
||||||
|
|
||||||
|
BODY is a the sequence of statements to be executed by all threads.
|
||||||
|
|
||||||
|
CLAUSES is a TREE_LIST node with all the clauses.
|
||||||
|
|
||||||
|
CHILD_FN is set when outlining the body of the parallel region.
|
||||||
|
All the statements in BODY are moved into this newly created
|
||||||
|
function when converting OMP constructs into low-GIMPLE.
|
||||||
|
|
||||||
|
DATA_ARG is a local variable in the parent function containing data
|
||||||
|
to be shared with CHILD_FN. This is used to implement all the data
|
||||||
|
sharing clauses. */
|
||||||
|
DEFGSCODE(GIMPLE_OMP_PARALLEL, "gimple_omp_parallel", GSS_OMP_PARALLEL)
|
||||||
|
|
||||||
|
/* GIMPLE_OMP_TASK <BODY, CLAUSES, CHILD_FN, DATA_ARG, COPY_FN,
|
||||||
|
ARG_SIZE, ARG_ALIGN> represents
|
||||||
|
|
||||||
|
#pragma omp task [CLAUSES]
|
||||||
|
BODY
|
||||||
|
|
||||||
|
BODY is a the sequence of statements to be executed by all threads.
|
||||||
|
|
||||||
|
CLAUSES is a TREE_LIST node with all the clauses.
|
||||||
|
|
||||||
|
CHILD_FN is set when outlining the body of the explicit task region.
|
||||||
|
All the statements in BODY are moved into this newly created
|
||||||
|
function when converting OMP constructs into low-GIMPLE.
|
||||||
|
|
||||||
|
DATA_ARG is a local variable in the parent function containing data
|
||||||
|
to be shared with CHILD_FN. This is used to implement all the data
|
||||||
|
sharing clauses.
|
||||||
|
|
||||||
|
COPY_FN is set when outlining the firstprivate var initialization.
|
||||||
|
All the needed statements are emitted into the newly created
|
||||||
|
function, or when only memcpy is needed, it is NULL.
|
||||||
|
|
||||||
|
ARG_SIZE and ARG_ALIGN are the size and alignment of the incoming
|
||||||
|
data area allocated by GOMP_task and passed to CHILD_FN. */
|
||||||
|
DEFGSCODE(GIMPLE_OMP_TASK, "gimple_omp_task", GSS_OMP_TASK)
|
||||||
|
|
||||||
|
/* OMP_RETURN marks the end of an OpenMP directive. */
|
||||||
|
DEFGSCODE(GIMPLE_OMP_RETURN, "gimple_omp_return", GSS_BASE)
|
||||||
|
|
||||||
|
/* OMP_SECTION <BODY> represents #pragma omp section.
|
||||||
|
BODY is the sequence of statements in the section body. */
|
||||||
|
DEFGSCODE(GIMPLE_OMP_SECTION, "gimple_omp_section", GSS_OMP)
|
||||||
|
|
||||||
|
/* OMP_SECTIONS <BODY, CLAUSES, CONTROL> represents #pragma omp sections.
|
||||||
|
|
||||||
|
BODY is the sequence of statements in the sections body.
|
||||||
|
CLAUSES is a TREE_LIST node holding the list of associated clauses.
|
||||||
|
CONTROL is a VAR_DECL used for deciding which of the sections
|
||||||
|
to execute. */
|
||||||
|
DEFGSCODE(GIMPLE_OMP_SECTIONS, "gimple_omp_sections", GSS_OMP_SECTIONS)
|
||||||
|
|
||||||
|
/* GIMPLE_OMP_SECTIONS_SWITCH is a marker placed immediately after
|
||||||
|
OMP_SECTIONS. It represents the GIMPLE_SWITCH used to decide which
|
||||||
|
branch is taken. */
|
||||||
|
DEFGSCODE(GIMPLE_OMP_SECTIONS_SWITCH, "gimple_omp_sections_switch", GSS_BASE)
|
||||||
|
|
||||||
|
/* GIMPLE_OMP_SINGLE <BODY, CLAUSES> represents #pragma omp single
|
||||||
|
BODY is the sequence of statements inside the single section.
|
||||||
|
CLAUSES is a TREE_LIST node holding the associated clauses. */
|
||||||
|
DEFGSCODE(GIMPLE_OMP_SINGLE, "gimple_omp_single", GSS_OMP_SINGLE)
|
||||||
|
|
||||||
|
/* GIMPLE_PREDICT <PREDICT, OUTCOME> specifies a hint for branch prediction.
|
||||||
|
|
||||||
|
PREDICT is one of the predictors from predict.def.
|
||||||
|
|
||||||
|
OUTCOME is NOT_TAKEN or TAKEN. */
|
||||||
|
DEFGSCODE(GIMPLE_PREDICT, "gimple_predict", GSS_BASE)
|
||||||
|
|
||||||
|
/* This node represents a cleanup expression. It is ONLY USED INTERNALLY
|
||||||
|
by the gimplifier as a placeholder for cleanups, and its uses will be
|
||||||
|
cleaned up by the time gimplification is done.
|
||||||
|
|
||||||
|
This tuple should not exist outside of the gimplifier proper. */
|
||||||
|
DEFGSCODE(GIMPLE_WITH_CLEANUP_EXPR, "gimple_with_cleanup_expr", GSS_WCE)
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,53 @@
|
||||||
|
/* This file contains the definitions for the gimple IR structure
|
||||||
|
enumeration used in GCC.
|
||||||
|
|
||||||
|
Copyright (C) 2007-2013 Free Software Foundation, Inc.
|
||||||
|
Contributed by Aldy Hernandez <aldyh@redhat.com>
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free
|
||||||
|
Software Foundation; either version 3, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GCC; see the file COPYING3. If not see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
/* The format of this file is
|
||||||
|
DEFGSSTRUCT(GSS enumeration value, structure name, has-tree-operands).
|
||||||
|
Each enum value should correspond with a single member of the union
|
||||||
|
gimple_statement_d. */
|
||||||
|
|
||||||
|
DEFGSSTRUCT(GSS_BASE, gimple_statement_base, false)
|
||||||
|
DEFGSSTRUCT(GSS_WITH_OPS, gimple_statement_with_ops, true)
|
||||||
|
DEFGSSTRUCT(GSS_WITH_MEM_OPS_BASE, gimple_statement_with_memory_ops_base, false)
|
||||||
|
DEFGSSTRUCT(GSS_WITH_MEM_OPS, gimple_statement_with_memory_ops, true)
|
||||||
|
DEFGSSTRUCT(GSS_CALL, gimple_statement_call, true)
|
||||||
|
DEFGSSTRUCT(GSS_ASM, gimple_statement_asm, true)
|
||||||
|
DEFGSSTRUCT(GSS_BIND, gimple_statement_bind, false)
|
||||||
|
DEFGSSTRUCT(GSS_PHI, gimple_statement_phi, false)
|
||||||
|
DEFGSSTRUCT(GSS_TRY, gimple_statement_try, false)
|
||||||
|
DEFGSSTRUCT(GSS_CATCH, gimple_statement_catch, false)
|
||||||
|
DEFGSSTRUCT(GSS_EH_FILTER, gimple_statement_eh_filter, false)
|
||||||
|
DEFGSSTRUCT(GSS_EH_MNT, gimple_statement_eh_mnt, false)
|
||||||
|
DEFGSSTRUCT(GSS_EH_CTRL, gimple_statement_eh_ctrl, false)
|
||||||
|
DEFGSSTRUCT(GSS_EH_ELSE, gimple_statement_eh_else, false)
|
||||||
|
DEFGSSTRUCT(GSS_WCE, gimple_statement_wce, false)
|
||||||
|
DEFGSSTRUCT(GSS_OMP, gimple_statement_omp, false)
|
||||||
|
DEFGSSTRUCT(GSS_OMP_CRITICAL, gimple_statement_omp_critical, false)
|
||||||
|
DEFGSSTRUCT(GSS_OMP_FOR, gimple_statement_omp_for, false)
|
||||||
|
DEFGSSTRUCT(GSS_OMP_PARALLEL, gimple_statement_omp_parallel, false)
|
||||||
|
DEFGSSTRUCT(GSS_OMP_TASK, gimple_statement_omp_task, false)
|
||||||
|
DEFGSSTRUCT(GSS_OMP_SECTIONS, gimple_statement_omp_sections, false)
|
||||||
|
DEFGSSTRUCT(GSS_OMP_SINGLE, gimple_statement_omp_single, false)
|
||||||
|
DEFGSSTRUCT(GSS_OMP_CONTINUE, gimple_statement_omp_continue, false)
|
||||||
|
DEFGSSTRUCT(GSS_OMP_ATOMIC_LOAD, gimple_statement_omp_atomic_load, false)
|
||||||
|
DEFGSSTRUCT(GSS_OMP_ATOMIC_STORE, gimple_statement_omp_atomic_store, false)
|
||||||
|
DEFGSSTRUCT(GSS_TRANSACTION, gimple_statement_transaction, false)
|
|
@ -0,0 +1,208 @@
|
||||||
|
DEF_TM_BUILTIN (BUILT_IN_TM_START, "_ITM_beginTransaction",
|
||||||
|
BT_FN_UINT32_UINT32_VAR, ATTR_TM_NOTHROW_RT_LIST)
|
||||||
|
|
||||||
|
DEF_TM_BUILTIN (BUILT_IN_TM_COMMIT, "_ITM_commitTransaction",
|
||||||
|
BT_FN_VOID, ATTR_TM_NOTHROW_LIST)
|
||||||
|
DEF_TM_BUILTIN (BUILT_IN_TM_COMMIT_EH, "_ITM_commitTransactionEH",
|
||||||
|
BT_FN_VOID_PTR, ATTR_TM_NOTHROW_LIST)
|
||||||
|
DEF_TM_BUILTIN (BUILT_IN_TM_ABORT, "_ITM_abortTransaction",
|
||||||
|
BT_FN_VOID_INT, ATTR_TM_NORETURN_NOTHROW_LIST)
|
||||||
|
DEF_TM_BUILTIN (BUILT_IN_TM_IRREVOCABLE, "_ITM_changeTransactionMode",
|
||||||
|
BT_FN_VOID_INT, ATTR_TM_NOTHROW_LIST)
|
||||||
|
|
||||||
|
DEF_TM_BUILTIN (BUILT_IN_TM_MEMCPY, "_ITM_memcpyRtWt",
|
||||||
|
BT_FN_VOID_PTR_CONST_PTR_SIZE, ATTR_TM_TMPURE_NOTHROW_LIST)
|
||||||
|
DEF_TM_BUILTIN (BUILT_IN_TM_MEMMOVE, "_ITM_memmoveRtWt",
|
||||||
|
BT_FN_VOID_PTR_CONST_PTR_SIZE, ATTR_TM_TMPURE_NOTHROW_LIST)
|
||||||
|
DEF_TM_BUILTIN (BUILT_IN_TM_MEMSET, "_ITM_memsetW",
|
||||||
|
BT_FN_VOID_PTR_INT_SIZE, ATTR_TM_TMPURE_NOTHROW_LIST)
|
||||||
|
|
||||||
|
DEF_TM_BUILTIN (BUILT_IN_TM_GETTMCLONE_IRR, "_ITM_getTMCloneOrIrrevocable",
|
||||||
|
BT_FN_PTR_PTR, ATTR_TM_CONST_NOTHROW_LIST)
|
||||||
|
DEF_TM_BUILTIN (BUILT_IN_TM_GETTMCLONE_SAFE, "_ITM_getTMCloneSafe",
|
||||||
|
BT_FN_PTR_PTR, ATTR_TM_CONST_NOTHROW_LIST)
|
||||||
|
|
||||||
|
/* Memory allocation builtins. */
|
||||||
|
DEF_TM_BUILTIN (BUILT_IN_TM_MALLOC, "_ITM_malloc",
|
||||||
|
BT_FN_PTR_SIZE, ATTR_TMPURE_MALLOC_NOTHROW_LIST)
|
||||||
|
DEF_TM_BUILTIN (BUILT_IN_TM_CALLOC, "_ITM_calloc",
|
||||||
|
BT_FN_PTR_SIZE_SIZE, ATTR_TMPURE_MALLOC_NOTHROW_LIST)
|
||||||
|
DEF_TM_BUILTIN (BUILT_IN_TM_FREE, "_ITM_free",
|
||||||
|
BT_FN_VOID_PTR, ATTR_TMPURE_NOTHROW_LIST)
|
||||||
|
|
||||||
|
/* Logging builtins. */
|
||||||
|
DEF_TM_BUILTIN (BUILT_IN_TM_LOG_1, "_ITM_LU1",
|
||||||
|
BT_FN_VOID_VPTR, ATTR_TM_TMPURE_NOTHROW_LIST)
|
||||||
|
DEF_TM_BUILTIN (BUILT_IN_TM_LOG_2, "_ITM_LU2",
|
||||||
|
BT_FN_VOID_VPTR, ATTR_TM_TMPURE_NOTHROW_LIST)
|
||||||
|
DEF_TM_BUILTIN (BUILT_IN_TM_LOG_4, "_ITM_LU4",
|
||||||
|
BT_FN_VOID_VPTR, ATTR_TM_TMPURE_NOTHROW_LIST)
|
||||||
|
DEF_TM_BUILTIN (BUILT_IN_TM_LOG_8, "_ITM_LU8",
|
||||||
|
BT_FN_VOID_VPTR, ATTR_TM_TMPURE_NOTHROW_LIST)
|
||||||
|
DEF_TM_BUILTIN (BUILT_IN_TM_LOG_FLOAT, "_ITM_LF",
|
||||||
|
BT_FN_VOID_VPTR, ATTR_TM_TMPURE_NOTHROW_LIST)
|
||||||
|
DEF_TM_BUILTIN (BUILT_IN_TM_LOG_DOUBLE, "_ITM_LD",
|
||||||
|
BT_FN_VOID_VPTR, ATTR_TM_TMPURE_NOTHROW_LIST)
|
||||||
|
DEF_TM_BUILTIN (BUILT_IN_TM_LOG_LDOUBLE, "_ITM_LE",
|
||||||
|
BT_FN_VOID_VPTR, ATTR_TM_TMPURE_NOTHROW_LIST)
|
||||||
|
DEF_TM_BUILTIN (BUILT_IN_TM_LOG, "_ITM_LB",
|
||||||
|
BT_FN_VOID_VPTR_SIZE, ATTR_TM_TMPURE_NOTHROW_LIST)
|
||||||
|
|
||||||
|
/* These stubs should get defined in the backend if applicable. */
|
||||||
|
DEF_BUILTIN_STUB (BUILT_IN_TM_LOG_M64, "__builtin__ITM_LM64")
|
||||||
|
DEF_BUILTIN_STUB (BUILT_IN_TM_LOG_M128, "__builtin__ITM_LM128")
|
||||||
|
DEF_BUILTIN_STUB (BUILT_IN_TM_LOG_M256, "__builtin__ITM_LM256")
|
||||||
|
|
||||||
|
/* Writes.
|
||||||
|
|
||||||
|
Note: The writes must follow the following order: STORE, WAR, WAW.
|
||||||
|
The TM optimizations depend on this order.
|
||||||
|
|
||||||
|
BUILT_IN_TM_STORE_1 must be the first builtin.
|
||||||
|
BUILTIN_TM_LOAD_STORE_P depends on this. */
|
||||||
|
DEF_TM_BUILTIN (BUILT_IN_TM_STORE_1, "_ITM_WU1",
|
||||||
|
BT_FN_VOID_VPTR_I1, ATTR_TM_NOTHROW_LIST)
|
||||||
|
DEF_TM_BUILTIN (BUILT_IN_TM_STORE_WAR_1, "_ITM_WaRU1",
|
||||||
|
BT_FN_VOID_VPTR_I1, ATTR_TM_NOTHROW_LIST)
|
||||||
|
DEF_TM_BUILTIN (BUILT_IN_TM_STORE_WAW_1, "_ITM_WaWU1",
|
||||||
|
BT_FN_VOID_VPTR_I1, ATTR_TM_NOTHROW_LIST)
|
||||||
|
|
||||||
|
DEF_TM_BUILTIN (BUILT_IN_TM_STORE_2, "_ITM_WU2",
|
||||||
|
BT_FN_VOID_VPTR_I2, ATTR_TM_NOTHROW_LIST)
|
||||||
|
DEF_TM_BUILTIN (BUILT_IN_TM_STORE_WAR_2, "_ITM_WaRU2",
|
||||||
|
BT_FN_VOID_VPTR_I2, ATTR_TM_NOTHROW_LIST)
|
||||||
|
DEF_TM_BUILTIN (BUILT_IN_TM_STORE_WAW_2, "_ITM_WaWU2",
|
||||||
|
BT_FN_VOID_VPTR_I2, ATTR_TM_NOTHROW_LIST)
|
||||||
|
|
||||||
|
DEF_TM_BUILTIN (BUILT_IN_TM_STORE_4, "_ITM_WU4",
|
||||||
|
BT_FN_VOID_VPTR_I4, ATTR_TM_NOTHROW_LIST)
|
||||||
|
DEF_TM_BUILTIN (BUILT_IN_TM_STORE_WAR_4, "_ITM_WaRU4",
|
||||||
|
BT_FN_VOID_VPTR_I4, ATTR_TM_NOTHROW_LIST)
|
||||||
|
DEF_TM_BUILTIN (BUILT_IN_TM_STORE_WAW_4, "_ITM_WaWU4",
|
||||||
|
BT_FN_VOID_VPTR_I4, ATTR_TM_NOTHROW_LIST)
|
||||||
|
|
||||||
|
DEF_TM_BUILTIN (BUILT_IN_TM_STORE_8, "_ITM_WU8",
|
||||||
|
BT_FN_VOID_VPTR_I8, ATTR_TM_NOTHROW_LIST)
|
||||||
|
DEF_TM_BUILTIN (BUILT_IN_TM_STORE_WAR_8, "_ITM_WaRU8",
|
||||||
|
BT_FN_VOID_VPTR_I8, ATTR_TM_NOTHROW_LIST)
|
||||||
|
DEF_TM_BUILTIN (BUILT_IN_TM_STORE_WAW_8, "_ITM_WaWU8",
|
||||||
|
BT_FN_VOID_VPTR_I8, ATTR_TM_NOTHROW_LIST)
|
||||||
|
|
||||||
|
DEF_TM_BUILTIN (BUILT_IN_TM_STORE_FLOAT, "_ITM_WF",
|
||||||
|
BT_FN_VOID_VPTR_FLOAT, ATTR_TM_NOTHROW_LIST)
|
||||||
|
DEF_TM_BUILTIN (BUILT_IN_TM_STORE_WAR_FLOAT, "_ITM_WaRF",
|
||||||
|
BT_FN_VOID_VPTR_FLOAT, ATTR_TM_NOTHROW_LIST)
|
||||||
|
DEF_TM_BUILTIN (BUILT_IN_TM_STORE_WAW_FLOAT, "_ITM_WaWF",
|
||||||
|
BT_FN_VOID_VPTR_FLOAT, ATTR_TM_NOTHROW_LIST)
|
||||||
|
|
||||||
|
DEF_TM_BUILTIN (BUILT_IN_TM_STORE_DOUBLE, "_ITM_WD",
|
||||||
|
BT_FN_VOID_VPTR_DOUBLE, ATTR_TM_NOTHROW_LIST)
|
||||||
|
DEF_TM_BUILTIN (BUILT_IN_TM_STORE_WAR_DOUBLE, "_ITM_WaRD",
|
||||||
|
BT_FN_VOID_VPTR_DOUBLE, ATTR_TM_NOTHROW_LIST)
|
||||||
|
DEF_TM_BUILTIN (BUILT_IN_TM_STORE_WAW_DOUBLE, "_ITM_WaWD",
|
||||||
|
BT_FN_VOID_VPTR_DOUBLE, ATTR_TM_NOTHROW_LIST)
|
||||||
|
|
||||||
|
/* These stubs should get defined in the backend if applicable. */
|
||||||
|
DEF_BUILTIN_STUB (BUILT_IN_TM_STORE_M64, "__builtin__ITM_WM64")
|
||||||
|
DEF_BUILTIN_STUB (BUILT_IN_TM_STORE_WAR_M64, "__builtin__ITM_WaRM64")
|
||||||
|
DEF_BUILTIN_STUB (BUILT_IN_TM_STORE_WAW_M64, "__builtin__ITM_WaWM64")
|
||||||
|
DEF_BUILTIN_STUB (BUILT_IN_TM_STORE_M128, "__builtin__ITM_WM128")
|
||||||
|
DEF_BUILTIN_STUB (BUILT_IN_TM_STORE_WAR_M128, "__builtin__ITM_WaRM128")
|
||||||
|
DEF_BUILTIN_STUB (BUILT_IN_TM_STORE_WAW_M128, "__builtin__ITM_WaWM128")
|
||||||
|
DEF_BUILTIN_STUB (BUILT_IN_TM_STORE_M256, "__builtin__ITM_WM256")
|
||||||
|
DEF_BUILTIN_STUB (BUILT_IN_TM_STORE_WAR_M256, "__builtin__ITM_WaRM256")
|
||||||
|
DEF_BUILTIN_STUB (BUILT_IN_TM_STORE_WAW_M256, "__builtin__ITM_WaWM256")
|
||||||
|
|
||||||
|
DEF_TM_BUILTIN (BUILT_IN_TM_STORE_LDOUBLE, "_ITM_WE",
|
||||||
|
BT_FN_VOID_VPTR_LDOUBLE, ATTR_TM_NOTHROW_LIST)
|
||||||
|
DEF_TM_BUILTIN (BUILT_IN_TM_STORE_WAR_LDOUBLE, "_ITM_WaRE",
|
||||||
|
BT_FN_VOID_VPTR_LDOUBLE, ATTR_TM_NOTHROW_LIST)
|
||||||
|
DEF_TM_BUILTIN (BUILT_IN_TM_STORE_WAW_LDOUBLE, "_ITM_WaWE",
|
||||||
|
BT_FN_VOID_VPTR_LDOUBLE, ATTR_TM_NOTHROW_LIST)
|
||||||
|
/* Note: BUILT_IN_TM_STORE_WAW_LDOUBLE must be the last TM store.
|
||||||
|
BUILTIN_TM_STORE_P depends on this. */
|
||||||
|
|
||||||
|
/* Reads.
|
||||||
|
|
||||||
|
Note: The reads must follow the following order: LOAD, RAR, RAW, RFW.
|
||||||
|
The TM optimizations depend on this order. */
|
||||||
|
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_1, "_ITM_RU1",
|
||||||
|
BT_FN_I1_VPTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
||||||
|
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_RAR_1, "_ITM_RaRU1",
|
||||||
|
BT_FN_I1_VPTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
||||||
|
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_RAW_1, "_ITM_RaWU1",
|
||||||
|
BT_FN_I1_VPTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
||||||
|
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_RFW_1, "_ITM_RfWU1",
|
||||||
|
BT_FN_I1_VPTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
||||||
|
|
||||||
|
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_2, "_ITM_RU2",
|
||||||
|
BT_FN_I2_VPTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
||||||
|
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_RAR_2, "_ITM_RaRU2",
|
||||||
|
BT_FN_I2_VPTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
||||||
|
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_RAW_2, "_ITM_RaWU2",
|
||||||
|
BT_FN_I2_VPTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
||||||
|
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_RFW_2, "_ITM_RfWU2",
|
||||||
|
BT_FN_I2_VPTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
||||||
|
|
||||||
|
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_4, "_ITM_RU4",
|
||||||
|
BT_FN_I4_VPTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
||||||
|
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_RAR_4, "_ITM_RaRU4",
|
||||||
|
BT_FN_I4_VPTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
||||||
|
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_RAW_4, "_ITM_RaWU4",
|
||||||
|
BT_FN_I4_VPTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
||||||
|
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_RFW_4, "_ITM_RfWU4",
|
||||||
|
BT_FN_I4_VPTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
||||||
|
|
||||||
|
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_8, "_ITM_RU8",
|
||||||
|
BT_FN_I8_VPTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
||||||
|
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_RAR_8, "_ITM_RaRU8",
|
||||||
|
BT_FN_I8_VPTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
||||||
|
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_RAW_8, "_ITM_RaWU8",
|
||||||
|
BT_FN_I8_VPTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
||||||
|
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_RFW_8, "_ITM_RfWU8",
|
||||||
|
BT_FN_I8_VPTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
||||||
|
|
||||||
|
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_FLOAT, "_ITM_RF",
|
||||||
|
BT_FN_FLOAT_VPTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
||||||
|
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_RAR_FLOAT, "_ITM_RaRF",
|
||||||
|
BT_FN_FLOAT_VPTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
||||||
|
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_RAW_FLOAT, "_ITM_RaWF",
|
||||||
|
BT_FN_FLOAT_VPTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
||||||
|
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_RFW_FLOAT, "_ITM_RfWF",
|
||||||
|
BT_FN_FLOAT_VPTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
||||||
|
|
||||||
|
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_DOUBLE, "_ITM_RD",
|
||||||
|
BT_FN_DOUBLE_CONST_DOUBLE_PTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
||||||
|
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_RAR_DOUBLE, "_ITM_RaRD",
|
||||||
|
BT_FN_DOUBLE_CONST_DOUBLE_PTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
||||||
|
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_RAW_DOUBLE, "_ITM_RaWD",
|
||||||
|
BT_FN_DOUBLE_CONST_DOUBLE_PTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
||||||
|
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_RFW_DOUBLE, "_ITM_RfWD",
|
||||||
|
BT_FN_DOUBLE_CONST_DOUBLE_PTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
||||||
|
|
||||||
|
/* These stubs should get defined in the backend if applicable. */
|
||||||
|
DEF_BUILTIN_STUB (BUILT_IN_TM_LOAD_M64, "__builtin__ITM_RM64")
|
||||||
|
DEF_BUILTIN_STUB (BUILT_IN_TM_LOAD_RAR_M64, "__builtin__ITM_RaRM64")
|
||||||
|
DEF_BUILTIN_STUB (BUILT_IN_TM_LOAD_RAW_M64, "__builtin__ITM_RaRM64")
|
||||||
|
DEF_BUILTIN_STUB (BUILT_IN_TM_LOAD_RFW_M64, "__builtin__ITM_RfWM64")
|
||||||
|
DEF_BUILTIN_STUB (BUILT_IN_TM_LOAD_M128, "__builtin__ITM_RM128")
|
||||||
|
DEF_BUILTIN_STUB (BUILT_IN_TM_LOAD_RAR_M128, "__builtin__ITM_RaRM128")
|
||||||
|
DEF_BUILTIN_STUB (BUILT_IN_TM_LOAD_RAW_M128, "__builtin__ITM_RaRM128")
|
||||||
|
DEF_BUILTIN_STUB (BUILT_IN_TM_LOAD_RFW_M128, "__builtin__ITM_RfWM128")
|
||||||
|
DEF_BUILTIN_STUB (BUILT_IN_TM_LOAD_M256, "__builtin__ITM_RM256")
|
||||||
|
DEF_BUILTIN_STUB (BUILT_IN_TM_LOAD_RAR_M256, "__builtin__ITM_RaRM256")
|
||||||
|
DEF_BUILTIN_STUB (BUILT_IN_TM_LOAD_RAW_M256, "__builtin__ITM_RaRM256")
|
||||||
|
DEF_BUILTIN_STUB (BUILT_IN_TM_LOAD_RFW_M256, "__builtin__ITM_RfWM256")
|
||||||
|
|
||||||
|
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_LDOUBLE, "_ITM_RE",
|
||||||
|
BT_FN_LDOUBLE_VPTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
||||||
|
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_RAR_LDOUBLE, "_ITM_RaRE",
|
||||||
|
BT_FN_LDOUBLE_VPTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
||||||
|
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_RAW_LDOUBLE, "_ITM_RaWE",
|
||||||
|
BT_FN_LDOUBLE_VPTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
||||||
|
DEF_TM_BUILTIN (BUILT_IN_TM_LOAD_RFW_LDOUBLE, "_ITM_RfWE",
|
||||||
|
BT_FN_LDOUBLE_VPTR, ATTR_TM_PURE_TMPURE_NOTHROW_LIST)
|
||||||
|
|
||||||
|
/* Note: BUILT_IN_TM_LOAD_RFW_LDOUBLE must be the last TM load as well
|
||||||
|
as the last builtin. BUILTIN_TM_LOAD_STORE_P and BUILTIN_TM_LOAD_P
|
||||||
|
depend on this. */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,724 @@
|
||||||
|
/* Sets (bit vectors) of hard registers, and operations on them.
|
||||||
|
Copyright (C) 1987-2013 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GCC
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free
|
||||||
|
Software Foundation; either version 3, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GCC; see the file COPYING3. If not see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#ifndef GCC_HARD_REG_SET_H
|
||||||
|
#define GCC_HARD_REG_SET_H
|
||||||
|
|
||||||
|
/* Define the type of a set of hard registers. */
|
||||||
|
|
||||||
|
/* HARD_REG_ELT_TYPE is a typedef of the unsigned integral type which
|
||||||
|
will be used for hard reg sets, either alone or in an array.
|
||||||
|
|
||||||
|
If HARD_REG_SET is a macro, its definition is HARD_REG_ELT_TYPE,
|
||||||
|
and it has enough bits to represent all the target machine's hard
|
||||||
|
registers. Otherwise, it is a typedef for a suitably sized array
|
||||||
|
of HARD_REG_ELT_TYPEs. HARD_REG_SET_LONGS is defined as how many.
|
||||||
|
|
||||||
|
Note that lots of code assumes that the first part of a regset is
|
||||||
|
the same format as a HARD_REG_SET. To help make sure this is true,
|
||||||
|
we only try the widest fast integer mode (HOST_WIDEST_FAST_INT)
|
||||||
|
instead of all the smaller types. This approach loses only if
|
||||||
|
there are very few registers and then only in the few cases where
|
||||||
|
we have an array of HARD_REG_SETs, so it needn't be as complex as
|
||||||
|
it used to be. */
|
||||||
|
|
||||||
|
typedef unsigned HOST_WIDEST_FAST_INT HARD_REG_ELT_TYPE;
|
||||||
|
|
||||||
|
#if FIRST_PSEUDO_REGISTER <= HOST_BITS_PER_WIDEST_FAST_INT
|
||||||
|
|
||||||
|
#define HARD_REG_SET HARD_REG_ELT_TYPE
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define HARD_REG_SET_LONGS \
|
||||||
|
((FIRST_PSEUDO_REGISTER + HOST_BITS_PER_WIDEST_FAST_INT - 1) \
|
||||||
|
/ HOST_BITS_PER_WIDEST_FAST_INT)
|
||||||
|
typedef HARD_REG_ELT_TYPE HARD_REG_SET[HARD_REG_SET_LONGS];
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* HARD_REG_SET wrapped into a structure, to make it possible to
|
||||||
|
use HARD_REG_SET even in APIs that should not include
|
||||||
|
hard-reg-set.h. */
|
||||||
|
struct hard_reg_set_container
|
||||||
|
{
|
||||||
|
HARD_REG_SET set;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* HARD_CONST is used to cast a constant to the appropriate type
|
||||||
|
for use with a HARD_REG_SET. */
|
||||||
|
|
||||||
|
#define HARD_CONST(X) ((HARD_REG_ELT_TYPE) (X))
|
||||||
|
|
||||||
|
/* Define macros SET_HARD_REG_BIT, CLEAR_HARD_REG_BIT and TEST_HARD_REG_BIT
|
||||||
|
to set, clear or test one bit in a hard reg set of type HARD_REG_SET.
|
||||||
|
All three take two arguments: the set and the register number.
|
||||||
|
|
||||||
|
In the case where sets are arrays of longs, the first argument
|
||||||
|
is actually a pointer to a long.
|
||||||
|
|
||||||
|
Define two macros for initializing a set:
|
||||||
|
CLEAR_HARD_REG_SET and SET_HARD_REG_SET.
|
||||||
|
These take just one argument.
|
||||||
|
|
||||||
|
Also define macros for copying hard reg sets:
|
||||||
|
COPY_HARD_REG_SET and COMPL_HARD_REG_SET.
|
||||||
|
These take two arguments TO and FROM; they read from FROM
|
||||||
|
and store into TO. COMPL_HARD_REG_SET complements each bit.
|
||||||
|
|
||||||
|
Also define macros for combining hard reg sets:
|
||||||
|
IOR_HARD_REG_SET and AND_HARD_REG_SET.
|
||||||
|
These take two arguments TO and FROM; they read from FROM
|
||||||
|
and combine bitwise into TO. Define also two variants
|
||||||
|
IOR_COMPL_HARD_REG_SET and AND_COMPL_HARD_REG_SET
|
||||||
|
which use the complement of the set FROM.
|
||||||
|
|
||||||
|
Also define:
|
||||||
|
|
||||||
|
hard_reg_set_subset_p (X, Y), which returns true if X is a subset of Y.
|
||||||
|
hard_reg_set_equal_p (X, Y), which returns true if X and Y are equal.
|
||||||
|
hard_reg_set_intersect_p (X, Y), which returns true if X and Y intersect.
|
||||||
|
hard_reg_set_empty_p (X), which returns true if X is empty. */
|
||||||
|
|
||||||
|
#define UHOST_BITS_PER_WIDE_INT ((unsigned) HOST_BITS_PER_WIDEST_FAST_INT)
|
||||||
|
|
||||||
|
#ifdef HARD_REG_SET
|
||||||
|
|
||||||
|
#define SET_HARD_REG_BIT(SET, BIT) \
|
||||||
|
((SET) |= HARD_CONST (1) << (BIT))
|
||||||
|
#define CLEAR_HARD_REG_BIT(SET, BIT) \
|
||||||
|
((SET) &= ~(HARD_CONST (1) << (BIT)))
|
||||||
|
#define TEST_HARD_REG_BIT(SET, BIT) \
|
||||||
|
(!!((SET) & (HARD_CONST (1) << (BIT))))
|
||||||
|
|
||||||
|
#define CLEAR_HARD_REG_SET(TO) ((TO) = HARD_CONST (0))
|
||||||
|
#define SET_HARD_REG_SET(TO) ((TO) = ~ HARD_CONST (0))
|
||||||
|
|
||||||
|
#define COPY_HARD_REG_SET(TO, FROM) ((TO) = (FROM))
|
||||||
|
#define COMPL_HARD_REG_SET(TO, FROM) ((TO) = ~(FROM))
|
||||||
|
|
||||||
|
#define IOR_HARD_REG_SET(TO, FROM) ((TO) |= (FROM))
|
||||||
|
#define IOR_COMPL_HARD_REG_SET(TO, FROM) ((TO) |= ~ (FROM))
|
||||||
|
#define AND_HARD_REG_SET(TO, FROM) ((TO) &= (FROM))
|
||||||
|
#define AND_COMPL_HARD_REG_SET(TO, FROM) ((TO) &= ~ (FROM))
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
hard_reg_set_subset_p (const HARD_REG_SET x, const HARD_REG_SET y)
|
||||||
|
{
|
||||||
|
return (x & ~y) == HARD_CONST (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
hard_reg_set_equal_p (const HARD_REG_SET x, const HARD_REG_SET y)
|
||||||
|
{
|
||||||
|
return x == y;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
hard_reg_set_intersect_p (const HARD_REG_SET x, const HARD_REG_SET y)
|
||||||
|
{
|
||||||
|
return (x & y) != HARD_CONST (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
hard_reg_set_empty_p (const HARD_REG_SET x)
|
||||||
|
{
|
||||||
|
return x == HARD_CONST (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define SET_HARD_REG_BIT(SET, BIT) \
|
||||||
|
((SET)[(BIT) / UHOST_BITS_PER_WIDE_INT] \
|
||||||
|
|= HARD_CONST (1) << ((BIT) % UHOST_BITS_PER_WIDE_INT))
|
||||||
|
|
||||||
|
#define CLEAR_HARD_REG_BIT(SET, BIT) \
|
||||||
|
((SET)[(BIT) / UHOST_BITS_PER_WIDE_INT] \
|
||||||
|
&= ~(HARD_CONST (1) << ((BIT) % UHOST_BITS_PER_WIDE_INT)))
|
||||||
|
|
||||||
|
#define TEST_HARD_REG_BIT(SET, BIT) \
|
||||||
|
(!!((SET)[(BIT) / UHOST_BITS_PER_WIDE_INT] \
|
||||||
|
& (HARD_CONST (1) << ((BIT) % UHOST_BITS_PER_WIDE_INT))))
|
||||||
|
|
||||||
|
#if FIRST_PSEUDO_REGISTER <= 2*HOST_BITS_PER_WIDEST_FAST_INT
|
||||||
|
#define CLEAR_HARD_REG_SET(TO) \
|
||||||
|
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \
|
||||||
|
scan_tp_[0] = 0; \
|
||||||
|
scan_tp_[1] = 0; } while (0)
|
||||||
|
|
||||||
|
#define SET_HARD_REG_SET(TO) \
|
||||||
|
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \
|
||||||
|
scan_tp_[0] = -1; \
|
||||||
|
scan_tp_[1] = -1; } while (0)
|
||||||
|
|
||||||
|
#define COPY_HARD_REG_SET(TO, FROM) \
|
||||||
|
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
|
||||||
|
scan_tp_[0] = scan_fp_[0]; \
|
||||||
|
scan_tp_[1] = scan_fp_[1]; } while (0)
|
||||||
|
|
||||||
|
#define COMPL_HARD_REG_SET(TO, FROM) \
|
||||||
|
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
|
||||||
|
scan_tp_[0] = ~ scan_fp_[0]; \
|
||||||
|
scan_tp_[1] = ~ scan_fp_[1]; } while (0)
|
||||||
|
|
||||||
|
#define AND_HARD_REG_SET(TO, FROM) \
|
||||||
|
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
|
||||||
|
scan_tp_[0] &= scan_fp_[0]; \
|
||||||
|
scan_tp_[1] &= scan_fp_[1]; } while (0)
|
||||||
|
|
||||||
|
#define AND_COMPL_HARD_REG_SET(TO, FROM) \
|
||||||
|
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
|
||||||
|
scan_tp_[0] &= ~ scan_fp_[0]; \
|
||||||
|
scan_tp_[1] &= ~ scan_fp_[1]; } while (0)
|
||||||
|
|
||||||
|
#define IOR_HARD_REG_SET(TO, FROM) \
|
||||||
|
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
|
||||||
|
scan_tp_[0] |= scan_fp_[0]; \
|
||||||
|
scan_tp_[1] |= scan_fp_[1]; } while (0)
|
||||||
|
|
||||||
|
#define IOR_COMPL_HARD_REG_SET(TO, FROM) \
|
||||||
|
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
|
||||||
|
scan_tp_[0] |= ~ scan_fp_[0]; \
|
||||||
|
scan_tp_[1] |= ~ scan_fp_[1]; } while (0)
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
hard_reg_set_subset_p (const HARD_REG_SET x, const HARD_REG_SET y)
|
||||||
|
{
|
||||||
|
return (x[0] & ~y[0]) == 0 && (x[1] & ~y[1]) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
hard_reg_set_equal_p (const HARD_REG_SET x, const HARD_REG_SET y)
|
||||||
|
{
|
||||||
|
return x[0] == y[0] && x[1] == y[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
hard_reg_set_intersect_p (const HARD_REG_SET x, const HARD_REG_SET y)
|
||||||
|
{
|
||||||
|
return (x[0] & y[0]) != 0 || (x[1] & y[1]) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
hard_reg_set_empty_p (const HARD_REG_SET x)
|
||||||
|
{
|
||||||
|
return x[0] == 0 && x[1] == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
#if FIRST_PSEUDO_REGISTER <= 3*HOST_BITS_PER_WIDEST_FAST_INT
|
||||||
|
#define CLEAR_HARD_REG_SET(TO) \
|
||||||
|
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \
|
||||||
|
scan_tp_[0] = 0; \
|
||||||
|
scan_tp_[1] = 0; \
|
||||||
|
scan_tp_[2] = 0; } while (0)
|
||||||
|
|
||||||
|
#define SET_HARD_REG_SET(TO) \
|
||||||
|
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \
|
||||||
|
scan_tp_[0] = -1; \
|
||||||
|
scan_tp_[1] = -1; \
|
||||||
|
scan_tp_[2] = -1; } while (0)
|
||||||
|
|
||||||
|
#define COPY_HARD_REG_SET(TO, FROM) \
|
||||||
|
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
|
||||||
|
scan_tp_[0] = scan_fp_[0]; \
|
||||||
|
scan_tp_[1] = scan_fp_[1]; \
|
||||||
|
scan_tp_[2] = scan_fp_[2]; } while (0)
|
||||||
|
|
||||||
|
#define COMPL_HARD_REG_SET(TO, FROM) \
|
||||||
|
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
|
||||||
|
scan_tp_[0] = ~ scan_fp_[0]; \
|
||||||
|
scan_tp_[1] = ~ scan_fp_[1]; \
|
||||||
|
scan_tp_[2] = ~ scan_fp_[2]; } while (0)
|
||||||
|
|
||||||
|
#define AND_HARD_REG_SET(TO, FROM) \
|
||||||
|
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
|
||||||
|
scan_tp_[0] &= scan_fp_[0]; \
|
||||||
|
scan_tp_[1] &= scan_fp_[1]; \
|
||||||
|
scan_tp_[2] &= scan_fp_[2]; } while (0)
|
||||||
|
|
||||||
|
#define AND_COMPL_HARD_REG_SET(TO, FROM) \
|
||||||
|
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
|
||||||
|
scan_tp_[0] &= ~ scan_fp_[0]; \
|
||||||
|
scan_tp_[1] &= ~ scan_fp_[1]; \
|
||||||
|
scan_tp_[2] &= ~ scan_fp_[2]; } while (0)
|
||||||
|
|
||||||
|
#define IOR_HARD_REG_SET(TO, FROM) \
|
||||||
|
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
|
||||||
|
scan_tp_[0] |= scan_fp_[0]; \
|
||||||
|
scan_tp_[1] |= scan_fp_[1]; \
|
||||||
|
scan_tp_[2] |= scan_fp_[2]; } while (0)
|
||||||
|
|
||||||
|
#define IOR_COMPL_HARD_REG_SET(TO, FROM) \
|
||||||
|
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
|
||||||
|
scan_tp_[0] |= ~ scan_fp_[0]; \
|
||||||
|
scan_tp_[1] |= ~ scan_fp_[1]; \
|
||||||
|
scan_tp_[2] |= ~ scan_fp_[2]; } while (0)
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
hard_reg_set_subset_p (const HARD_REG_SET x, const HARD_REG_SET y)
|
||||||
|
{
|
||||||
|
return ((x[0] & ~y[0]) == 0
|
||||||
|
&& (x[1] & ~y[1]) == 0
|
||||||
|
&& (x[2] & ~y[2]) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
hard_reg_set_equal_p (const HARD_REG_SET x, const HARD_REG_SET y)
|
||||||
|
{
|
||||||
|
return x[0] == y[0] && x[1] == y[1] && x[2] == y[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
hard_reg_set_intersect_p (const HARD_REG_SET x, const HARD_REG_SET y)
|
||||||
|
{
|
||||||
|
return ((x[0] & y[0]) != 0
|
||||||
|
|| (x[1] & y[1]) != 0
|
||||||
|
|| (x[2] & y[2]) != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
hard_reg_set_empty_p (const HARD_REG_SET x)
|
||||||
|
{
|
||||||
|
return x[0] == 0 && x[1] == 0 && x[2] == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
#if FIRST_PSEUDO_REGISTER <= 4*HOST_BITS_PER_WIDEST_FAST_INT
|
||||||
|
#define CLEAR_HARD_REG_SET(TO) \
|
||||||
|
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \
|
||||||
|
scan_tp_[0] = 0; \
|
||||||
|
scan_tp_[1] = 0; \
|
||||||
|
scan_tp_[2] = 0; \
|
||||||
|
scan_tp_[3] = 0; } while (0)
|
||||||
|
|
||||||
|
#define SET_HARD_REG_SET(TO) \
|
||||||
|
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \
|
||||||
|
scan_tp_[0] = -1; \
|
||||||
|
scan_tp_[1] = -1; \
|
||||||
|
scan_tp_[2] = -1; \
|
||||||
|
scan_tp_[3] = -1; } while (0)
|
||||||
|
|
||||||
|
#define COPY_HARD_REG_SET(TO, FROM) \
|
||||||
|
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
|
||||||
|
scan_tp_[0] = scan_fp_[0]; \
|
||||||
|
scan_tp_[1] = scan_fp_[1]; \
|
||||||
|
scan_tp_[2] = scan_fp_[2]; \
|
||||||
|
scan_tp_[3] = scan_fp_[3]; } while (0)
|
||||||
|
|
||||||
|
#define COMPL_HARD_REG_SET(TO, FROM) \
|
||||||
|
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
|
||||||
|
scan_tp_[0] = ~ scan_fp_[0]; \
|
||||||
|
scan_tp_[1] = ~ scan_fp_[1]; \
|
||||||
|
scan_tp_[2] = ~ scan_fp_[2]; \
|
||||||
|
scan_tp_[3] = ~ scan_fp_[3]; } while (0)
|
||||||
|
|
||||||
|
#define AND_HARD_REG_SET(TO, FROM) \
|
||||||
|
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
|
||||||
|
scan_tp_[0] &= scan_fp_[0]; \
|
||||||
|
scan_tp_[1] &= scan_fp_[1]; \
|
||||||
|
scan_tp_[2] &= scan_fp_[2]; \
|
||||||
|
scan_tp_[3] &= scan_fp_[3]; } while (0)
|
||||||
|
|
||||||
|
#define AND_COMPL_HARD_REG_SET(TO, FROM) \
|
||||||
|
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
|
||||||
|
scan_tp_[0] &= ~ scan_fp_[0]; \
|
||||||
|
scan_tp_[1] &= ~ scan_fp_[1]; \
|
||||||
|
scan_tp_[2] &= ~ scan_fp_[2]; \
|
||||||
|
scan_tp_[3] &= ~ scan_fp_[3]; } while (0)
|
||||||
|
|
||||||
|
#define IOR_HARD_REG_SET(TO, FROM) \
|
||||||
|
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
|
||||||
|
scan_tp_[0] |= scan_fp_[0]; \
|
||||||
|
scan_tp_[1] |= scan_fp_[1]; \
|
||||||
|
scan_tp_[2] |= scan_fp_[2]; \
|
||||||
|
scan_tp_[3] |= scan_fp_[3]; } while (0)
|
||||||
|
|
||||||
|
#define IOR_COMPL_HARD_REG_SET(TO, FROM) \
|
||||||
|
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
|
||||||
|
scan_tp_[0] |= ~ scan_fp_[0]; \
|
||||||
|
scan_tp_[1] |= ~ scan_fp_[1]; \
|
||||||
|
scan_tp_[2] |= ~ scan_fp_[2]; \
|
||||||
|
scan_tp_[3] |= ~ scan_fp_[3]; } while (0)
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
hard_reg_set_subset_p (const HARD_REG_SET x, const HARD_REG_SET y)
|
||||||
|
{
|
||||||
|
return ((x[0] & ~y[0]) == 0
|
||||||
|
&& (x[1] & ~y[1]) == 0
|
||||||
|
&& (x[2] & ~y[2]) == 0
|
||||||
|
&& (x[3] & ~y[3]) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
hard_reg_set_equal_p (const HARD_REG_SET x, const HARD_REG_SET y)
|
||||||
|
{
|
||||||
|
return x[0] == y[0] && x[1] == y[1] && x[2] == y[2] && x[3] == y[3];
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
hard_reg_set_intersect_p (const HARD_REG_SET x, const HARD_REG_SET y)
|
||||||
|
{
|
||||||
|
return ((x[0] & y[0]) != 0
|
||||||
|
|| (x[1] & y[1]) != 0
|
||||||
|
|| (x[2] & y[2]) != 0
|
||||||
|
|| (x[3] & y[3]) != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
hard_reg_set_empty_p (const HARD_REG_SET x)
|
||||||
|
{
|
||||||
|
return x[0] == 0 && x[1] == 0 && x[2] == 0 && x[3] == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* FIRST_PSEUDO_REGISTER > 4*HOST_BITS_PER_WIDEST_FAST_INT */
|
||||||
|
|
||||||
|
#define CLEAR_HARD_REG_SET(TO) \
|
||||||
|
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \
|
||||||
|
int i; \
|
||||||
|
for (i = 0; i < HARD_REG_SET_LONGS; i++) \
|
||||||
|
*scan_tp_++ = 0; } while (0)
|
||||||
|
|
||||||
|
#define SET_HARD_REG_SET(TO) \
|
||||||
|
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \
|
||||||
|
int i; \
|
||||||
|
for (i = 0; i < HARD_REG_SET_LONGS; i++) \
|
||||||
|
*scan_tp_++ = -1; } while (0)
|
||||||
|
|
||||||
|
#define COPY_HARD_REG_SET(TO, FROM) \
|
||||||
|
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
|
||||||
|
int i; \
|
||||||
|
for (i = 0; i < HARD_REG_SET_LONGS; i++) \
|
||||||
|
*scan_tp_++ = *scan_fp_++; } while (0)
|
||||||
|
|
||||||
|
#define COMPL_HARD_REG_SET(TO, FROM) \
|
||||||
|
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
|
||||||
|
int i; \
|
||||||
|
for (i = 0; i < HARD_REG_SET_LONGS; i++) \
|
||||||
|
*scan_tp_++ = ~ *scan_fp_++; } while (0)
|
||||||
|
|
||||||
|
#define AND_HARD_REG_SET(TO, FROM) \
|
||||||
|
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
|
||||||
|
int i; \
|
||||||
|
for (i = 0; i < HARD_REG_SET_LONGS; i++) \
|
||||||
|
*scan_tp_++ &= *scan_fp_++; } while (0)
|
||||||
|
|
||||||
|
#define AND_COMPL_HARD_REG_SET(TO, FROM) \
|
||||||
|
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
|
||||||
|
int i; \
|
||||||
|
for (i = 0; i < HARD_REG_SET_LONGS; i++) \
|
||||||
|
*scan_tp_++ &= ~ *scan_fp_++; } while (0)
|
||||||
|
|
||||||
|
#define IOR_HARD_REG_SET(TO, FROM) \
|
||||||
|
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
|
||||||
|
int i; \
|
||||||
|
for (i = 0; i < HARD_REG_SET_LONGS; i++) \
|
||||||
|
*scan_tp_++ |= *scan_fp_++; } while (0)
|
||||||
|
|
||||||
|
#define IOR_COMPL_HARD_REG_SET(TO, FROM) \
|
||||||
|
do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \
|
||||||
|
int i; \
|
||||||
|
for (i = 0; i < HARD_REG_SET_LONGS; i++) \
|
||||||
|
*scan_tp_++ |= ~ *scan_fp_++; } while (0)
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
hard_reg_set_subset_p (const HARD_REG_SET x, const HARD_REG_SET y)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < HARD_REG_SET_LONGS; i++)
|
||||||
|
if ((x[i] & ~y[i]) != 0)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
hard_reg_set_equal_p (const HARD_REG_SET x, const HARD_REG_SET y)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < HARD_REG_SET_LONGS; i++)
|
||||||
|
if (x[i] != y[i])
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
hard_reg_set_intersect_p (const HARD_REG_SET x, const HARD_REG_SET y)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < HARD_REG_SET_LONGS; i++)
|
||||||
|
if ((x[i] & y[i]) != 0)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
hard_reg_set_empty_p (const HARD_REG_SET x)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < HARD_REG_SET_LONGS; i++)
|
||||||
|
if (x[i] != 0)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Iterator for hard register sets. */
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
/* Pointer to the current element. */
|
||||||
|
HARD_REG_ELT_TYPE *pelt;
|
||||||
|
|
||||||
|
/* The length of the set. */
|
||||||
|
unsigned short length;
|
||||||
|
|
||||||
|
/* Word within the current element. */
|
||||||
|
unsigned short word_no;
|
||||||
|
|
||||||
|
/* Contents of the actually processed word. When finding next bit
|
||||||
|
it is shifted right, so that the actual bit is always the least
|
||||||
|
significant bit of ACTUAL. */
|
||||||
|
HARD_REG_ELT_TYPE bits;
|
||||||
|
} hard_reg_set_iterator;
|
||||||
|
|
||||||
|
#define HARD_REG_ELT_BITS UHOST_BITS_PER_WIDE_INT
|
||||||
|
|
||||||
|
/* The implementation of the iterator functions is fully analogous to
|
||||||
|
the bitmap iterators. */
|
||||||
|
static inline void
|
||||||
|
hard_reg_set_iter_init (hard_reg_set_iterator *iter, HARD_REG_SET set,
|
||||||
|
unsigned min, unsigned *regno)
|
||||||
|
{
|
||||||
|
#ifdef HARD_REG_SET_LONGS
|
||||||
|
iter->pelt = set;
|
||||||
|
iter->length = HARD_REG_SET_LONGS;
|
||||||
|
#else
|
||||||
|
iter->pelt = &set;
|
||||||
|
iter->length = 1;
|
||||||
|
#endif
|
||||||
|
iter->word_no = min / HARD_REG_ELT_BITS;
|
||||||
|
if (iter->word_no < iter->length)
|
||||||
|
{
|
||||||
|
iter->bits = iter->pelt[iter->word_no];
|
||||||
|
iter->bits >>= min % HARD_REG_ELT_BITS;
|
||||||
|
|
||||||
|
/* This is required for correct search of the next bit. */
|
||||||
|
min += !iter->bits;
|
||||||
|
}
|
||||||
|
*regno = min;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
hard_reg_set_iter_set (hard_reg_set_iterator *iter, unsigned *regno)
|
||||||
|
{
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
/* Return false when we're advanced past the end of the set. */
|
||||||
|
if (iter->word_no >= iter->length)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (iter->bits)
|
||||||
|
{
|
||||||
|
/* Find the correct bit and return it. */
|
||||||
|
while (!(iter->bits & 1))
|
||||||
|
{
|
||||||
|
iter->bits >>= 1;
|
||||||
|
*regno += 1;
|
||||||
|
}
|
||||||
|
return (*regno < FIRST_PSEUDO_REGISTER);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Round to the beginning of the next word. */
|
||||||
|
*regno = (*regno + HARD_REG_ELT_BITS - 1);
|
||||||
|
*regno -= *regno % HARD_REG_ELT_BITS;
|
||||||
|
|
||||||
|
/* Find the next non-zero word. */
|
||||||
|
while (++iter->word_no < iter->length)
|
||||||
|
{
|
||||||
|
iter->bits = iter->pelt[iter->word_no];
|
||||||
|
if (iter->bits)
|
||||||
|
break;
|
||||||
|
*regno += HARD_REG_ELT_BITS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
hard_reg_set_iter_next (hard_reg_set_iterator *iter, unsigned *regno)
|
||||||
|
{
|
||||||
|
iter->bits >>= 1;
|
||||||
|
*regno += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define EXECUTE_IF_SET_IN_HARD_REG_SET(SET, MIN, REGNUM, ITER) \
|
||||||
|
for (hard_reg_set_iter_init (&(ITER), (SET), (MIN), &(REGNUM)); \
|
||||||
|
hard_reg_set_iter_set (&(ITER), &(REGNUM)); \
|
||||||
|
hard_reg_set_iter_next (&(ITER), &(REGNUM)))
|
||||||
|
|
||||||
|
|
||||||
|
/* Define some standard sets of registers. */
|
||||||
|
|
||||||
|
/* Indexed by hard register number, contains 1 for registers
|
||||||
|
that are being used for global register decls.
|
||||||
|
These must be exempt from ordinary flow analysis
|
||||||
|
and are also considered fixed. */
|
||||||
|
|
||||||
|
extern char global_regs[FIRST_PSEUDO_REGISTER];
|
||||||
|
|
||||||
|
struct target_hard_regs {
|
||||||
|
/* The set of registers that actually exist on the current target. */
|
||||||
|
HARD_REG_SET x_accessible_reg_set;
|
||||||
|
|
||||||
|
/* The set of registers that should be considered to be register
|
||||||
|
operands. It is a subset of x_accessible_reg_set. */
|
||||||
|
HARD_REG_SET x_operand_reg_set;
|
||||||
|
|
||||||
|
/* Indexed by hard register number, contains 1 for registers
|
||||||
|
that are fixed use (stack pointer, pc, frame pointer, etc.;.
|
||||||
|
These are the registers that cannot be used to allocate
|
||||||
|
a pseudo reg whose life does not cross calls. */
|
||||||
|
char x_fixed_regs[FIRST_PSEUDO_REGISTER];
|
||||||
|
|
||||||
|
/* The same info as a HARD_REG_SET. */
|
||||||
|
HARD_REG_SET x_fixed_reg_set;
|
||||||
|
|
||||||
|
/* Indexed by hard register number, contains 1 for registers
|
||||||
|
that are fixed use or are clobbered by function calls.
|
||||||
|
These are the registers that cannot be used to allocate
|
||||||
|
a pseudo reg whose life crosses calls. */
|
||||||
|
char x_call_used_regs[FIRST_PSEUDO_REGISTER];
|
||||||
|
|
||||||
|
char x_call_really_used_regs[FIRST_PSEUDO_REGISTER];
|
||||||
|
|
||||||
|
/* The same info as a HARD_REG_SET. */
|
||||||
|
HARD_REG_SET x_call_used_reg_set;
|
||||||
|
|
||||||
|
/* Contains registers that are fixed use -- i.e. in fixed_reg_set -- or
|
||||||
|
a function value return register or TARGET_STRUCT_VALUE_RTX or
|
||||||
|
STATIC_CHAIN_REGNUM. These are the registers that cannot hold quantities
|
||||||
|
across calls even if we are willing to save and restore them. */
|
||||||
|
HARD_REG_SET x_call_fixed_reg_set;
|
||||||
|
|
||||||
|
/* Contains 1 for registers that are set or clobbered by calls. */
|
||||||
|
/* ??? Ideally, this would be just call_used_regs plus global_regs, but
|
||||||
|
for someone's bright idea to have call_used_regs strictly include
|
||||||
|
fixed_regs. Which leaves us guessing as to the set of fixed_regs
|
||||||
|
that are actually preserved. We know for sure that those associated
|
||||||
|
with the local stack frame are safe, but scant others. */
|
||||||
|
HARD_REG_SET x_regs_invalidated_by_call;
|
||||||
|
|
||||||
|
/* Call used hard registers which can not be saved because there is no
|
||||||
|
insn for this. */
|
||||||
|
HARD_REG_SET x_no_caller_save_reg_set;
|
||||||
|
|
||||||
|
/* Table of register numbers in the order in which to try to use them. */
|
||||||
|
int x_reg_alloc_order[FIRST_PSEUDO_REGISTER];
|
||||||
|
|
||||||
|
/* The inverse of reg_alloc_order. */
|
||||||
|
int x_inv_reg_alloc_order[FIRST_PSEUDO_REGISTER];
|
||||||
|
|
||||||
|
/* For each reg class, a HARD_REG_SET saying which registers are in it. */
|
||||||
|
HARD_REG_SET x_reg_class_contents[N_REG_CLASSES];
|
||||||
|
|
||||||
|
/* For each reg class, a boolean saying whether the class contains only
|
||||||
|
fixed registers. */
|
||||||
|
bool x_class_only_fixed_regs[N_REG_CLASSES];
|
||||||
|
|
||||||
|
/* For each reg class, number of regs it contains. */
|
||||||
|
unsigned int x_reg_class_size[N_REG_CLASSES];
|
||||||
|
|
||||||
|
/* For each reg class, table listing all the classes contained in it. */
|
||||||
|
enum reg_class x_reg_class_subclasses[N_REG_CLASSES][N_REG_CLASSES];
|
||||||
|
|
||||||
|
/* For each pair of reg classes,
|
||||||
|
a largest reg class contained in their union. */
|
||||||
|
enum reg_class x_reg_class_subunion[N_REG_CLASSES][N_REG_CLASSES];
|
||||||
|
|
||||||
|
/* For each pair of reg classes,
|
||||||
|
the smallest reg class that contains their union. */
|
||||||
|
enum reg_class x_reg_class_superunion[N_REG_CLASSES][N_REG_CLASSES];
|
||||||
|
|
||||||
|
/* Vector indexed by hardware reg giving its name. */
|
||||||
|
const char *x_reg_names[FIRST_PSEUDO_REGISTER];
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct target_hard_regs default_target_hard_regs;
|
||||||
|
#if SWITCHABLE_TARGET
|
||||||
|
extern struct target_hard_regs *this_target_hard_regs;
|
||||||
|
#else
|
||||||
|
#define this_target_hard_regs (&default_target_hard_regs)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define accessible_reg_set \
|
||||||
|
(this_target_hard_regs->x_accessible_reg_set)
|
||||||
|
#define operand_reg_set \
|
||||||
|
(this_target_hard_regs->x_operand_reg_set)
|
||||||
|
#define fixed_regs \
|
||||||
|
(this_target_hard_regs->x_fixed_regs)
|
||||||
|
#define fixed_reg_set \
|
||||||
|
(this_target_hard_regs->x_fixed_reg_set)
|
||||||
|
#define call_used_regs \
|
||||||
|
(this_target_hard_regs->x_call_used_regs)
|
||||||
|
#define call_really_used_regs \
|
||||||
|
(this_target_hard_regs->x_call_really_used_regs)
|
||||||
|
#define call_used_reg_set \
|
||||||
|
(this_target_hard_regs->x_call_used_reg_set)
|
||||||
|
#define call_fixed_reg_set \
|
||||||
|
(this_target_hard_regs->x_call_fixed_reg_set)
|
||||||
|
#define regs_invalidated_by_call \
|
||||||
|
(this_target_hard_regs->x_regs_invalidated_by_call)
|
||||||
|
#define no_caller_save_reg_set \
|
||||||
|
(this_target_hard_regs->x_no_caller_save_reg_set)
|
||||||
|
#define reg_alloc_order \
|
||||||
|
(this_target_hard_regs->x_reg_alloc_order)
|
||||||
|
#define inv_reg_alloc_order \
|
||||||
|
(this_target_hard_regs->x_inv_reg_alloc_order)
|
||||||
|
#define reg_class_contents \
|
||||||
|
(this_target_hard_regs->x_reg_class_contents)
|
||||||
|
#define class_only_fixed_regs \
|
||||||
|
(this_target_hard_regs->x_class_only_fixed_regs)
|
||||||
|
#define reg_class_size \
|
||||||
|
(this_target_hard_regs->x_reg_class_size)
|
||||||
|
#define reg_class_subclasses \
|
||||||
|
(this_target_hard_regs->x_reg_class_subclasses)
|
||||||
|
#define reg_class_subunion \
|
||||||
|
(this_target_hard_regs->x_reg_class_subunion)
|
||||||
|
#define reg_class_superunion \
|
||||||
|
(this_target_hard_regs->x_reg_class_superunion)
|
||||||
|
#define reg_names \
|
||||||
|
(this_target_hard_regs->x_reg_names)
|
||||||
|
|
||||||
|
/* Vector indexed by reg class giving its name. */
|
||||||
|
|
||||||
|
extern const char * reg_class_names[];
|
||||||
|
|
||||||
|
/* Given a hard REGN a FROM mode and a TO mode, return nonzero if
|
||||||
|
REGN cannot change modes between the specified modes. */
|
||||||
|
#define REG_CANNOT_CHANGE_MODE_P(REGN, FROM, TO) \
|
||||||
|
CANNOT_CHANGE_MODE_CLASS (FROM, TO, REGNO_REG_CLASS (REGN))
|
||||||
|
|
||||||
|
#endif /* ! GCC_HARD_REG_SET_H */
|
|
@ -0,0 +1,209 @@
|
||||||
|
/* An expandable hash tables datatype.
|
||||||
|
Copyright (C) 1999, 2000, 2002, 2003, 2004, 2005, 2009, 2010
|
||||||
|
Free Software Foundation, Inc.
|
||||||
|
Contributed by Vladimir Makarov (vmakarov@cygnus.com).
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||||
|
|
||||||
|
/* This package implements basic hash table functionality. It is possible
|
||||||
|
to search for an entry, create an entry and destroy an entry.
|
||||||
|
|
||||||
|
Elements in the table are generic pointers.
|
||||||
|
|
||||||
|
The size of the table is not fixed; if the occupancy of the table
|
||||||
|
grows too high the hash table will be expanded.
|
||||||
|
|
||||||
|
The abstract data implementation is based on generalized Algorithm D
|
||||||
|
from Knuth's book "The art of computer programming". Hash table is
|
||||||
|
expanded by creation of new hash table and transferring elements from
|
||||||
|
the old table to the new table. */
|
||||||
|
|
||||||
|
#ifndef __HASHTAB_H__
|
||||||
|
#define __HASHTAB_H__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
|
#include "ansidecl.h"
|
||||||
|
|
||||||
|
#ifndef GTY
|
||||||
|
#define GTY(X)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* The type for a hash code. */
|
||||||
|
typedef unsigned int hashval_t;
|
||||||
|
|
||||||
|
/* Callback function pointer types. */
|
||||||
|
|
||||||
|
/* Calculate hash of a table entry. */
|
||||||
|
typedef hashval_t (*htab_hash) (const void *);
|
||||||
|
|
||||||
|
/* Compare a table entry with a possible entry. The entry already in
|
||||||
|
the table always comes first, so the second element can be of a
|
||||||
|
different type (but in this case htab_find and htab_find_slot
|
||||||
|
cannot be used; instead the variants that accept a hash value
|
||||||
|
must be used). */
|
||||||
|
typedef int (*htab_eq) (const void *, const void *);
|
||||||
|
|
||||||
|
/* Cleanup function called whenever a live element is removed from
|
||||||
|
the hash table. */
|
||||||
|
typedef void (*htab_del) (void *);
|
||||||
|
|
||||||
|
/* Function called by htab_traverse for each live element. The first
|
||||||
|
arg is the slot of the element (which can be passed to htab_clear_slot
|
||||||
|
if desired), the second arg is the auxiliary pointer handed to
|
||||||
|
htab_traverse. Return 1 to continue scan, 0 to stop. */
|
||||||
|
typedef int (*htab_trav) (void **, void *);
|
||||||
|
|
||||||
|
/* Memory-allocation function, with the same functionality as calloc().
|
||||||
|
Iff it returns NULL, the hash table implementation will pass an error
|
||||||
|
code back to the user, so if your code doesn't handle errors,
|
||||||
|
best if you use xcalloc instead. */
|
||||||
|
typedef void *(*htab_alloc) (size_t, size_t);
|
||||||
|
|
||||||
|
/* We also need a free() routine. */
|
||||||
|
typedef void (*htab_free) (void *);
|
||||||
|
|
||||||
|
/* Memory allocation and deallocation; variants which take an extra
|
||||||
|
argument. */
|
||||||
|
typedef void *(*htab_alloc_with_arg) (void *, size_t, size_t);
|
||||||
|
typedef void (*htab_free_with_arg) (void *, void *);
|
||||||
|
|
||||||
|
/* This macro defines reserved value for empty table entry. */
|
||||||
|
|
||||||
|
#define HTAB_EMPTY_ENTRY ((PTR) 0)
|
||||||
|
|
||||||
|
/* This macro defines reserved value for table entry which contained
|
||||||
|
a deleted element. */
|
||||||
|
|
||||||
|
#define HTAB_DELETED_ENTRY ((PTR) 1)
|
||||||
|
|
||||||
|
/* Hash tables are of the following type. The structure
|
||||||
|
(implementation) of this type is not needed for using the hash
|
||||||
|
tables. All work with hash table should be executed only through
|
||||||
|
functions mentioned below. The size of this structure is subject to
|
||||||
|
change. */
|
||||||
|
|
||||||
|
struct GTY(()) htab {
|
||||||
|
/* Pointer to hash function. */
|
||||||
|
htab_hash hash_f;
|
||||||
|
|
||||||
|
/* Pointer to comparison function. */
|
||||||
|
htab_eq eq_f;
|
||||||
|
|
||||||
|
/* Pointer to cleanup function. */
|
||||||
|
htab_del del_f;
|
||||||
|
|
||||||
|
/* Table itself. */
|
||||||
|
void ** GTY ((use_param, length ("%h.size"))) entries;
|
||||||
|
|
||||||
|
/* Current size (in entries) of the hash table. */
|
||||||
|
size_t size;
|
||||||
|
|
||||||
|
/* Current number of elements including also deleted elements. */
|
||||||
|
size_t n_elements;
|
||||||
|
|
||||||
|
/* Current number of deleted elements in the table. */
|
||||||
|
size_t n_deleted;
|
||||||
|
|
||||||
|
/* The following member is used for debugging. Its value is number
|
||||||
|
of all calls of `htab_find_slot' for the hash table. */
|
||||||
|
unsigned int searches;
|
||||||
|
|
||||||
|
/* The following member is used for debugging. Its value is number
|
||||||
|
of collisions fixed for time of work with the hash table. */
|
||||||
|
unsigned int collisions;
|
||||||
|
|
||||||
|
/* Pointers to allocate/free functions. */
|
||||||
|
htab_alloc alloc_f;
|
||||||
|
htab_free free_f;
|
||||||
|
|
||||||
|
/* Alternate allocate/free functions, which take an extra argument. */
|
||||||
|
void * GTY((skip)) alloc_arg;
|
||||||
|
htab_alloc_with_arg alloc_with_arg_f;
|
||||||
|
htab_free_with_arg free_with_arg_f;
|
||||||
|
|
||||||
|
/* Current size (in entries) of the hash table, as an index into the
|
||||||
|
table of primes. */
|
||||||
|
unsigned int size_prime_index;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct htab *htab_t;
|
||||||
|
|
||||||
|
/* An enum saying whether we insert into the hash table or not. */
|
||||||
|
enum insert_option {NO_INSERT, INSERT};
|
||||||
|
|
||||||
|
/* The prototypes of the package functions. */
|
||||||
|
|
||||||
|
extern htab_t htab_create_alloc (size_t, htab_hash,
|
||||||
|
htab_eq, htab_del,
|
||||||
|
htab_alloc, htab_free);
|
||||||
|
|
||||||
|
extern htab_t htab_create_alloc_ex (size_t, htab_hash,
|
||||||
|
htab_eq, htab_del,
|
||||||
|
void *, htab_alloc_with_arg,
|
||||||
|
htab_free_with_arg);
|
||||||
|
|
||||||
|
extern htab_t htab_create_typed_alloc (size_t, htab_hash, htab_eq, htab_del,
|
||||||
|
htab_alloc, htab_alloc, htab_free);
|
||||||
|
|
||||||
|
/* Backward-compatibility functions. */
|
||||||
|
extern htab_t htab_create (size_t, htab_hash, htab_eq, htab_del);
|
||||||
|
extern htab_t htab_try_create (size_t, htab_hash, htab_eq, htab_del);
|
||||||
|
|
||||||
|
extern void htab_set_functions_ex (htab_t, htab_hash,
|
||||||
|
htab_eq, htab_del,
|
||||||
|
void *, htab_alloc_with_arg,
|
||||||
|
htab_free_with_arg);
|
||||||
|
|
||||||
|
extern void htab_delete (htab_t);
|
||||||
|
extern void htab_empty (htab_t);
|
||||||
|
|
||||||
|
extern void * htab_find (htab_t, const void *);
|
||||||
|
extern void ** htab_find_slot (htab_t, const void *, enum insert_option);
|
||||||
|
extern void * htab_find_with_hash (htab_t, const void *, hashval_t);
|
||||||
|
extern void ** htab_find_slot_with_hash (htab_t, const void *,
|
||||||
|
hashval_t, enum insert_option);
|
||||||
|
extern void htab_clear_slot (htab_t, void **);
|
||||||
|
extern void htab_remove_elt (htab_t, void *);
|
||||||
|
extern void htab_remove_elt_with_hash (htab_t, void *, hashval_t);
|
||||||
|
|
||||||
|
extern void htab_traverse (htab_t, htab_trav, void *);
|
||||||
|
extern void htab_traverse_noresize (htab_t, htab_trav, void *);
|
||||||
|
|
||||||
|
extern size_t htab_size (htab_t);
|
||||||
|
extern size_t htab_elements (htab_t);
|
||||||
|
extern double htab_collisions (htab_t);
|
||||||
|
|
||||||
|
/* A hash function for pointers. */
|
||||||
|
extern htab_hash htab_hash_pointer;
|
||||||
|
|
||||||
|
/* An equality function for pointers. */
|
||||||
|
extern htab_eq htab_eq_pointer;
|
||||||
|
|
||||||
|
/* A hash function for null-terminated strings. */
|
||||||
|
extern hashval_t htab_hash_string (const void *);
|
||||||
|
|
||||||
|
/* An iterative hash function for arbitrary data. */
|
||||||
|
extern hashval_t iterative_hash (const void *, size_t, hashval_t);
|
||||||
|
/* Shorthand for hashing something with an intrinsic size. */
|
||||||
|
#define iterative_hash_object(OB,INIT) iterative_hash (&OB, sizeof (OB), INIT)
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
|
#endif /* __HASHTAB_H */
|
|
@ -0,0 +1,33 @@
|
||||||
|
/* Interface for high-level plugins in GCC - Parts common between GCC,
|
||||||
|
ICI and high-level plugins.
|
||||||
|
|
||||||
|
Copyright (C) 2009-2013 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
Contributed by INRIA.
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free
|
||||||
|
Software Foundation; either version 3, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GCC; see the file COPYING3. If not see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#ifndef HIGHLEV_PLUGIN_COMMON_H
|
||||||
|
#define HIGHLEV_PLUGIN_COMMON_H
|
||||||
|
|
||||||
|
/* Return codes for invoke_plugin_callbacks / call_plugin_event . */
|
||||||
|
#define PLUGEVT_SUCCESS 0
|
||||||
|
#define PLUGEVT_NO_EVENTS 1
|
||||||
|
#define PLUGEVT_NO_SUCH_EVENT 2
|
||||||
|
#define PLUGEVT_NO_CALLBACK 3
|
||||||
|
|
||||||
|
#endif /* HIGHLEV_PLUGIN_COMMON_H */
|
|
@ -0,0 +1,279 @@
|
||||||
|
/* HOST_WIDE_INT definitions for the GNU compiler.
|
||||||
|
Copyright (C) 1998-2013 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
Provide definitions for macros which depend on HOST_BITS_PER_INT
|
||||||
|
and HOST_BITS_PER_LONG. */
|
||||||
|
|
||||||
|
#ifndef GCC_HWINT_H
|
||||||
|
#define GCC_HWINT_H
|
||||||
|
|
||||||
|
/* This describes the machine the compiler is hosted on. */
|
||||||
|
#define HOST_BITS_PER_CHAR CHAR_BIT
|
||||||
|
#define HOST_BITS_PER_SHORT (CHAR_BIT * SIZEOF_SHORT)
|
||||||
|
#define HOST_BITS_PER_INT (CHAR_BIT * SIZEOF_INT)
|
||||||
|
#define HOST_BITS_PER_LONG (CHAR_BIT * SIZEOF_LONG)
|
||||||
|
|
||||||
|
/* The string that should be inserted into a printf style format to
|
||||||
|
indicate a "long" operand. */
|
||||||
|
#ifndef HOST_LONG_FORMAT
|
||||||
|
#define HOST_LONG_FORMAT "l"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* The string that should be inserted into a printf style format to
|
||||||
|
indicate a "long long" operand. */
|
||||||
|
#ifndef HOST_LONG_LONG_FORMAT
|
||||||
|
#define HOST_LONG_LONG_FORMAT "ll"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* If HAVE_LONG_LONG and SIZEOF_LONG_LONG aren't defined, but
|
||||||
|
GCC_VERSION >= 3000, assume this is the second or later stage of a
|
||||||
|
bootstrap, we do have long long, and it's 64 bits. (This is
|
||||||
|
required by C99; we do have some ports that violate that assumption
|
||||||
|
but they're all cross-compile-only.) Just in case, force a
|
||||||
|
constraint violation if that assumption is incorrect. */
|
||||||
|
#if !defined HAVE_LONG_LONG
|
||||||
|
# if GCC_VERSION >= 3000
|
||||||
|
# define HAVE_LONG_LONG 1
|
||||||
|
# define SIZEOF_LONG_LONG 8
|
||||||
|
extern char sizeof_long_long_must_be_8[sizeof(long long) == 8 ? 1 : -1];
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_LONG_LONG
|
||||||
|
# define HOST_BITS_PER_LONGLONG (CHAR_BIT * SIZEOF_LONG_LONG)
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE___INT64
|
||||||
|
# define HOST_BITS_PER___INT64 (CHAR_BIT * SIZEOF___INT64)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Set HOST_WIDE_INT. This should be the widest efficient host
|
||||||
|
integer type. It can be 32 or 64 bits, except that if we are
|
||||||
|
targeting a machine with 64-bit size_t then it has to be 64 bits.
|
||||||
|
|
||||||
|
With a sane ABI, 'long' is the largest efficient host integer type.
|
||||||
|
Thus, we use that unless we have to use 'long long' or '__int64'
|
||||||
|
because we're targeting a 64-bit machine from a 32-bit host. */
|
||||||
|
|
||||||
|
#if HOST_BITS_PER_LONG >= 64 || !defined NEED_64BIT_HOST_WIDE_INT
|
||||||
|
# define HOST_BITS_PER_WIDE_INT HOST_BITS_PER_LONG
|
||||||
|
# define HOST_WIDE_INT long
|
||||||
|
# define HOST_WIDE_INT_C(X) X ## L
|
||||||
|
#else
|
||||||
|
# if HOST_BITS_PER_LONGLONG >= 64
|
||||||
|
# define HOST_BITS_PER_WIDE_INT HOST_BITS_PER_LONGLONG
|
||||||
|
# define HOST_WIDE_INT long long
|
||||||
|
# define HOST_WIDE_INT_C(X) X ## LL
|
||||||
|
# else
|
||||||
|
# if HOST_BITS_PER___INT64 >= 64
|
||||||
|
# define HOST_BITS_PER_WIDE_INT HOST_BITS_PER___INT64
|
||||||
|
# define HOST_WIDE_INT __int64
|
||||||
|
# define HOST_WIDE_INT_C(X) X ## i64
|
||||||
|
# else
|
||||||
|
#error "Unable to find a suitable type for HOST_WIDE_INT"
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define HOST_WIDE_INT_1 HOST_WIDE_INT_C(1)
|
||||||
|
|
||||||
|
/* This is a magic identifier which allows GCC to figure out the type
|
||||||
|
of HOST_WIDE_INT for %wd specifier checks. You must issue this
|
||||||
|
typedef before using the __asm_fprintf__ format attribute. */
|
||||||
|
typedef HOST_WIDE_INT __gcc_host_wide_int__;
|
||||||
|
|
||||||
|
/* Various printf format strings for HOST_WIDE_INT. */
|
||||||
|
|
||||||
|
#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG
|
||||||
|
# define HOST_WIDE_INT_PRINT HOST_LONG_FORMAT
|
||||||
|
# define HOST_WIDE_INT_PRINT_C "L"
|
||||||
|
/* 'long' might be 32 or 64 bits, and the number of leading zeroes
|
||||||
|
must be tweaked accordingly. */
|
||||||
|
# if HOST_BITS_PER_WIDE_INT == 64
|
||||||
|
# define HOST_WIDE_INT_PRINT_DOUBLE_HEX \
|
||||||
|
"0x%" HOST_LONG_FORMAT "x%016" HOST_LONG_FORMAT "x"
|
||||||
|
# else
|
||||||
|
# define HOST_WIDE_INT_PRINT_DOUBLE_HEX \
|
||||||
|
"0x%" HOST_LONG_FORMAT "x%08" HOST_LONG_FORMAT "x"
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
# define HOST_WIDE_INT_PRINT HOST_LONG_LONG_FORMAT
|
||||||
|
# define HOST_WIDE_INT_PRINT_C "LL"
|
||||||
|
/* We can assume that 'long long' is at least 64 bits. */
|
||||||
|
# define HOST_WIDE_INT_PRINT_DOUBLE_HEX \
|
||||||
|
"0x%" HOST_LONG_LONG_FORMAT "x%016" HOST_LONG_LONG_FORMAT "x"
|
||||||
|
#endif /* HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG */
|
||||||
|
|
||||||
|
#define HOST_WIDE_INT_PRINT_DEC "%" HOST_WIDE_INT_PRINT "d"
|
||||||
|
#define HOST_WIDE_INT_PRINT_DEC_C HOST_WIDE_INT_PRINT_DEC HOST_WIDE_INT_PRINT_C
|
||||||
|
#define HOST_WIDE_INT_PRINT_UNSIGNED "%" HOST_WIDE_INT_PRINT "u"
|
||||||
|
#define HOST_WIDE_INT_PRINT_HEX "%#" HOST_WIDE_INT_PRINT "x"
|
||||||
|
#define HOST_WIDE_INT_PRINT_HEX_PURE "%" HOST_WIDE_INT_PRINT "x"
|
||||||
|
|
||||||
|
/* Set HOST_WIDEST_INT. This is a 64-bit type unless the compiler
|
||||||
|
in use has no 64-bit type at all; in that case it's 32 bits. */
|
||||||
|
|
||||||
|
#if HOST_BITS_PER_WIDE_INT >= 64 \
|
||||||
|
|| (HOST_BITS_PER_LONGLONG < 64 && HOST_BITS_PER___INT64 < 64)
|
||||||
|
# define HOST_WIDEST_INT HOST_WIDE_INT
|
||||||
|
# define HOST_BITS_PER_WIDEST_INT HOST_BITS_PER_WIDE_INT
|
||||||
|
# define HOST_WIDEST_INT_PRINT HOST_WIDE_INT_PRINT
|
||||||
|
# define HOST_WIDEST_INT_PRINT_DEC HOST_WIDE_INT_PRINT_DEC
|
||||||
|
# define HOST_WIDEST_INT_PRINT_DEC_C HOST_WIDE_INT_PRINT_DEC_C
|
||||||
|
# define HOST_WIDEST_INT_PRINT_UNSIGNED HOST_WIDE_INT_PRINT_UNSIGNED
|
||||||
|
# define HOST_WIDEST_INT_PRINT_HEX HOST_WIDE_INT_PRINT_HEX
|
||||||
|
# define HOST_WIDEST_INT_PRINT_DOUBLE_HEX HOST_WIDE_INT_PRINT_DOUBLE_HEX
|
||||||
|
# define HOST_WIDEST_INT_C(X) HOST_WIDE_INT(X)
|
||||||
|
#else
|
||||||
|
# if HOST_BITS_PER_LONGLONG >= 64
|
||||||
|
# define HOST_BITS_PER_WIDEST_INT HOST_BITS_PER_LONGLONG
|
||||||
|
# define HOST_WIDEST_INT long long
|
||||||
|
# define HOST_WIDEST_INT_C(X) X ## LL
|
||||||
|
# else
|
||||||
|
# if HOST_BITS_PER___INT64 >= 64
|
||||||
|
# define HOST_BITS_PER_WIDEST_INT HOST_BITS_PER___INT64
|
||||||
|
# define HOST_WIDEST_INT __int64
|
||||||
|
# define HOST_WIDEST_INT_C(X) X ## i64
|
||||||
|
# else
|
||||||
|
#error "This line should be impossible to reach"
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
# define HOST_WIDEST_INT_PRINT HOST_LONG_LONG_FORMAT
|
||||||
|
# define HOST_WIDEST_INT_PRINT_DEC "%" HOST_LONG_LONG_FORMAT "d"
|
||||||
|
# define HOST_WIDEST_INT_PRINT_DEC_C "%" HOST_LONG_LONG_FORMAT "dLL"
|
||||||
|
# define HOST_WIDEST_INT_PRINT_UNSIGNED "%" HOST_LONG_LONG_FORMAT "u"
|
||||||
|
# define HOST_WIDEST_INT_PRINT_HEX "%#" HOST_LONG_LONG_FORMAT "x"
|
||||||
|
# define HOST_WIDEST_INT_PRINT_DOUBLE_HEX \
|
||||||
|
"0x%" HOST_LONG_LONG_FORMAT "x%016" HOST_LONG_LONG_FORMAT "x"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Define HOST_WIDEST_FAST_INT to the widest integer type supported
|
||||||
|
efficiently in hardware. (That is, the widest integer type that fits
|
||||||
|
in a hardware register.) Normally this is "long" but on some hosts it
|
||||||
|
should be "long long" or "__int64". This is no convenient way to
|
||||||
|
autodetect this, so such systems must set a flag in config.host; see there
|
||||||
|
for details. */
|
||||||
|
|
||||||
|
#ifdef USE_LONG_LONG_FOR_WIDEST_FAST_INT
|
||||||
|
# ifdef HAVE_LONG_LONG
|
||||||
|
# define HOST_WIDEST_FAST_INT long long
|
||||||
|
# define HOST_BITS_PER_WIDEST_FAST_INT HOST_BITS_PER_LONGLONG
|
||||||
|
# elif defined (HAVE___INT64)
|
||||||
|
# define HOST_WIDEST_FAST_INT __int64
|
||||||
|
# define HOST_BITS_PER_WIDEST_FAST_INT HOST_BITS_PER___INT64
|
||||||
|
# else
|
||||||
|
# error "Your host said it wanted to use long long or __int64 but neither"
|
||||||
|
# error "exist"
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
# define HOST_WIDEST_FAST_INT long
|
||||||
|
# define HOST_BITS_PER_WIDEST_FAST_INT HOST_BITS_PER_LONG
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Inline functions operating on HOST_WIDE_INT. */
|
||||||
|
#if GCC_VERSION < 3004
|
||||||
|
|
||||||
|
extern int clz_hwi (unsigned HOST_WIDE_INT x);
|
||||||
|
extern int ctz_hwi (unsigned HOST_WIDE_INT x);
|
||||||
|
extern int ffs_hwi (unsigned HOST_WIDE_INT x);
|
||||||
|
|
||||||
|
/* Return the number of set bits in X. */
|
||||||
|
extern int popcount_hwi (unsigned HOST_WIDE_INT x);
|
||||||
|
|
||||||
|
/* Return log2, or -1 if not exact. */
|
||||||
|
extern int exact_log2 (unsigned HOST_WIDE_INT);
|
||||||
|
|
||||||
|
/* Return floor of log2, with -1 for zero. */
|
||||||
|
extern int floor_log2 (unsigned HOST_WIDE_INT);
|
||||||
|
|
||||||
|
/* Return the smallest n such that 2**n >= X. */
|
||||||
|
extern int ceil_log2 (unsigned HOST_WIDE_INT);
|
||||||
|
|
||||||
|
#else /* GCC_VERSION >= 3004 */
|
||||||
|
|
||||||
|
/* For convenience, define 0 -> word_size. */
|
||||||
|
static inline int
|
||||||
|
clz_hwi (unsigned HOST_WIDE_INT x)
|
||||||
|
{
|
||||||
|
if (x == 0)
|
||||||
|
return HOST_BITS_PER_WIDE_INT;
|
||||||
|
# if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG
|
||||||
|
return __builtin_clzl (x);
|
||||||
|
# elif HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONGLONG
|
||||||
|
return __builtin_clzll (x);
|
||||||
|
# else
|
||||||
|
return __builtin_clz (x);
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
ctz_hwi (unsigned HOST_WIDE_INT x)
|
||||||
|
{
|
||||||
|
if (x == 0)
|
||||||
|
return HOST_BITS_PER_WIDE_INT;
|
||||||
|
# if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG
|
||||||
|
return __builtin_ctzl (x);
|
||||||
|
# elif HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONGLONG
|
||||||
|
return __builtin_ctzll (x);
|
||||||
|
# else
|
||||||
|
return __builtin_ctz (x);
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
ffs_hwi (unsigned HOST_WIDE_INT x)
|
||||||
|
{
|
||||||
|
# if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG
|
||||||
|
return __builtin_ffsl (x);
|
||||||
|
# elif HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONGLONG
|
||||||
|
return __builtin_ffsll (x);
|
||||||
|
# else
|
||||||
|
return __builtin_ffs (x);
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
popcount_hwi (unsigned HOST_WIDE_INT x)
|
||||||
|
{
|
||||||
|
# if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG
|
||||||
|
return __builtin_popcountl (x);
|
||||||
|
# elif HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONGLONG
|
||||||
|
return __builtin_popcountll (x);
|
||||||
|
# else
|
||||||
|
return __builtin_popcount (x);
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
floor_log2 (unsigned HOST_WIDE_INT x)
|
||||||
|
{
|
||||||
|
return HOST_BITS_PER_WIDE_INT - 1 - clz_hwi (x);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
ceil_log2 (unsigned HOST_WIDE_INT x)
|
||||||
|
{
|
||||||
|
return floor_log2 (x - 1) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
exact_log2 (unsigned HOST_WIDE_INT x)
|
||||||
|
{
|
||||||
|
return x == (x & -x) && x ? ctz_hwi (x) : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* GCC_VERSION >= 3004 */
|
||||||
|
|
||||||
|
#define HOST_WIDE_INT_MIN (HOST_WIDE_INT) \
|
||||||
|
((unsigned HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT - 1))
|
||||||
|
#define HOST_WIDE_INT_MAX (~(HOST_WIDE_INT_MIN))
|
||||||
|
|
||||||
|
extern HOST_WIDE_INT abs_hwi (HOST_WIDE_INT);
|
||||||
|
extern unsigned HOST_WIDE_INT absu_hwi (HOST_WIDE_INT);
|
||||||
|
extern HOST_WIDE_INT gcd (HOST_WIDE_INT, HOST_WIDE_INT);
|
||||||
|
extern HOST_WIDE_INT pos_mul_hwi (HOST_WIDE_INT, HOST_WIDE_INT);
|
||||||
|
extern HOST_WIDE_INT mul_hwi (HOST_WIDE_INT, HOST_WIDE_INT);
|
||||||
|
extern HOST_WIDE_INT least_common_multiple (HOST_WIDE_INT, HOST_WIDE_INT);
|
||||||
|
|
||||||
|
#endif /* ! GCC_HWINT_H */
|
|
@ -0,0 +1,34 @@
|
||||||
|
/* Set up combined include path for the preprocessor.
|
||||||
|
Copyright (C) 2003-2013 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by the
|
||||||
|
Free Software Foundation; either version 3, or (at your option) any
|
||||||
|
later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; see the file COPYING3. If not see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
extern void split_quote_chain (void);
|
||||||
|
extern void add_path (char *, int, int, bool);
|
||||||
|
extern void register_include_chains (cpp_reader *, const char *,
|
||||||
|
const char *, const char *,
|
||||||
|
int, int, int);
|
||||||
|
extern void add_cpp_dir_path (struct cpp_dir *, int);
|
||||||
|
extern struct cpp_dir *get_added_cpp_dirs (int);
|
||||||
|
|
||||||
|
struct target_c_incpath_s {
|
||||||
|
/* Do extra includes processing. STDINC is false iff -nostdinc was given. */
|
||||||
|
void (*extra_pre_includes) (const char *, const char *, int);
|
||||||
|
void (*extra_includes) (const char *, const char *, int);
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct target_c_incpath_s target_c_incpath;
|
||||||
|
|
||||||
|
enum { QUOTE = 0, BRACKET, SYSTEM, AFTER };
|
|
@ -0,0 +1,67 @@
|
||||||
|
/* Declarations for variables relating to reading the source file.
|
||||||
|
Used by parsers, lexical analyzers, and error message routines.
|
||||||
|
Copyright (C) 1993-2013 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free
|
||||||
|
Software Foundation; either version 3, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GCC; see the file COPYING3. If not see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#ifndef GCC_INPUT_H
|
||||||
|
#define GCC_INPUT_H
|
||||||
|
|
||||||
|
#include "line-map.h"
|
||||||
|
|
||||||
|
extern GTY(()) struct line_maps *line_table;
|
||||||
|
|
||||||
|
/* A value which will never be used to represent a real location. */
|
||||||
|
#define UNKNOWN_LOCATION ((source_location) 0)
|
||||||
|
|
||||||
|
/* The location for declarations in "<built-in>" */
|
||||||
|
#define BUILTINS_LOCATION ((source_location) 1)
|
||||||
|
|
||||||
|
/* line-map.c reserves RESERVED_LOCATION_COUNT to the user. Ensure
|
||||||
|
both UNKNOWN_LOCATION and BUILTINS_LOCATION fit into that. */
|
||||||
|
extern char builtins_location_check[(BUILTINS_LOCATION
|
||||||
|
< RESERVED_LOCATION_COUNT) ? 1 : -1];
|
||||||
|
|
||||||
|
extern expanded_location expand_location (source_location);
|
||||||
|
extern const char * location_get_source_line(expanded_location xloc);
|
||||||
|
extern expanded_location expand_location_to_spelling_point (source_location);
|
||||||
|
extern source_location expansion_point_location_if_in_system_header (source_location);
|
||||||
|
|
||||||
|
/* Historically GCC used location_t, while cpp used source_location.
|
||||||
|
This could be removed but it hardly seems worth the effort. */
|
||||||
|
typedef source_location location_t;
|
||||||
|
|
||||||
|
extern location_t input_location;
|
||||||
|
|
||||||
|
#define LOCATION_FILE(LOC) ((expand_location (LOC)).file)
|
||||||
|
#define LOCATION_LINE(LOC) ((expand_location (LOC)).line)
|
||||||
|
#define LOCATION_COLUMN(LOC)((expand_location (LOC)).column)
|
||||||
|
#define LOCATION_LOCUS(LOC) \
|
||||||
|
((IS_ADHOC_LOC(LOC)) ? get_location_from_adhoc_loc (line_table, LOC) : (LOC))
|
||||||
|
#define LOCATION_BLOCK(LOC) \
|
||||||
|
((tree) ((IS_ADHOC_LOC (LOC)) ? get_data_from_adhoc_loc (line_table, (LOC)) \
|
||||||
|
: NULL))
|
||||||
|
|
||||||
|
#define input_line LOCATION_LINE (input_location)
|
||||||
|
#define input_filename LOCATION_FILE (input_location)
|
||||||
|
#define in_system_header_at(LOC) \
|
||||||
|
((linemap_location_in_system_header_p (line_table, LOC)))
|
||||||
|
#define in_system_header (in_system_header_at (input_location))
|
||||||
|
|
||||||
|
void dump_line_table_statistics (void);
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,279 @@
|
||||||
|
/* Generated automatically by the program `genconstants'
|
||||||
|
from the machine description file `md'. */
|
||||||
|
|
||||||
|
#ifndef GCC_INSN_CONSTANTS_H
|
||||||
|
#define GCC_INSN_CONSTANTS_H
|
||||||
|
|
||||||
|
#define XMM9_REG 46
|
||||||
|
#define R13_REG 42
|
||||||
|
#define XMM14_REG 51
|
||||||
|
#define ROUND_CEIL 0x2
|
||||||
|
#define PCOM_TRUE 1
|
||||||
|
#define PPERM_SRC 0x00
|
||||||
|
#define PPERM_ZERO 0x80
|
||||||
|
#define MM7_REG 36
|
||||||
|
#define XMM6_REG 27
|
||||||
|
#define ST3_REG 11
|
||||||
|
#define R10_REG 39
|
||||||
|
#define XMM11_REG 48
|
||||||
|
#define FLAGS_REG 17
|
||||||
|
#define ST1_REG 9
|
||||||
|
#define MM4_REG 33
|
||||||
|
#define COM_FALSE_P 3
|
||||||
|
#define XMM3_REG 24
|
||||||
|
#define ST0_REG 8
|
||||||
|
#define COM_FALSE_S 2
|
||||||
|
#define SP_REG 7
|
||||||
|
#define AX_REG 0
|
||||||
|
#define ROUND_NO_EXC 0x8
|
||||||
|
#define R8_REG 37
|
||||||
|
#define XMM0_REG 21
|
||||||
|
#define XMM8_REG 45
|
||||||
|
#define ST5_REG 13
|
||||||
|
#define R12_REG 41
|
||||||
|
#define R9_REG 38
|
||||||
|
#define ROUND_MXCSR 0x4
|
||||||
|
#define PCOM_FALSE 0
|
||||||
|
#define FPSR_REG 18
|
||||||
|
#define PPERM_INVERT 0x20
|
||||||
|
#define MM6_REG 35
|
||||||
|
#define MM1_REG 30
|
||||||
|
#define PPERM_SRC1 0x00
|
||||||
|
#define PPERM_SRC2 0x10
|
||||||
|
#define XMM5_REG 26
|
||||||
|
#define ST2_REG 10
|
||||||
|
#define XMM10_REG 47
|
||||||
|
#define ROUND_TRUNC 0x3
|
||||||
|
#define DI_REG 5
|
||||||
|
#define DX_REG 1
|
||||||
|
#define MM3_REG 32
|
||||||
|
#define XMM12_REG 49
|
||||||
|
#define COM_TRUE_P 5
|
||||||
|
#define XMM4_REG 25
|
||||||
|
#define COM_TRUE_S 4
|
||||||
|
#define ROUND_FLOOR 0x1
|
||||||
|
#define ST6_REG 14
|
||||||
|
#define ST7_REG 15
|
||||||
|
#define R14_REG 43
|
||||||
|
#define XMM15_REG 52
|
||||||
|
#define R15_REG 44
|
||||||
|
#define XMM13_REG 50
|
||||||
|
#define PPERM_SIGN 0xc0
|
||||||
|
#define MM0_REG 29
|
||||||
|
#define BP_REG 6
|
||||||
|
#define BX_REG 3
|
||||||
|
#define XMM7_REG 28
|
||||||
|
#define ST4_REG 12
|
||||||
|
#define PPERM_INV_SIGN 0xe0
|
||||||
|
#define R11_REG 40
|
||||||
|
#define PPERM_REV_INV 0x60
|
||||||
|
#define MM5_REG 34
|
||||||
|
#define PPERM_REVERSE 0x40
|
||||||
|
#define CX_REG 2
|
||||||
|
#define SI_REG 4
|
||||||
|
#define XMM2_REG 23
|
||||||
|
#define PPERM_ONES 0xa0
|
||||||
|
#define MM2_REG 31
|
||||||
|
#define XMM1_REG 22
|
||||||
|
#define FPCR_REG 19
|
||||||
|
|
||||||
|
enum unspec {
|
||||||
|
UNSPEC_GOT = 0,
|
||||||
|
UNSPEC_GOTOFF = 1,
|
||||||
|
UNSPEC_GOTPCREL = 2,
|
||||||
|
UNSPEC_GOTTPOFF = 3,
|
||||||
|
UNSPEC_TPOFF = 4,
|
||||||
|
UNSPEC_NTPOFF = 5,
|
||||||
|
UNSPEC_DTPOFF = 6,
|
||||||
|
UNSPEC_GOTNTPOFF = 7,
|
||||||
|
UNSPEC_INDNTPOFF = 8,
|
||||||
|
UNSPEC_PLTOFF = 9,
|
||||||
|
UNSPEC_MACHOPIC_OFFSET = 10,
|
||||||
|
UNSPEC_PCREL = 11,
|
||||||
|
UNSPEC_STACK_ALLOC = 12,
|
||||||
|
UNSPEC_SET_GOT = 13,
|
||||||
|
UNSPEC_SET_RIP = 14,
|
||||||
|
UNSPEC_SET_GOT_OFFSET = 15,
|
||||||
|
UNSPEC_MEMORY_BLOCKAGE = 16,
|
||||||
|
UNSPEC_STACK_CHECK = 17,
|
||||||
|
UNSPEC_TP = 18,
|
||||||
|
UNSPEC_TLS_GD = 19,
|
||||||
|
UNSPEC_TLS_LD_BASE = 20,
|
||||||
|
UNSPEC_TLSDESC = 21,
|
||||||
|
UNSPEC_TLS_IE_SUN = 22,
|
||||||
|
UNSPEC_SCAS = 23,
|
||||||
|
UNSPEC_FNSTSW = 24,
|
||||||
|
UNSPEC_SAHF = 25,
|
||||||
|
UNSPEC_PARITY = 26,
|
||||||
|
UNSPEC_FSTCW = 27,
|
||||||
|
UNSPEC_ADD_CARRY = 28,
|
||||||
|
UNSPEC_FLDCW = 29,
|
||||||
|
UNSPEC_REP = 30,
|
||||||
|
UNSPEC_LD_MPIC = 31,
|
||||||
|
UNSPEC_TRUNC_NOOP = 32,
|
||||||
|
UNSPEC_DIV_ALREADY_SPLIT = 33,
|
||||||
|
UNSPEC_MS_TO_SYSV_CALL = 34,
|
||||||
|
UNSPEC_PAUSE = 35,
|
||||||
|
UNSPEC_LEA_ADDR = 36,
|
||||||
|
UNSPEC_XBEGIN_ABORT = 37,
|
||||||
|
UNSPEC_STOS = 38,
|
||||||
|
UNSPEC_FIX_NOTRUNC = 39,
|
||||||
|
UNSPEC_MASKMOV = 40,
|
||||||
|
UNSPEC_MOVMSK = 41,
|
||||||
|
UNSPEC_RCP = 42,
|
||||||
|
UNSPEC_RSQRT = 43,
|
||||||
|
UNSPEC_PSADBW = 44,
|
||||||
|
UNSPEC_COPYSIGN = 45,
|
||||||
|
UNSPEC_IEEE_MIN = 46,
|
||||||
|
UNSPEC_IEEE_MAX = 47,
|
||||||
|
UNSPEC_SIN = 48,
|
||||||
|
UNSPEC_COS = 49,
|
||||||
|
UNSPEC_FPATAN = 50,
|
||||||
|
UNSPEC_FYL2X = 51,
|
||||||
|
UNSPEC_FYL2XP1 = 52,
|
||||||
|
UNSPEC_FRNDINT = 53,
|
||||||
|
UNSPEC_FIST = 54,
|
||||||
|
UNSPEC_F2XM1 = 55,
|
||||||
|
UNSPEC_TAN = 56,
|
||||||
|
UNSPEC_FXAM = 57,
|
||||||
|
UNSPEC_FRNDINT_FLOOR = 58,
|
||||||
|
UNSPEC_FRNDINT_CEIL = 59,
|
||||||
|
UNSPEC_FRNDINT_TRUNC = 60,
|
||||||
|
UNSPEC_FRNDINT_MASK_PM = 61,
|
||||||
|
UNSPEC_FIST_FLOOR = 62,
|
||||||
|
UNSPEC_FIST_CEIL = 63,
|
||||||
|
UNSPEC_SINCOS_COS = 64,
|
||||||
|
UNSPEC_SINCOS_SIN = 65,
|
||||||
|
UNSPEC_XTRACT_FRACT = 66,
|
||||||
|
UNSPEC_XTRACT_EXP = 67,
|
||||||
|
UNSPEC_FSCALE_FRACT = 68,
|
||||||
|
UNSPEC_FSCALE_EXP = 69,
|
||||||
|
UNSPEC_FPREM_F = 70,
|
||||||
|
UNSPEC_FPREM_U = 71,
|
||||||
|
UNSPEC_FPREM1_F = 72,
|
||||||
|
UNSPEC_FPREM1_U = 73,
|
||||||
|
UNSPEC_C2_FLAG = 74,
|
||||||
|
UNSPEC_FXAM_MEM = 75,
|
||||||
|
UNSPEC_SP_SET = 76,
|
||||||
|
UNSPEC_SP_TEST = 77,
|
||||||
|
UNSPEC_SP_TLS_SET = 78,
|
||||||
|
UNSPEC_SP_TLS_TEST = 79,
|
||||||
|
UNSPEC_ROUND = 80,
|
||||||
|
UNSPEC_CRC32 = 81,
|
||||||
|
UNSPEC_BEXTR = 82,
|
||||||
|
UNSPEC_PDEP = 83,
|
||||||
|
UNSPEC_PEXT = 84,
|
||||||
|
UNSPEC_MOVNTQ = 85,
|
||||||
|
UNSPEC_PFRCP = 86,
|
||||||
|
UNSPEC_PFRCPIT1 = 87,
|
||||||
|
UNSPEC_PFRCPIT2 = 88,
|
||||||
|
UNSPEC_PFRSQRT = 89,
|
||||||
|
UNSPEC_PFRSQIT1 = 90,
|
||||||
|
UNSPEC_MOVNT = 91,
|
||||||
|
UNSPEC_LOADU = 92,
|
||||||
|
UNSPEC_STOREU = 93,
|
||||||
|
UNSPEC_LDDQU = 94,
|
||||||
|
UNSPEC_PSHUFB = 95,
|
||||||
|
UNSPEC_PSIGN = 96,
|
||||||
|
UNSPEC_PALIGNR = 97,
|
||||||
|
UNSPEC_EXTRQI = 98,
|
||||||
|
UNSPEC_EXTRQ = 99,
|
||||||
|
UNSPEC_INSERTQI = 100,
|
||||||
|
UNSPEC_INSERTQ = 101,
|
||||||
|
UNSPEC_BLENDV = 102,
|
||||||
|
UNSPEC_INSERTPS = 103,
|
||||||
|
UNSPEC_DP = 104,
|
||||||
|
UNSPEC_MOVNTDQA = 105,
|
||||||
|
UNSPEC_MPSADBW = 106,
|
||||||
|
UNSPEC_PHMINPOSUW = 107,
|
||||||
|
UNSPEC_PTEST = 108,
|
||||||
|
UNSPEC_PCMPESTR = 109,
|
||||||
|
UNSPEC_PCMPISTR = 110,
|
||||||
|
UNSPEC_FMADDSUB = 111,
|
||||||
|
UNSPEC_XOP_UNSIGNED_CMP = 112,
|
||||||
|
UNSPEC_XOP_TRUEFALSE = 113,
|
||||||
|
UNSPEC_XOP_PERMUTE = 114,
|
||||||
|
UNSPEC_FRCZ = 115,
|
||||||
|
UNSPEC_AESENC = 116,
|
||||||
|
UNSPEC_AESENCLAST = 117,
|
||||||
|
UNSPEC_AESDEC = 118,
|
||||||
|
UNSPEC_AESDECLAST = 119,
|
||||||
|
UNSPEC_AESIMC = 120,
|
||||||
|
UNSPEC_AESKEYGENASSIST = 121,
|
||||||
|
UNSPEC_PCLMUL = 122,
|
||||||
|
UNSPEC_PCMP = 123,
|
||||||
|
UNSPEC_VPERMIL = 124,
|
||||||
|
UNSPEC_VPERMIL2 = 125,
|
||||||
|
UNSPEC_VPERMIL2F128 = 126,
|
||||||
|
UNSPEC_CAST = 127,
|
||||||
|
UNSPEC_VTESTP = 128,
|
||||||
|
UNSPEC_VCVTPH2PS = 129,
|
||||||
|
UNSPEC_VCVTPS2PH = 130,
|
||||||
|
UNSPEC_VPERMVAR = 131,
|
||||||
|
UNSPEC_VPERMTI = 132,
|
||||||
|
UNSPEC_GATHER = 133,
|
||||||
|
UNSPEC_VSIBADDR = 134,
|
||||||
|
UNSPEC_LFENCE = 135,
|
||||||
|
UNSPEC_SFENCE = 136,
|
||||||
|
UNSPEC_MFENCE = 137,
|
||||||
|
UNSPEC_MOVA = 138,
|
||||||
|
UNSPEC_LDA = 139,
|
||||||
|
UNSPEC_STA = 140
|
||||||
|
};
|
||||||
|
#define NUM_UNSPEC_VALUES 141
|
||||||
|
extern const char *const unspec_strings[];
|
||||||
|
|
||||||
|
enum unspecv {
|
||||||
|
UNSPECV_BLOCKAGE = 0,
|
||||||
|
UNSPECV_STACK_PROBE = 1,
|
||||||
|
UNSPECV_PROBE_STACK_RANGE = 2,
|
||||||
|
UNSPECV_ALIGN = 3,
|
||||||
|
UNSPECV_PROLOGUE_USE = 4,
|
||||||
|
UNSPECV_SPLIT_STACK_RETURN = 5,
|
||||||
|
UNSPECV_CLD = 6,
|
||||||
|
UNSPECV_NOPS = 7,
|
||||||
|
UNSPECV_RDTSC = 8,
|
||||||
|
UNSPECV_RDTSCP = 9,
|
||||||
|
UNSPECV_RDPMC = 10,
|
||||||
|
UNSPECV_LLWP_INTRINSIC = 11,
|
||||||
|
UNSPECV_SLWP_INTRINSIC = 12,
|
||||||
|
UNSPECV_LWPVAL_INTRINSIC = 13,
|
||||||
|
UNSPECV_LWPINS_INTRINSIC = 14,
|
||||||
|
UNSPECV_RDFSBASE = 15,
|
||||||
|
UNSPECV_RDGSBASE = 16,
|
||||||
|
UNSPECV_WRFSBASE = 17,
|
||||||
|
UNSPECV_WRGSBASE = 18,
|
||||||
|
UNSPECV_FXSAVE = 19,
|
||||||
|
UNSPECV_FXRSTOR = 20,
|
||||||
|
UNSPECV_FXSAVE64 = 21,
|
||||||
|
UNSPECV_FXRSTOR64 = 22,
|
||||||
|
UNSPECV_XSAVE = 23,
|
||||||
|
UNSPECV_XRSTOR = 24,
|
||||||
|
UNSPECV_XSAVE64 = 25,
|
||||||
|
UNSPECV_XRSTOR64 = 26,
|
||||||
|
UNSPECV_XSAVEOPT = 27,
|
||||||
|
UNSPECV_XSAVEOPT64 = 28,
|
||||||
|
UNSPECV_RDRAND = 29,
|
||||||
|
UNSPECV_RDSEED = 30,
|
||||||
|
UNSPECV_XBEGIN = 31,
|
||||||
|
UNSPECV_XEND = 32,
|
||||||
|
UNSPECV_XABORT = 33,
|
||||||
|
UNSPECV_XTEST = 34,
|
||||||
|
UNSPECV_NLGR = 35,
|
||||||
|
UNSPECV_EMMS = 36,
|
||||||
|
UNSPECV_FEMMS = 37,
|
||||||
|
UNSPECV_LDMXCSR = 38,
|
||||||
|
UNSPECV_STMXCSR = 39,
|
||||||
|
UNSPECV_CLFLUSH = 40,
|
||||||
|
UNSPECV_MONITOR = 41,
|
||||||
|
UNSPECV_MWAIT = 42,
|
||||||
|
UNSPECV_VZEROALL = 43,
|
||||||
|
UNSPECV_VZEROUPPER = 44,
|
||||||
|
UNSPECV_CMPXCHG = 45,
|
||||||
|
UNSPECV_XCHG = 46,
|
||||||
|
UNSPECV_LOCK = 47
|
||||||
|
};
|
||||||
|
#define NUM_UNSPECV_VALUES 48
|
||||||
|
extern const char *const unspecv_strings[];
|
||||||
|
|
||||||
|
#endif /* GCC_INSN_CONSTANTS_H */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,160 @@
|
||||||
|
/* Generated automatically from machmode.def and config/i386/i386-modes.def
|
||||||
|
by genmodes. */
|
||||||
|
|
||||||
|
#ifndef GCC_INSN_MODES_H
|
||||||
|
#define GCC_INSN_MODES_H
|
||||||
|
|
||||||
|
enum machine_mode
|
||||||
|
{
|
||||||
|
VOIDmode, /* machmode.def:172 */
|
||||||
|
BLKmode, /* machmode.def:176 */
|
||||||
|
CCmode, /* machmode.def:204 */
|
||||||
|
CCGCmode, /* config/i386/i386-modes.def:61 */
|
||||||
|
CCGOCmode, /* config/i386/i386-modes.def:62 */
|
||||||
|
CCNOmode, /* config/i386/i386-modes.def:63 */
|
||||||
|
CCAmode, /* config/i386/i386-modes.def:64 */
|
||||||
|
CCCmode, /* config/i386/i386-modes.def:65 */
|
||||||
|
CCOmode, /* config/i386/i386-modes.def:66 */
|
||||||
|
CCSmode, /* config/i386/i386-modes.def:67 */
|
||||||
|
CCZmode, /* config/i386/i386-modes.def:68 */
|
||||||
|
CCFPmode, /* config/i386/i386-modes.def:69 */
|
||||||
|
CCFPUmode, /* config/i386/i386-modes.def:70 */
|
||||||
|
BImode, /* machmode.def:179 */
|
||||||
|
QImode, /* machmode.def:184 */
|
||||||
|
HImode, /* machmode.def:185 */
|
||||||
|
SImode, /* machmode.def:186 */
|
||||||
|
DImode, /* machmode.def:187 */
|
||||||
|
TImode, /* machmode.def:188 */
|
||||||
|
OImode, /* config/i386/i386-modes.def:88 */
|
||||||
|
QQmode, /* machmode.def:207 */
|
||||||
|
HQmode, /* machmode.def:208 */
|
||||||
|
SQmode, /* machmode.def:209 */
|
||||||
|
DQmode, /* machmode.def:210 */
|
||||||
|
TQmode, /* machmode.def:211 */
|
||||||
|
UQQmode, /* machmode.def:213 */
|
||||||
|
UHQmode, /* machmode.def:214 */
|
||||||
|
USQmode, /* machmode.def:215 */
|
||||||
|
UDQmode, /* machmode.def:216 */
|
||||||
|
UTQmode, /* machmode.def:217 */
|
||||||
|
HAmode, /* machmode.def:219 */
|
||||||
|
SAmode, /* machmode.def:220 */
|
||||||
|
DAmode, /* machmode.def:221 */
|
||||||
|
TAmode, /* machmode.def:222 */
|
||||||
|
UHAmode, /* machmode.def:224 */
|
||||||
|
USAmode, /* machmode.def:225 */
|
||||||
|
UDAmode, /* machmode.def:226 */
|
||||||
|
UTAmode, /* machmode.def:227 */
|
||||||
|
SFmode, /* machmode.def:199 */
|
||||||
|
DFmode, /* machmode.def:200 */
|
||||||
|
XFmode, /* config/i386/i386-modes.def:24 */
|
||||||
|
TFmode, /* config/i386/i386-modes.def:25 */
|
||||||
|
SDmode, /* machmode.def:239 */
|
||||||
|
DDmode, /* machmode.def:240 */
|
||||||
|
TDmode, /* machmode.def:241 */
|
||||||
|
CQImode, /* machmode.def:235 */
|
||||||
|
CHImode, /* machmode.def:235 */
|
||||||
|
CSImode, /* machmode.def:235 */
|
||||||
|
CDImode, /* machmode.def:235 */
|
||||||
|
CTImode, /* machmode.def:235 */
|
||||||
|
COImode, /* machmode.def:235 */
|
||||||
|
SCmode, /* machmode.def:236 */
|
||||||
|
DCmode, /* machmode.def:236 */
|
||||||
|
XCmode, /* machmode.def:236 */
|
||||||
|
TCmode, /* machmode.def:236 */
|
||||||
|
V2QImode, /* config/i386/i386-modes.def:86 */
|
||||||
|
V4QImode, /* config/i386/i386-modes.def:74 */
|
||||||
|
V2HImode, /* config/i386/i386-modes.def:74 */
|
||||||
|
V1SImode, /* config/i386/i386-modes.def:85 */
|
||||||
|
V8QImode, /* config/i386/i386-modes.def:75 */
|
||||||
|
V4HImode, /* config/i386/i386-modes.def:75 */
|
||||||
|
V2SImode, /* config/i386/i386-modes.def:75 */
|
||||||
|
V1DImode, /* config/i386/i386-modes.def:84 */
|
||||||
|
V16QImode, /* config/i386/i386-modes.def:76 */
|
||||||
|
V8HImode, /* config/i386/i386-modes.def:76 */
|
||||||
|
V4SImode, /* config/i386/i386-modes.def:76 */
|
||||||
|
V2DImode, /* config/i386/i386-modes.def:76 */
|
||||||
|
V1TImode, /* config/i386/i386-modes.def:83 */
|
||||||
|
V32QImode, /* config/i386/i386-modes.def:77 */
|
||||||
|
V16HImode, /* config/i386/i386-modes.def:77 */
|
||||||
|
V8SImode, /* config/i386/i386-modes.def:77 */
|
||||||
|
V4DImode, /* config/i386/i386-modes.def:77 */
|
||||||
|
V2TImode, /* config/i386/i386-modes.def:77 */
|
||||||
|
V64QImode, /* config/i386/i386-modes.def:78 */
|
||||||
|
V32HImode, /* config/i386/i386-modes.def:78 */
|
||||||
|
V16SImode, /* config/i386/i386-modes.def:78 */
|
||||||
|
V8DImode, /* config/i386/i386-modes.def:78 */
|
||||||
|
V4TImode, /* config/i386/i386-modes.def:78 */
|
||||||
|
V2SFmode, /* config/i386/i386-modes.def:79 */
|
||||||
|
V4SFmode, /* config/i386/i386-modes.def:80 */
|
||||||
|
V2DFmode, /* config/i386/i386-modes.def:80 */
|
||||||
|
V8SFmode, /* config/i386/i386-modes.def:81 */
|
||||||
|
V4DFmode, /* config/i386/i386-modes.def:81 */
|
||||||
|
V2TFmode, /* config/i386/i386-modes.def:81 */
|
||||||
|
V16SFmode, /* config/i386/i386-modes.def:82 */
|
||||||
|
V8DFmode, /* config/i386/i386-modes.def:82 */
|
||||||
|
V4TFmode, /* config/i386/i386-modes.def:82 */
|
||||||
|
MAX_MACHINE_MODE,
|
||||||
|
|
||||||
|
MIN_MODE_RANDOM = VOIDmode,
|
||||||
|
MAX_MODE_RANDOM = BLKmode,
|
||||||
|
|
||||||
|
MIN_MODE_CC = CCmode,
|
||||||
|
MAX_MODE_CC = CCFPUmode,
|
||||||
|
|
||||||
|
MIN_MODE_INT = QImode,
|
||||||
|
MAX_MODE_INT = OImode,
|
||||||
|
|
||||||
|
MIN_MODE_PARTIAL_INT = VOIDmode,
|
||||||
|
MAX_MODE_PARTIAL_INT = VOIDmode,
|
||||||
|
|
||||||
|
MIN_MODE_FRACT = QQmode,
|
||||||
|
MAX_MODE_FRACT = TQmode,
|
||||||
|
|
||||||
|
MIN_MODE_UFRACT = UQQmode,
|
||||||
|
MAX_MODE_UFRACT = UTQmode,
|
||||||
|
|
||||||
|
MIN_MODE_ACCUM = HAmode,
|
||||||
|
MAX_MODE_ACCUM = TAmode,
|
||||||
|
|
||||||
|
MIN_MODE_UACCUM = UHAmode,
|
||||||
|
MAX_MODE_UACCUM = UTAmode,
|
||||||
|
|
||||||
|
MIN_MODE_FLOAT = SFmode,
|
||||||
|
MAX_MODE_FLOAT = TFmode,
|
||||||
|
|
||||||
|
MIN_MODE_DECIMAL_FLOAT = SDmode,
|
||||||
|
MAX_MODE_DECIMAL_FLOAT = TDmode,
|
||||||
|
|
||||||
|
MIN_MODE_COMPLEX_INT = CQImode,
|
||||||
|
MAX_MODE_COMPLEX_INT = COImode,
|
||||||
|
|
||||||
|
MIN_MODE_COMPLEX_FLOAT = SCmode,
|
||||||
|
MAX_MODE_COMPLEX_FLOAT = TCmode,
|
||||||
|
|
||||||
|
MIN_MODE_VECTOR_INT = V2QImode,
|
||||||
|
MAX_MODE_VECTOR_INT = V4TImode,
|
||||||
|
|
||||||
|
MIN_MODE_VECTOR_FRACT = VOIDmode,
|
||||||
|
MAX_MODE_VECTOR_FRACT = VOIDmode,
|
||||||
|
|
||||||
|
MIN_MODE_VECTOR_UFRACT = VOIDmode,
|
||||||
|
MAX_MODE_VECTOR_UFRACT = VOIDmode,
|
||||||
|
|
||||||
|
MIN_MODE_VECTOR_ACCUM = VOIDmode,
|
||||||
|
MAX_MODE_VECTOR_ACCUM = VOIDmode,
|
||||||
|
|
||||||
|
MIN_MODE_VECTOR_UACCUM = VOIDmode,
|
||||||
|
MAX_MODE_VECTOR_UACCUM = VOIDmode,
|
||||||
|
|
||||||
|
MIN_MODE_VECTOR_FLOAT = V2SFmode,
|
||||||
|
MAX_MODE_VECTOR_FLOAT = V4TFmode,
|
||||||
|
|
||||||
|
NUM_MACHINE_MODES = MAX_MACHINE_MODE
|
||||||
|
};
|
||||||
|
|
||||||
|
#define CONST_MODE_SIZE
|
||||||
|
#define CONST_MODE_BASE_ALIGN
|
||||||
|
#define CONST_MODE_IBIT const
|
||||||
|
#define CONST_MODE_FBIT const
|
||||||
|
|
||||||
|
#endif /* insn-modes.h */
|
|
@ -0,0 +1,90 @@
|
||||||
|
/* Insn note definitions.
|
||||||
|
Copyright (C) 2004-2013 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free
|
||||||
|
Software Foundation; either version 3, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GCC; see the file COPYING3. If not see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
/* This file defines all the codes that may appear in the
|
||||||
|
NOTE_LINE_NUMBER field of a NOTE insn for kinds of notes that are
|
||||||
|
not line numbers. Source files define DEF_INSN_NOTE appropriately
|
||||||
|
before including this file.
|
||||||
|
|
||||||
|
We are slowly removing the concept of insn-chain notes from the
|
||||||
|
compiler. Adding new codes to this file is STRONGLY DISCOURAGED.
|
||||||
|
If you think you need one, look for other ways to express what you
|
||||||
|
mean, such as register notes or bits in the basic-block structure. */
|
||||||
|
|
||||||
|
/* Shorthand. */
|
||||||
|
#define INSN_NOTE(NAME) DEF_INSN_NOTE (NOTE_INSN_##NAME)
|
||||||
|
|
||||||
|
/* This note is used to get rid of an insn when it isn't safe to patch
|
||||||
|
the insn out of the chain. */
|
||||||
|
INSN_NOTE (DELETED)
|
||||||
|
|
||||||
|
/* Generated in place of user-declared labels when they are deleted. */
|
||||||
|
INSN_NOTE (DELETED_LABEL)
|
||||||
|
/* Similarly, but for labels that have been present in debug stmts
|
||||||
|
earlier and thus will only appear with -g. These must use different
|
||||||
|
label namespace. */
|
||||||
|
INSN_NOTE (DELETED_DEBUG_LABEL)
|
||||||
|
|
||||||
|
/* These are used to mark the beginning and end of a lexical block.
|
||||||
|
See NOTE_BLOCK and reorder_blocks. */
|
||||||
|
INSN_NOTE (BLOCK_BEG)
|
||||||
|
INSN_NOTE (BLOCK_END)
|
||||||
|
|
||||||
|
/* This note indicates the start of the real body of the function,
|
||||||
|
i.e. the point just after all of the parms have been moved into
|
||||||
|
their homes, etc. */
|
||||||
|
INSN_NOTE (FUNCTION_BEG)
|
||||||
|
|
||||||
|
/* This marks the point immediately after the last prologue insn. */
|
||||||
|
INSN_NOTE (PROLOGUE_END)
|
||||||
|
|
||||||
|
/* This marks the point immediately prior to the first epilogue insn. */
|
||||||
|
INSN_NOTE (EPILOGUE_BEG)
|
||||||
|
|
||||||
|
/* These note where exception handling regions begin and end.
|
||||||
|
Uses NOTE_EH_HANDLER to identify the region in question. */
|
||||||
|
INSN_NOTE (EH_REGION_BEG)
|
||||||
|
INSN_NOTE (EH_REGION_END)
|
||||||
|
|
||||||
|
/* The location of a variable. */
|
||||||
|
INSN_NOTE (VAR_LOCATION)
|
||||||
|
|
||||||
|
/* The values passed to callee. */
|
||||||
|
INSN_NOTE (CALL_ARG_LOCATION)
|
||||||
|
|
||||||
|
/* Record the struct for the following basic block. Uses
|
||||||
|
NOTE_BASIC_BLOCK. FIXME: Redundant with the basic block pointer
|
||||||
|
now included in every insn. NOTE: If there's no CFG anymore, in other words,
|
||||||
|
if BLOCK_FOR_INSN () == NULL, NOTE_BASIC_BLOCK cannot be considered reliable
|
||||||
|
anymore. */
|
||||||
|
INSN_NOTE (BASIC_BLOCK)
|
||||||
|
|
||||||
|
/* Mark the inflection point in the instruction stream where we switch
|
||||||
|
between hot and cold text sections. */
|
||||||
|
INSN_NOTE (SWITCH_TEXT_SECTIONS)
|
||||||
|
|
||||||
|
/* When emitting dwarf2 frame information, contains a directive that
|
||||||
|
should be emitted. */
|
||||||
|
INSN_NOTE (CFI)
|
||||||
|
|
||||||
|
/* When emitting dwarf2 frame information, contains the number of a debug
|
||||||
|
label that should be emitted. */
|
||||||
|
INSN_NOTE (CFI_LABEL)
|
||||||
|
|
||||||
|
#undef INSN_NOTE
|
|
@ -0,0 +1,42 @@
|
||||||
|
/* Internal functions.
|
||||||
|
Copyright (C) 2011-2013 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free
|
||||||
|
Software Foundation; either version 3, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GCC; see the file COPYING3. If not see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
/* This file specifies a list of internal "functions". These functions
|
||||||
|
differ from built-in functions in that they have no linkage and cannot
|
||||||
|
be called directly by the user. They represent operations that are only
|
||||||
|
synthesised by GCC itself.
|
||||||
|
|
||||||
|
Internal functions are used instead of tree codes if the operation
|
||||||
|
and its operands are more naturally represented as a GIMPLE_CALL
|
||||||
|
than a GIMPLE_ASSIGN.
|
||||||
|
|
||||||
|
Each entry in this file has the form:
|
||||||
|
|
||||||
|
DEF_INTERNAL_FN (NAME, FLAGS)
|
||||||
|
|
||||||
|
where NAME is the name of the function and FLAGS is a set of
|
||||||
|
ECF_* flags. Each entry must have a corresponding expander
|
||||||
|
of the form:
|
||||||
|
|
||||||
|
void expand_NAME (gimple stmt)
|
||||||
|
|
||||||
|
where STMT is the statement that performs the call. */
|
||||||
|
|
||||||
|
DEF_INTERNAL_FN (LOAD_LANES, ECF_CONST | ECF_LEAF)
|
||||||
|
DEF_INTERNAL_FN (STORE_LANES, ECF_CONST | ECF_LEAF)
|
|
@ -0,0 +1,53 @@
|
||||||
|
/* Internal functions.
|
||||||
|
Copyright (C) 2011-2013 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free
|
||||||
|
Software Foundation; either version 3, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GCC; see the file COPYING3. If not see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#ifndef GCC_INTERNAL_FN_H
|
||||||
|
#define GCC_INTERNAL_FN_H
|
||||||
|
|
||||||
|
enum internal_fn {
|
||||||
|
#define DEF_INTERNAL_FN(CODE, FLAGS) IFN_##CODE,
|
||||||
|
#include "internal-fn.def"
|
||||||
|
#undef DEF_INTERNAL_FN
|
||||||
|
IFN_LAST
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Return the name of internal function FN. The name is only meaningful
|
||||||
|
for dumps; it has no linkage. */
|
||||||
|
|
||||||
|
extern const char *const internal_fn_name_array[];
|
||||||
|
|
||||||
|
static inline const char *
|
||||||
|
internal_fn_name (enum internal_fn fn)
|
||||||
|
{
|
||||||
|
return internal_fn_name_array[(int) fn];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the ECF_* flags for function FN. */
|
||||||
|
|
||||||
|
extern const int internal_fn_flags_array[];
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
internal_fn_flags (enum internal_fn fn)
|
||||||
|
{
|
||||||
|
return internal_fn_flags_array[(int) fn];
|
||||||
|
}
|
||||||
|
|
||||||
|
extern void expand_internal_call (gimple);
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,69 @@
|
||||||
|
/* intl.h - internationalization
|
||||||
|
Copyright (C) 1998-2013 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GCC; see the file COPYING3. If not see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#ifndef GCC_INTL_H
|
||||||
|
#define GCC_INTL_H
|
||||||
|
|
||||||
|
#ifdef HAVE_LOCALE_H
|
||||||
|
# include <locale.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef HAVE_SETLOCALE
|
||||||
|
# define setlocale(category, locale) (locale)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ENABLE_NLS
|
||||||
|
#include <libintl.h>
|
||||||
|
extern void gcc_init_libintl (void);
|
||||||
|
extern size_t gcc_gettext_width (const char *);
|
||||||
|
#else
|
||||||
|
/* Stubs. */
|
||||||
|
# undef textdomain
|
||||||
|
# define textdomain(domain) (domain)
|
||||||
|
# undef bindtextdomain
|
||||||
|
# define bindtextdomain(domain, directory) (domain)
|
||||||
|
# undef gettext
|
||||||
|
# define gettext(msgid) (msgid)
|
||||||
|
# define ngettext(singular,plural,n) fake_ngettext(singular,plural,n)
|
||||||
|
# define gcc_init_libintl() /* nothing */
|
||||||
|
# define gcc_gettext_width(s) strlen(s)
|
||||||
|
|
||||||
|
extern const char *fake_ngettext(const char *singular,const char *plural,
|
||||||
|
unsigned long int n);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _
|
||||||
|
# define _(msgid) gettext (msgid)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef N_
|
||||||
|
# define N_(msgid) msgid
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef G_
|
||||||
|
# define G_(gmsgid) gmsgid
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern char *get_spaces (const char *);
|
||||||
|
|
||||||
|
extern const char *open_quote;
|
||||||
|
extern const char *close_quote;
|
||||||
|
extern const char *locale_encoding;
|
||||||
|
extern bool locale_utf8;
|
||||||
|
|
||||||
|
#endif /* intl.h */
|
|
@ -0,0 +1,619 @@
|
||||||
|
/* Interprocedural analyses.
|
||||||
|
Copyright (C) 2005-2013 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free
|
||||||
|
Software Foundation; either version 3, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GCC; see the file COPYING3. If not see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#ifndef IPA_PROP_H
|
||||||
|
#define IPA_PROP_H
|
||||||
|
|
||||||
|
#include "tree.h"
|
||||||
|
#include "vec.h"
|
||||||
|
#include "cgraph.h"
|
||||||
|
#include "gimple.h"
|
||||||
|
#include "alloc-pool.h"
|
||||||
|
|
||||||
|
/* The following definitions and interfaces are used by
|
||||||
|
interprocedural analyses or parameters. */
|
||||||
|
|
||||||
|
/* ipa-prop.c stuff (ipa-cp, indirect inlining): */
|
||||||
|
|
||||||
|
/* A jump function for a callsite represents the values passed as actual
|
||||||
|
arguments of the callsite. They were originally proposed in a paper called
|
||||||
|
"Interprocedural Constant Propagation", by David Callahan, Keith D Cooper,
|
||||||
|
Ken Kennedy, Linda Torczon in Comp86, pg 152-161. There are three main
|
||||||
|
types of values :
|
||||||
|
|
||||||
|
Pass-through - the caller's formal parameter is passed as an actual
|
||||||
|
argument, possibly one simple operation performed on it.
|
||||||
|
Constant - a constant (is_gimple_ip_invariant)is passed as an actual
|
||||||
|
argument.
|
||||||
|
Unknown - neither of the above.
|
||||||
|
|
||||||
|
IPA_JF_ANCESTOR is a special pass-through jump function, which means that
|
||||||
|
the result is an address of a part of the object pointed to by the formal
|
||||||
|
parameter to which the function refers. It is mainly intended to represent
|
||||||
|
getting addresses of of ancestor fields in C++
|
||||||
|
(e.g. &this_1(D)->D.1766.D.1756). Note that if the original pointer is
|
||||||
|
NULL, ancestor jump function must behave like a simple pass-through.
|
||||||
|
|
||||||
|
Other pass-through functions can either simply pass on an unchanged formal
|
||||||
|
parameter or can apply one simple binary operation to it (such jump
|
||||||
|
functions are called polynomial).
|
||||||
|
|
||||||
|
IPA_JF_KNOWN_TYPE is a special type of an "unknown" function that applies
|
||||||
|
only to pointer parameters. It means that even though we cannot prove that
|
||||||
|
the passed value is an interprocedural constant, we still know the exact
|
||||||
|
type of the containing object which may be valuable for devirtualization.
|
||||||
|
|
||||||
|
Jump functions are computed in ipa-prop.c by function
|
||||||
|
update_call_notes_after_inlining. Some information can be lost and jump
|
||||||
|
functions degraded accordingly when inlining, see
|
||||||
|
update_call_notes_after_inlining in the same file. */
|
||||||
|
|
||||||
|
enum jump_func_type
|
||||||
|
{
|
||||||
|
IPA_JF_UNKNOWN = 0, /* newly allocated and zeroed jump functions default */
|
||||||
|
IPA_JF_KNOWN_TYPE, /* represented by field known_type */
|
||||||
|
IPA_JF_CONST, /* represented by field costant */
|
||||||
|
IPA_JF_PASS_THROUGH, /* represented by field pass_through */
|
||||||
|
IPA_JF_ANCESTOR /* represented by field ancestor */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Structure holding data required to describe a known type jump function. */
|
||||||
|
struct GTY(()) ipa_known_type_data
|
||||||
|
{
|
||||||
|
/* Offset of the component of the base_type being described. */
|
||||||
|
HOST_WIDE_INT offset;
|
||||||
|
/* Type of the whole object. */
|
||||||
|
tree base_type;
|
||||||
|
/* Type of the component of the object that is being described. */
|
||||||
|
tree component_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Structure holding data required to describe a pass-through jump function. */
|
||||||
|
|
||||||
|
struct GTY(()) ipa_pass_through_data
|
||||||
|
{
|
||||||
|
/* If an operation is to be performed on the original parameter, this is the
|
||||||
|
second (constant) operand. */
|
||||||
|
tree operand;
|
||||||
|
/* Number of the caller's formal parameter being passed. */
|
||||||
|
int formal_id;
|
||||||
|
/* Operation that is performed on the argument before it is passed on.
|
||||||
|
NOP_EXPR means no operation. Otherwise oper must be a simple binary
|
||||||
|
arithmetic operation where the caller's parameter is the first operand and
|
||||||
|
operand field from this structure is the second one. */
|
||||||
|
enum tree_code operation;
|
||||||
|
/* When the passed value is a pointer, it is set to true only when we are
|
||||||
|
certain that no write to the object it points to has occurred since the
|
||||||
|
caller functions started execution, except for changes noted in the
|
||||||
|
aggregate part of the jump function (see description of
|
||||||
|
ipa_agg_jump_function). The flag is used only when the operation is
|
||||||
|
NOP_EXPR. */
|
||||||
|
bool agg_preserved;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Structure holding data required to describe an ancestor pass-through
|
||||||
|
jump function. */
|
||||||
|
|
||||||
|
struct GTY(()) ipa_ancestor_jf_data
|
||||||
|
{
|
||||||
|
/* Offset of the field representing the ancestor. */
|
||||||
|
HOST_WIDE_INT offset;
|
||||||
|
/* Type of the result. */
|
||||||
|
tree type;
|
||||||
|
/* Number of the caller's formal parameter being passed. */
|
||||||
|
int formal_id;
|
||||||
|
/* Flag with the same meaning like agg_preserve in ipa_pass_through_data. */
|
||||||
|
bool agg_preserved;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* An element in an aggegate part of a jump function describing a known value
|
||||||
|
at a given offset. When it is part of a pass-through jump function with
|
||||||
|
agg_preserved set or an ancestor jump function with agg_preserved set, all
|
||||||
|
unlisted positions are assumed to be preserved but the value can be a type
|
||||||
|
node, which means that the particular piece (starting at offset and having
|
||||||
|
the size of the type) is clobbered with an unknown value. When
|
||||||
|
agg_preserved is false or the type of the containing jump function is
|
||||||
|
different, all unlisted parts are assumed to be unknown and all values must
|
||||||
|
fullfill is_gimple_ip_invariant. */
|
||||||
|
|
||||||
|
typedef struct GTY(()) ipa_agg_jf_item
|
||||||
|
{
|
||||||
|
/* The offset at which the known value is located within the aggregate. */
|
||||||
|
HOST_WIDE_INT offset;
|
||||||
|
|
||||||
|
/* The known constant or type if this is a clobber. */
|
||||||
|
tree value;
|
||||||
|
} ipa_agg_jf_item_t;
|
||||||
|
|
||||||
|
|
||||||
|
/* Aggregate jump function - i.e. description of contents of aggregates passed
|
||||||
|
either by reference or value. */
|
||||||
|
|
||||||
|
struct GTY(()) ipa_agg_jump_function
|
||||||
|
{
|
||||||
|
/* Description of the individual items. */
|
||||||
|
vec<ipa_agg_jf_item_t, va_gc> *items;
|
||||||
|
/* True if the data was passed by reference (as opposed to by value). */
|
||||||
|
bool by_ref;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct ipa_agg_jump_function *ipa_agg_jump_function_p;
|
||||||
|
typedef struct ipa_agg_jump_function ipa_agg_jump_function_t;
|
||||||
|
|
||||||
|
/* A jump function for a callsite represents the values passed as actual
|
||||||
|
arguments of the callsite. See enum jump_func_type for the various
|
||||||
|
types of jump functions supported. */
|
||||||
|
typedef struct GTY (()) ipa_jump_func
|
||||||
|
{
|
||||||
|
/* Aggregate contants description. See struct ipa_agg_jump_function and its
|
||||||
|
description. */
|
||||||
|
struct ipa_agg_jump_function agg;
|
||||||
|
|
||||||
|
enum jump_func_type type;
|
||||||
|
/* Represents a value of a jump function. pass_through is used only in jump
|
||||||
|
function context. constant represents the actual constant in constant jump
|
||||||
|
functions and member_cst holds constant c++ member functions. */
|
||||||
|
union jump_func_value
|
||||||
|
{
|
||||||
|
struct ipa_known_type_data GTY ((tag ("IPA_JF_KNOWN_TYPE"))) known_type;
|
||||||
|
tree GTY ((tag ("IPA_JF_CONST"))) constant;
|
||||||
|
struct ipa_pass_through_data GTY ((tag ("IPA_JF_PASS_THROUGH"))) pass_through;
|
||||||
|
struct ipa_ancestor_jf_data GTY ((tag ("IPA_JF_ANCESTOR"))) ancestor;
|
||||||
|
} GTY ((desc ("%1.type"))) value;
|
||||||
|
} ipa_jump_func_t;
|
||||||
|
|
||||||
|
|
||||||
|
/* Return the offset of the component that is decribed by a known type jump
|
||||||
|
function JFUNC. */
|
||||||
|
|
||||||
|
static inline HOST_WIDE_INT
|
||||||
|
ipa_get_jf_known_type_offset (struct ipa_jump_func *jfunc)
|
||||||
|
{
|
||||||
|
gcc_checking_assert (jfunc->type == IPA_JF_KNOWN_TYPE);
|
||||||
|
return jfunc->value.known_type.offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the base type of a known type jump function JFUNC. */
|
||||||
|
|
||||||
|
static inline tree
|
||||||
|
ipa_get_jf_known_type_base_type (struct ipa_jump_func *jfunc)
|
||||||
|
{
|
||||||
|
gcc_checking_assert (jfunc->type == IPA_JF_KNOWN_TYPE);
|
||||||
|
return jfunc->value.known_type.base_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the component type of a known type jump function JFUNC. */
|
||||||
|
|
||||||
|
static inline tree
|
||||||
|
ipa_get_jf_known_type_component_type (struct ipa_jump_func *jfunc)
|
||||||
|
{
|
||||||
|
gcc_checking_assert (jfunc->type == IPA_JF_KNOWN_TYPE);
|
||||||
|
return jfunc->value.known_type.component_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the constant stored in a constant jump functin JFUNC. */
|
||||||
|
|
||||||
|
static inline tree
|
||||||
|
ipa_get_jf_constant (struct ipa_jump_func *jfunc)
|
||||||
|
{
|
||||||
|
gcc_checking_assert (jfunc->type == IPA_JF_CONST);
|
||||||
|
return jfunc->value.constant;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the operand of a pass through jmp function JFUNC. */
|
||||||
|
|
||||||
|
static inline tree
|
||||||
|
ipa_get_jf_pass_through_operand (struct ipa_jump_func *jfunc)
|
||||||
|
{
|
||||||
|
gcc_checking_assert (jfunc->type == IPA_JF_PASS_THROUGH);
|
||||||
|
return jfunc->value.pass_through.operand;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the number of the caller's formal parameter that a pass through jump
|
||||||
|
function JFUNC refers to. */
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
ipa_get_jf_pass_through_formal_id (struct ipa_jump_func *jfunc)
|
||||||
|
{
|
||||||
|
gcc_checking_assert (jfunc->type == IPA_JF_PASS_THROUGH);
|
||||||
|
return jfunc->value.pass_through.formal_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return operation of a pass through jump function JFUNC. */
|
||||||
|
|
||||||
|
static inline enum tree_code
|
||||||
|
ipa_get_jf_pass_through_operation (struct ipa_jump_func *jfunc)
|
||||||
|
{
|
||||||
|
gcc_checking_assert (jfunc->type == IPA_JF_PASS_THROUGH);
|
||||||
|
return jfunc->value.pass_through.operation;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the agg_preserved flag of a pass through jump functin JFUNC. */
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
ipa_get_jf_pass_through_agg_preserved (struct ipa_jump_func *jfunc)
|
||||||
|
{
|
||||||
|
gcc_checking_assert (jfunc->type == IPA_JF_PASS_THROUGH);
|
||||||
|
return jfunc->value.pass_through.agg_preserved;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the offset of an ancestor jump function JFUNC. */
|
||||||
|
|
||||||
|
static inline HOST_WIDE_INT
|
||||||
|
ipa_get_jf_ancestor_offset (struct ipa_jump_func *jfunc)
|
||||||
|
{
|
||||||
|
gcc_checking_assert (jfunc->type == IPA_JF_ANCESTOR);
|
||||||
|
return jfunc->value.ancestor.offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the result type of an ancestor jump function JFUNC. */
|
||||||
|
|
||||||
|
static inline tree
|
||||||
|
ipa_get_jf_ancestor_type (struct ipa_jump_func *jfunc)
|
||||||
|
{
|
||||||
|
gcc_checking_assert (jfunc->type == IPA_JF_ANCESTOR);
|
||||||
|
return jfunc->value.ancestor.type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the number of the caller's formal parameter that an ancestor jump
|
||||||
|
function JFUNC refers to. */
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
ipa_get_jf_ancestor_formal_id (struct ipa_jump_func *jfunc)
|
||||||
|
{
|
||||||
|
gcc_checking_assert (jfunc->type == IPA_JF_ANCESTOR);
|
||||||
|
return jfunc->value.ancestor.formal_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the agg_preserved flag of an ancestor jump functin JFUNC. */
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
ipa_get_jf_ancestor_agg_preserved (struct ipa_jump_func *jfunc)
|
||||||
|
{
|
||||||
|
gcc_checking_assert (jfunc->type == IPA_JF_ANCESTOR);
|
||||||
|
return jfunc->value.ancestor.agg_preserved;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Summary describing a single formal parameter. */
|
||||||
|
|
||||||
|
struct ipa_param_descriptor
|
||||||
|
{
|
||||||
|
/* PARAM_DECL of this parameter. */
|
||||||
|
tree decl;
|
||||||
|
/* The parameter is used. */
|
||||||
|
unsigned used : 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct ipa_param_descriptor ipa_param_descriptor_t;
|
||||||
|
struct ipcp_lattice;
|
||||||
|
|
||||||
|
/* ipa_node_params stores information related to formal parameters of functions
|
||||||
|
and some other information for interprocedural passes that operate on
|
||||||
|
parameters (such as ipa-cp). */
|
||||||
|
|
||||||
|
struct ipa_node_params
|
||||||
|
{
|
||||||
|
/* Information about individual formal parameters that are gathered when
|
||||||
|
summaries are generated. */
|
||||||
|
vec<ipa_param_descriptor_t> descriptors;
|
||||||
|
/* Pointer to an array of structures describing individual formal
|
||||||
|
parameters. */
|
||||||
|
struct ipcp_param_lattices *lattices;
|
||||||
|
/* Only for versioned nodes this field would not be NULL,
|
||||||
|
it points to the node that IPA cp cloned from. */
|
||||||
|
struct cgraph_node *ipcp_orig_node;
|
||||||
|
/* If this node is an ipa-cp clone, these are the known values that describe
|
||||||
|
what it has been specialized for. */
|
||||||
|
vec<tree> known_vals;
|
||||||
|
/* Whether the param uses analysis has already been performed. */
|
||||||
|
unsigned uses_analysis_done : 1;
|
||||||
|
/* Whether the function is enqueued in ipa-cp propagation stack. */
|
||||||
|
unsigned node_enqueued : 1;
|
||||||
|
/* Whether we should create a specialized version based on values that are
|
||||||
|
known to be constant in all contexts. */
|
||||||
|
unsigned do_clone_for_all_contexts : 1;
|
||||||
|
/* Set if this is an IPA-CP clone for all contexts. */
|
||||||
|
unsigned is_all_contexts_clone : 1;
|
||||||
|
/* Node has been completely replaced by clones and will be removed after
|
||||||
|
ipa-cp is finished. */
|
||||||
|
unsigned node_dead : 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* ipa_node_params access functions. Please use these to access fields that
|
||||||
|
are or will be shared among various passes. */
|
||||||
|
|
||||||
|
/* Return the number of formal parameters. */
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
ipa_get_param_count (struct ipa_node_params *info)
|
||||||
|
{
|
||||||
|
return info->descriptors.length ();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the declaration of Ith formal parameter of the function corresponding
|
||||||
|
to INFO. Note there is no setter function as this array is built just once
|
||||||
|
using ipa_initialize_node_params. */
|
||||||
|
|
||||||
|
static inline tree
|
||||||
|
ipa_get_param (struct ipa_node_params *info, int i)
|
||||||
|
{
|
||||||
|
return info->descriptors[i].decl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the used flag corresponding to the Ith formal parameter of the function
|
||||||
|
associated with INFO to VAL. */
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
ipa_set_param_used (struct ipa_node_params *info, int i, bool val)
|
||||||
|
{
|
||||||
|
info->descriptors[i].used = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the used flag corresponding to the Ith formal parameter of the
|
||||||
|
function associated with INFO. */
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
ipa_is_param_used (struct ipa_node_params *info, int i)
|
||||||
|
{
|
||||||
|
return info->descriptors[i].used;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Information about replacements done in aggregates for a given node (each
|
||||||
|
node has its linked list). */
|
||||||
|
struct GTY(()) ipa_agg_replacement_value
|
||||||
|
{
|
||||||
|
/* Next item in the linked list. */
|
||||||
|
struct ipa_agg_replacement_value *next;
|
||||||
|
/* Offset within the aggregate. */
|
||||||
|
HOST_WIDE_INT offset;
|
||||||
|
/* The constant value. */
|
||||||
|
tree value;
|
||||||
|
/* The paramter index. */
|
||||||
|
int index;
|
||||||
|
/* Whether the value was passed by reference. */
|
||||||
|
bool by_ref;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct ipa_agg_replacement_value *ipa_agg_replacement_value_p;
|
||||||
|
|
||||||
|
void ipa_set_node_agg_value_chain (struct cgraph_node *node,
|
||||||
|
struct ipa_agg_replacement_value *aggvals);
|
||||||
|
|
||||||
|
/* ipa_edge_args stores information related to a callsite and particularly its
|
||||||
|
arguments. It can be accessed by the IPA_EDGE_REF macro. */
|
||||||
|
typedef struct GTY(()) ipa_edge_args
|
||||||
|
{
|
||||||
|
/* Vector of the callsite's jump function of each parameter. */
|
||||||
|
vec<ipa_jump_func_t, va_gc> *jump_functions;
|
||||||
|
} ipa_edge_args_t;
|
||||||
|
|
||||||
|
/* ipa_edge_args access functions. Please use these to access fields that
|
||||||
|
are or will be shared among various passes. */
|
||||||
|
|
||||||
|
/* Return the number of actual arguments. */
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
ipa_get_cs_argument_count (struct ipa_edge_args *args)
|
||||||
|
{
|
||||||
|
return vec_safe_length (args->jump_functions);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns a pointer to the jump function for the ith argument. Please note
|
||||||
|
there is no setter function as jump functions are all set up in
|
||||||
|
ipa_compute_jump_functions. */
|
||||||
|
|
||||||
|
static inline struct ipa_jump_func *
|
||||||
|
ipa_get_ith_jump_func (struct ipa_edge_args *args, int i)
|
||||||
|
{
|
||||||
|
return &(*args->jump_functions)[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Vectors need to have typedefs of structures. */
|
||||||
|
typedef struct ipa_node_params ipa_node_params_t;
|
||||||
|
|
||||||
|
/* Types of vectors holding the infos. */
|
||||||
|
|
||||||
|
/* Vector where the parameter infos are actually stored. */
|
||||||
|
extern vec<ipa_node_params_t> ipa_node_params_vector;
|
||||||
|
/* Vector of known aggregate values in cloned nodes. */
|
||||||
|
extern GTY(()) vec<ipa_agg_replacement_value_p, va_gc> *ipa_node_agg_replacements;
|
||||||
|
/* Vector where the parameter infos are actually stored. */
|
||||||
|
extern GTY(()) vec<ipa_edge_args_t, va_gc> *ipa_edge_args_vector;
|
||||||
|
|
||||||
|
/* Return the associated parameter/argument info corresponding to the given
|
||||||
|
node/edge. */
|
||||||
|
#define IPA_NODE_REF(NODE) (&ipa_node_params_vector[(NODE)->uid])
|
||||||
|
#define IPA_EDGE_REF(EDGE) (&(*ipa_edge_args_vector)[(EDGE)->uid])
|
||||||
|
/* This macro checks validity of index returned by
|
||||||
|
ipa_get_param_decl_index function. */
|
||||||
|
#define IS_VALID_JUMP_FUNC_INDEX(I) ((I) != -1)
|
||||||
|
|
||||||
|
/* Creating and freeing ipa_node_params and ipa_edge_args. */
|
||||||
|
void ipa_create_all_node_params (void);
|
||||||
|
void ipa_create_all_edge_args (void);
|
||||||
|
void ipa_free_edge_args_substructures (struct ipa_edge_args *);
|
||||||
|
void ipa_free_node_params_substructures (struct ipa_node_params *);
|
||||||
|
void ipa_free_all_node_params (void);
|
||||||
|
void ipa_free_all_edge_args (void);
|
||||||
|
void ipa_free_all_structures_after_ipa_cp (void);
|
||||||
|
void ipa_free_all_structures_after_iinln (void);
|
||||||
|
void ipa_register_cgraph_hooks (void);
|
||||||
|
|
||||||
|
/* This function ensures the array of node param infos is big enough to
|
||||||
|
accommodate a structure for all nodes and reallocates it if not. */
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
ipa_check_create_node_params (void)
|
||||||
|
{
|
||||||
|
if (!ipa_node_params_vector.exists ())
|
||||||
|
ipa_node_params_vector.create (cgraph_max_uid);
|
||||||
|
|
||||||
|
if (ipa_node_params_vector.length () <= (unsigned) cgraph_max_uid)
|
||||||
|
ipa_node_params_vector.safe_grow_cleared (cgraph_max_uid + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This function ensures the array of edge arguments infos is big enough to
|
||||||
|
accommodate a structure for all edges and reallocates it if not. */
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
ipa_check_create_edge_args (void)
|
||||||
|
{
|
||||||
|
if (vec_safe_length (ipa_edge_args_vector) <= (unsigned) cgraph_edge_max_uid)
|
||||||
|
vec_safe_grow_cleared (ipa_edge_args_vector, cgraph_edge_max_uid + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns true if the array of edge infos is large enough to accommodate an
|
||||||
|
info for EDGE. The main purpose of this function is that debug dumping
|
||||||
|
function can check info availability without causing reallocations. */
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
ipa_edge_args_info_available_for_edge_p (struct cgraph_edge *edge)
|
||||||
|
{
|
||||||
|
return ((unsigned) edge->uid < vec_safe_length (ipa_edge_args_vector));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the aggregate replacements for NODE, if there are any. */
|
||||||
|
|
||||||
|
static inline struct ipa_agg_replacement_value *
|
||||||
|
ipa_get_agg_replacements_for_node (struct cgraph_node *node)
|
||||||
|
{
|
||||||
|
if ((unsigned) node->uid >= vec_safe_length (ipa_node_agg_replacements))
|
||||||
|
return NULL;
|
||||||
|
return (*ipa_node_agg_replacements)[node->uid];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Function formal parameters related computations. */
|
||||||
|
void ipa_initialize_node_params (struct cgraph_node *node);
|
||||||
|
bool ipa_propagate_indirect_call_infos (struct cgraph_edge *cs,
|
||||||
|
vec<cgraph_edge_p> *new_edges);
|
||||||
|
|
||||||
|
/* Indirect edge and binfo processing. */
|
||||||
|
tree ipa_get_indirect_edge_target (struct cgraph_edge *ie,
|
||||||
|
vec<tree> ,
|
||||||
|
vec<tree> ,
|
||||||
|
vec<ipa_agg_jump_function_p> );
|
||||||
|
struct cgraph_edge *ipa_make_edge_direct_to_target (struct cgraph_edge *, tree);
|
||||||
|
|
||||||
|
/* Functions related to both. */
|
||||||
|
void ipa_analyze_node (struct cgraph_node *);
|
||||||
|
|
||||||
|
/* Aggregate jump function related functions. */
|
||||||
|
tree ipa_find_agg_cst_for_param (struct ipa_agg_jump_function *, HOST_WIDE_INT,
|
||||||
|
bool);
|
||||||
|
bool ipa_load_from_parm_agg (struct ipa_node_params *, gimple, tree, int *,
|
||||||
|
HOST_WIDE_INT *, bool *);
|
||||||
|
|
||||||
|
/* Debugging interface. */
|
||||||
|
void ipa_print_node_params (FILE *, struct cgraph_node *node);
|
||||||
|
void ipa_print_all_params (FILE *);
|
||||||
|
void ipa_print_node_jump_functions (FILE *f, struct cgraph_node *node);
|
||||||
|
void ipa_print_all_jump_functions (FILE * f);
|
||||||
|
void ipcp_verify_propagated_values (void);
|
||||||
|
|
||||||
|
extern alloc_pool ipcp_values_pool;
|
||||||
|
extern alloc_pool ipcp_sources_pool;
|
||||||
|
extern alloc_pool ipcp_agg_lattice_pool;
|
||||||
|
|
||||||
|
/* Structure to describe transformations of formal parameters and actual
|
||||||
|
arguments. Each instance describes one new parameter and they are meant to
|
||||||
|
be stored in a vector. Additionally, most users will probably want to store
|
||||||
|
adjustments about parameters that are being removed altogether so that SSA
|
||||||
|
names belonging to them can be replaced by SSA names of an artificial
|
||||||
|
variable. */
|
||||||
|
struct ipa_parm_adjustment
|
||||||
|
{
|
||||||
|
/* The original PARM_DECL itself, helpful for processing of the body of the
|
||||||
|
function itself. Intended for traversing function bodies.
|
||||||
|
ipa_modify_formal_parameters, ipa_modify_call_arguments and
|
||||||
|
ipa_combine_adjustments ignore this and use base_index.
|
||||||
|
ipa_modify_formal_parameters actually sets this. */
|
||||||
|
tree base;
|
||||||
|
|
||||||
|
/* Type of the new parameter. However, if by_ref is true, the real type will
|
||||||
|
be a pointer to this type. */
|
||||||
|
tree type;
|
||||||
|
|
||||||
|
/* Alias refrerence type to be used in MEM_REFs when adjusting caller
|
||||||
|
arguments. */
|
||||||
|
tree alias_ptr_type;
|
||||||
|
|
||||||
|
/* The new declaration when creating/replacing a parameter. Created by
|
||||||
|
ipa_modify_formal_parameters, useful for functions modifying the body
|
||||||
|
accordingly. */
|
||||||
|
tree reduction;
|
||||||
|
|
||||||
|
/* New declaration of a substitute variable that we may use to replace all
|
||||||
|
non-default-def ssa names when a parm decl is going away. */
|
||||||
|
tree new_ssa_base;
|
||||||
|
|
||||||
|
/* If non-NULL and the original parameter is to be removed (copy_param below
|
||||||
|
is NULL), this is going to be its nonlocalized vars value. */
|
||||||
|
tree nonlocal_value;
|
||||||
|
|
||||||
|
/* Offset into the original parameter (for the cases when the new parameter
|
||||||
|
is a component of an original one). */
|
||||||
|
HOST_WIDE_INT offset;
|
||||||
|
|
||||||
|
/* Zero based index of the original parameter this one is based on. (ATM
|
||||||
|
there is no way to insert a new parameter out of the blue because there is
|
||||||
|
no need but if it arises the code can be easily exteded to do so.) */
|
||||||
|
int base_index;
|
||||||
|
|
||||||
|
/* This new parameter is an unmodified parameter at index base_index. */
|
||||||
|
unsigned copy_param : 1;
|
||||||
|
|
||||||
|
/* This adjustment describes a parameter that is about to be removed
|
||||||
|
completely. Most users will probably need to book keep those so that they
|
||||||
|
don't leave behinfd any non default def ssa names belonging to them. */
|
||||||
|
unsigned remove_param : 1;
|
||||||
|
|
||||||
|
/* The parameter is to be passed by reference. */
|
||||||
|
unsigned by_ref : 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct ipa_parm_adjustment ipa_parm_adjustment_t;
|
||||||
|
|
||||||
|
typedef vec<ipa_parm_adjustment_t> ipa_parm_adjustment_vec;
|
||||||
|
|
||||||
|
vec<tree> ipa_get_vector_of_formal_parms (tree fndecl);
|
||||||
|
void ipa_modify_formal_parameters (tree fndecl, ipa_parm_adjustment_vec,
|
||||||
|
const char *);
|
||||||
|
void ipa_modify_call_arguments (struct cgraph_edge *, gimple,
|
||||||
|
ipa_parm_adjustment_vec);
|
||||||
|
ipa_parm_adjustment_vec ipa_combine_adjustments (ipa_parm_adjustment_vec,
|
||||||
|
ipa_parm_adjustment_vec);
|
||||||
|
void ipa_dump_param_adjustments (FILE *, ipa_parm_adjustment_vec, tree);
|
||||||
|
void ipa_dump_agg_replacement_values (FILE *f,
|
||||||
|
struct ipa_agg_replacement_value *av);
|
||||||
|
void ipa_prop_write_jump_functions (void);
|
||||||
|
void ipa_prop_read_jump_functions (void);
|
||||||
|
void ipa_prop_write_all_agg_replacement (void);
|
||||||
|
void ipa_prop_read_all_agg_replacement (void);
|
||||||
|
void ipa_update_after_lto_read (void);
|
||||||
|
int ipa_get_param_decl_index (struct ipa_node_params *, tree);
|
||||||
|
tree ipa_value_from_jfunc (struct ipa_node_params *info,
|
||||||
|
struct ipa_jump_func *jfunc);
|
||||||
|
unsigned int ipcp_transform_function (struct cgraph_node *node);
|
||||||
|
|
||||||
|
|
||||||
|
/* From tree-sra.c: */
|
||||||
|
tree build_ref_for_offset (location_t, tree, HOST_WIDE_INT, tree,
|
||||||
|
gimple_stmt_iterator *, bool);
|
||||||
|
|
||||||
|
#endif /* IPA_PROP_H */
|
|
@ -0,0 +1,108 @@
|
||||||
|
/* IPA reference lists.
|
||||||
|
Copyright (C) 2010-2013 Free Software Foundation, Inc.
|
||||||
|
Contributed by Jan Hubicka
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free
|
||||||
|
Software Foundation; either version 3, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GCC; see the file COPYING3. If not see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
/* Return callgraph node REF is referring. */
|
||||||
|
static inline struct cgraph_node *
|
||||||
|
ipa_ref_node (struct ipa_ref *ref)
|
||||||
|
{
|
||||||
|
return cgraph (ref->referred);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return varpool node REF is referring. */
|
||||||
|
|
||||||
|
static inline struct varpool_node *
|
||||||
|
ipa_ref_varpool_node (struct ipa_ref *ref)
|
||||||
|
{
|
||||||
|
return varpool (ref->referred);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return cgraph node REF is in. */
|
||||||
|
|
||||||
|
static inline struct cgraph_node *
|
||||||
|
ipa_ref_referring_node (struct ipa_ref *ref)
|
||||||
|
{
|
||||||
|
return cgraph (ref->referring);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return varpool node REF is in. */
|
||||||
|
|
||||||
|
static inline struct varpool_node *
|
||||||
|
ipa_ref_referring_varpool_node (struct ipa_ref *ref)
|
||||||
|
{
|
||||||
|
return varpool (ref->referring);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return reference list REF is in. */
|
||||||
|
|
||||||
|
static inline struct ipa_ref_list *
|
||||||
|
ipa_ref_referring_ref_list (struct ipa_ref *ref)
|
||||||
|
{
|
||||||
|
return &ref->referring->symbol.ref_list;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return reference list REF is in. */
|
||||||
|
|
||||||
|
static inline struct ipa_ref_list *
|
||||||
|
ipa_ref_referred_ref_list (struct ipa_ref *ref)
|
||||||
|
{
|
||||||
|
return &ref->referred->symbol.ref_list;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return first reference in LIST or NULL if empty. */
|
||||||
|
|
||||||
|
static inline struct ipa_ref *
|
||||||
|
ipa_ref_list_first_reference (struct ipa_ref_list *list)
|
||||||
|
{
|
||||||
|
if (!vec_safe_length (list->references))
|
||||||
|
return NULL;
|
||||||
|
return &(*list->references)[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return first referring ref in LIST or NULL if empty. */
|
||||||
|
|
||||||
|
static inline struct ipa_ref *
|
||||||
|
ipa_ref_list_first_referring (struct ipa_ref_list *list)
|
||||||
|
{
|
||||||
|
if (!list->referring.length ())
|
||||||
|
return NULL;
|
||||||
|
return list->referring[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Clear reference list. */
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
ipa_empty_ref_list (struct ipa_ref_list *list)
|
||||||
|
{
|
||||||
|
list->referring.create (0);
|
||||||
|
list->references = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Clear reference list. */
|
||||||
|
|
||||||
|
static inline unsigned int
|
||||||
|
ipa_ref_list_nreferences (struct ipa_ref_list *list)
|
||||||
|
{
|
||||||
|
return vec_safe_length (list->references);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ipa_ref_list_reference_iterate(L,I,P) \
|
||||||
|
vec_safe_iterate ((L)->references, (I), &(P))
|
||||||
|
#define ipa_ref_list_referring_iterate(L,I,P) \
|
||||||
|
(L)->referring.iterate ((I), &(P))
|
|
@ -0,0 +1,73 @@
|
||||||
|
/* IPA reference lists.
|
||||||
|
Copyright (C) 2010-2013 Free Software Foundation, Inc.
|
||||||
|
Contributed by Jan Hubicka
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free
|
||||||
|
Software Foundation; either version 3, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GCC; see the file COPYING3. If not see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
struct cgraph_node;
|
||||||
|
struct varpool_node;
|
||||||
|
union symtab_node_def;
|
||||||
|
typedef union symtab_node_def *symtab_node;
|
||||||
|
typedef const union symtab_node_def *const_symtab_node;
|
||||||
|
|
||||||
|
|
||||||
|
/* How the reference is done. */
|
||||||
|
enum GTY(()) ipa_ref_use
|
||||||
|
{
|
||||||
|
IPA_REF_LOAD,
|
||||||
|
IPA_REF_STORE,
|
||||||
|
IPA_REF_ADDR,
|
||||||
|
IPA_REF_ALIAS
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Record of reference in callgraph or varpool. */
|
||||||
|
struct GTY(()) ipa_ref
|
||||||
|
{
|
||||||
|
symtab_node referring;
|
||||||
|
symtab_node referred;
|
||||||
|
gimple stmt;
|
||||||
|
unsigned int referred_index;
|
||||||
|
ENUM_BITFIELD (ipa_ref_use) use:2;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct ipa_ref ipa_ref_t;
|
||||||
|
typedef struct ipa_ref *ipa_ref_ptr;
|
||||||
|
|
||||||
|
|
||||||
|
/* List of references. This is stored in both callgraph and varpool nodes. */
|
||||||
|
struct GTY(()) ipa_ref_list
|
||||||
|
{
|
||||||
|
/* Store actual references in references vector. */
|
||||||
|
vec<ipa_ref_t, va_gc> *references;
|
||||||
|
/* Referring is vector of pointers to references. It must not live in GGC space
|
||||||
|
or GGC will try to mark middle of references vectors. */
|
||||||
|
vec<ipa_ref_ptr> GTY((skip)) referring;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ipa_ref * ipa_record_reference (symtab_node,
|
||||||
|
symtab_node,
|
||||||
|
enum ipa_ref_use, gimple);
|
||||||
|
|
||||||
|
void ipa_remove_reference (struct ipa_ref *);
|
||||||
|
void ipa_remove_all_references (struct ipa_ref_list *);
|
||||||
|
void ipa_remove_all_referring (struct ipa_ref_list *);
|
||||||
|
void ipa_dump_references (FILE *, struct ipa_ref_list *);
|
||||||
|
void ipa_dump_referring (FILE *, struct ipa_ref_list *);
|
||||||
|
void ipa_clone_references (symtab_node, struct ipa_ref_list *);
|
||||||
|
void ipa_clone_referring (symtab_node, struct ipa_ref_list *);
|
||||||
|
bool ipa_ref_cannot_lead_to_return (struct ipa_ref *);
|
||||||
|
bool ipa_ref_has_aliases_p (struct ipa_ref_list *);
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue