1 Star 0 Fork 151

wangding16/src-gcc

forked from src-openEuler/gcc 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
0077-Struct-Reorg-Add-Safe-Structure-Pointer-Compression.patch 37.58 KB
一键复制 编辑 原始数据 按行查看 历史
笨鸟不飞就是鸡 提交于 2022-12-01 11:33 +08:00 . [Sync] Sync patch from openeuler/gcc
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193
From 0445301c09926a20d5e02809b2cd35bddc9fa50e Mon Sep 17 00:00:00 2001
From: liyancheng <412998149@qq.com>
Date: Wed, 9 Nov 2022 21:00:04 +0800
Subject: [PATCH 29/35] [Struct Reorg] Add Safe Structure Pointer Compression
Safe structure pointer compression allows safely compressing pointers
stored in structure to reduce the size of structure.
Add flag -fipa-struct-reorg=4 to enable safe structure pointer compression.
---
gcc/common.opt | 5 +-
gcc/ipa-struct-reorg/ipa-struct-reorg.c | 905 +++++++++++++++++++++++-
gcc/ipa-struct-reorg/ipa-struct-reorg.h | 4 +
gcc/params.opt | 4 +
4 files changed, 877 insertions(+), 41 deletions(-)
diff --git a/gcc/common.opt b/gcc/common.opt
index 6a7f66624..c9b099817 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -1889,8 +1889,9 @@ Common Report Var(flag_ipa_struct_reorg) Init(0) Optimization
Perform structure layout optimizations.
fipa-struct-reorg=
-Common RejectNegative Joined UInteger Var(struct_layout_optimize_level) Init(0) IntegerRange(0, 3)
--fipa-struct-reorg=[0,1,2,3] adding none, struct-reorg, reorder-fields, dfe optimizations.
+Common RejectNegative Joined UInteger Var(struct_layout_optimize_level) Init(0) IntegerRange(0, 4)
+-fipa-struct-reorg=[0,1,2,3,4] adding none, struct-reorg, reorder-fields,
+dfe, safe-pointer-compression optimizations.
fipa-extend-auto-profile
Common Report Var(flag_ipa_extend_auto_profile)
diff --git a/gcc/ipa-struct-reorg/ipa-struct-reorg.c b/gcc/ipa-struct-reorg/ipa-struct-reorg.c
index 08cb51fee..3550411dc 100644
--- a/gcc/ipa-struct-reorg/ipa-struct-reorg.c
+++ b/gcc/ipa-struct-reorg/ipa-struct-reorg.c
@@ -83,6 +83,7 @@ along with GCC; see the file COPYING3. If not see
#include "gimple-iterator.h"
#include "gimple-walk.h"
#include "cfg.h"
+#include "cfghooks.h" /* For split_block. */
#include "ssa.h"
#include "tree-dfa.h"
#include "fold-const.h"
@@ -145,7 +146,27 @@ namespace {
using namespace struct_reorg;
using namespace struct_relayout;
-/* Return true iff TYPE is stdarg va_list type. */
+static void
+set_var_attributes (tree var)
+{
+ if (!var)
+ return;
+ gcc_assert (TREE_CODE (var) == VAR_DECL);
+
+ DECL_ARTIFICIAL (var) = 1;
+ DECL_EXTERNAL (var) = 0;
+ TREE_STATIC (var) = 1;
+ TREE_PUBLIC (var) = 0;
+ TREE_USED (var) = 1;
+ DECL_CONTEXT (var) = NULL_TREE;
+ TREE_THIS_VOLATILE (var) = 0;
+ TREE_ADDRESSABLE (var) = 0;
+ TREE_READONLY (var) = 0;
+ if (is_global_var (var))
+ set_decl_tls_model (var, TLS_MODEL_NONE);
+}
+
+/* Return true if TYPE is stdarg va_list type. */
static inline bool
is_va_list_type (tree type)
@@ -242,9 +263,15 @@ enum struct_layout_opt_level
STRUCT_SPLIT = 1 << 0,
COMPLETE_STRUCT_RELAYOUT = 1 << 1,
STRUCT_REORDER_FIELDS = 1 << 2,
- DEAD_FIELD_ELIMINATION = 1 << 3
+ DEAD_FIELD_ELIMINATION = 1 << 3,
+ POINTER_COMPRESSION_SAFE = 1 << 4
};
+/* Defines the target pointer size of compressed pointer, which should be 8,
+ 16, 32. */
+
+static int compressed_size = 32;
+
static bool is_result_of_mult (tree arg, tree *num, tree struct_size);
bool isptrptr (tree type);
void get_base (tree &base, tree expr);
@@ -366,7 +393,10 @@ srtype::srtype (tree type)
: type (type),
chain_type (false),
escapes (does_not_escape),
+ pc_gptr (NULL_TREE),
visited (false),
+ pc_candidate (false),
+ has_legal_alloc_num (false),
has_alloc_array (0)
{
for (int i = 0; i < max_split; i++)
@@ -447,6 +477,31 @@ srtype::mark_escape (escape_type e, gimple *stmt)
}
}
+/* Create a global header for compressed struct. */
+
+void
+srtype::create_global_ptr_for_pc ()
+{
+ if (!pc_candidate || pc_gptr != NULL_TREE)
+ return;
+
+ const char *type_name = get_type_name (type);
+ gcc_assert (type_name != NULL);
+
+ char *gptr_name = concat (type_name, "_pc", NULL);
+ tree new_name = get_identifier (gptr_name);
+ tree new_type = build_pointer_type (newtype[0]);
+ tree new_var = build_decl (UNKNOWN_LOCATION, VAR_DECL, new_name, new_type);
+ set_var_attributes (new_var);
+ pc_gptr = new_var;
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, "\nType: %s has create global header for pointer"
+ " compression: %s\n", type_name, gptr_name);
+
+ free (gptr_name);
+}
+
/* Add FIELD to the list of fields that use this type. */
void
@@ -790,20 +845,31 @@ srfield::create_new_optimized_fields (tree newtype[max_split],
fields.safe_push (field);
}
- DECL_NAME (field) = DECL_NAME (fielddecl);
if (type == NULL)
{
+ DECL_NAME (field) = DECL_NAME (fielddecl);
/* Common members do not need to reconstruct.
Otherwise, int* -> int** or void* -> void**. */
TREE_TYPE (field) = nt;
+ SET_DECL_ALIGN (field, DECL_ALIGN (fielddecl));
+ }
+ else if (type->pc_candidate)
+ {
+ const char *old_name = IDENTIFIER_POINTER (DECL_NAME (fielddecl));
+ char *new_name = concat (old_name, "_pc", NULL);
+ DECL_NAME (field) = get_identifier (new_name);
+ free (new_name);
+ TREE_TYPE (field) = make_unsigned_type (compressed_size);
+ SET_DECL_ALIGN (field, compressed_size);
}
else
{
- TREE_TYPE (field)
- = reconstruct_complex_type (TREE_TYPE (fielddecl), nt);
+ DECL_NAME (field) = DECL_NAME (fielddecl);
+ TREE_TYPE (field) = reconstruct_complex_type (TREE_TYPE (fielddecl), nt);
+ SET_DECL_ALIGN (field, DECL_ALIGN (fielddecl));
}
+
DECL_SOURCE_LOCATION (field) = DECL_SOURCE_LOCATION (fielddecl);
- SET_DECL_ALIGN (field, DECL_ALIGN (fielddecl));
DECL_USER_ALIGN (field) = DECL_USER_ALIGN (fielddecl);
TREE_ADDRESSABLE (field) = TREE_ADDRESSABLE (fielddecl);
DECL_NONADDRESSABLE_P (field) = !TREE_ADDRESSABLE (fielddecl);
@@ -923,6 +989,10 @@ srtype::create_new_type (void)
&& has_dead_field ())
fprintf (dump_file, "Dead field elimination.\n");
}
+
+ if (pc_candidate && pc_gptr == NULL_TREE)
+ create_global_ptr_for_pc ();
+
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "Created %d types:\n", maxclusters);
@@ -1341,6 +1411,30 @@ public:
void maybe_mark_or_record_other_side (tree side, tree other, gimple *stmt);
unsigned execute_struct_relayout (void);
bool remove_dead_field_stmt (tree lhs);
+
+ // Pointer compression methods:
+ void check_and_prune_struct_for_pointer_compression (void);
+ void try_rewrite_with_pointer_compression (gassign *, gimple_stmt_iterator *,
+ tree, tree, tree &, tree &);
+ bool safe_void_cmp_p (tree, srtype *);
+ bool pc_candidate_st_type_p (tree);
+ bool pc_candidate_tree_p (tree);
+ bool pc_type_conversion_candidate_p (tree);
+ bool pc_direct_rewrite_chance_p (tree, tree &);
+ bool compress_candidate_with_check (gimple_stmt_iterator *, tree, tree &);
+ bool compress_candidate (gassign *, gimple_stmt_iterator *, tree, tree &);
+ bool decompress_candidate_with_check (gimple_stmt_iterator *, tree, tree &);
+ bool decompress_candidate (gimple_stmt_iterator *, tree, tree, tree &,
+ tree &);
+ srtype *get_compression_candidate_type (tree);
+ tree compress_ptr_to_offset (tree, srtype *, gimple_stmt_iterator *);
+ tree decompress_offset_to_ptr (tree, srtype *, gimple_stmt_iterator *);
+ basic_block create_bb_for_compress_candidate (basic_block, tree, srtype *,
+ tree &);
+ basic_block create_bb_for_decompress_candidate (basic_block, tree, srtype *,
+ tree &);
+ basic_block create_bb_for_compress_nullptr (basic_block, tree &);
+ basic_block create_bb_for_decompress_nullptr (basic_block, tree, tree &);
};
struct ipa_struct_relayout
@@ -1391,29 +1485,6 @@ namespace {
/* Methods for ipa_struct_relayout. */
-static void
-set_var_attributes (tree var)
-{
- if (!var)
- {
- return;
- }
- gcc_assert (TREE_CODE (var) == VAR_DECL);
-
- DECL_ARTIFICIAL (var) = 1;
- DECL_EXTERNAL (var) = 0;
- TREE_STATIC (var) = 1;
- TREE_PUBLIC (var) = 0;
- TREE_USED (var) = 1;
- DECL_CONTEXT (var) = NULL;
- TREE_THIS_VOLATILE (var) = 0;
- TREE_ADDRESSABLE (var) = 0;
- TREE_READONLY (var) = 0;
- if (is_global_var (var))
- {
- set_decl_tls_model (var, TLS_MODEL_NONE);
- }
-}
tree
ipa_struct_relayout::create_new_vars (tree type, const char *name)
@@ -3135,6 +3206,19 @@ ipa_struct_reorg::find_vars (gimple *stmt)
records the right value _1 declaration. */
find_var (gimple_assign_rhs1 (stmt), stmt);
+ /* Pointer types from non-zero pointer need to be escaped in pointer
+ compression and complete relayout.
+ e.g _1->t = (struct *) 0x400000. */
+ if (current_layout_opt_level >= COMPLETE_STRUCT_RELAYOUT
+ && TREE_CODE (lhs) == COMPONENT_REF
+ && TREE_CODE (TREE_TYPE (lhs)) == POINTER_TYPE
+ && TREE_CODE (rhs) == INTEGER_CST
+ && !integer_zerop (rhs))
+ {
+ mark_type_as_escape (inner_type (TREE_TYPE (lhs)),
+ escape_cast_int, stmt);
+ }
+
/* Add a safe func mechanism. */
bool l_find = true;
bool r_find = true;
@@ -3603,14 +3687,15 @@ is_result_of_mult (tree arg, tree *num, tree struct_size)
bool
ipa_struct_reorg::handled_allocation_stmt (gimple *stmt)
{
- if ((current_layout_opt_level >= STRUCT_REORDER_FIELDS)
+ if ((current_layout_opt_level & STRUCT_REORDER_FIELDS)
&& (gimple_call_builtin_p (stmt, BUILT_IN_REALLOC)
|| gimple_call_builtin_p (stmt, BUILT_IN_MALLOC)
|| gimple_call_builtin_p (stmt, BUILT_IN_CALLOC)))
{
return true;
}
- if ((current_layout_opt_level == COMPLETE_STRUCT_RELAYOUT)
+ if ((current_layout_opt_level == COMPLETE_STRUCT_RELAYOUT
+ || current_layout_opt_level & POINTER_COMPRESSION_SAFE)
&& gimple_call_builtin_p (stmt, BUILT_IN_CALLOC))
return true;
if ((current_layout_opt_level == STRUCT_SPLIT)
@@ -3737,15 +3822,20 @@ ipa_struct_reorg::maybe_mark_or_record_other_side (tree side, tree other, gimple
}
}
/* x_1 = y.x_nodes; void *x;
- Directly mark the structure pointer type assigned
- to the void* variable as escape. */
+ Mark the structure pointer type assigned
+ to the void* variable as escape. Unless the void* is only used to compare
+ with variables of the same type. */
else if (current_layout_opt_level >= STRUCT_REORDER_FIELDS
&& TREE_CODE (side) == SSA_NAME
&& VOID_POINTER_P (TREE_TYPE (side))
&& SSA_NAME_VAR (side)
&& VOID_POINTER_P (TREE_TYPE (SSA_NAME_VAR (side))))
{
- mark_type_as_escape (TREE_TYPE (other), escape_cast_void, stmt);
+ if (current_layout_opt_level < POINTER_COMPRESSION_SAFE
+ || !safe_void_cmp_p (side, type))
+ {
+ mark_type_as_escape (TREE_TYPE (other), escape_cast_void, stmt);
+ }
}
check_ptr_layers (side, other, stmt);
@@ -4361,7 +4451,7 @@ ipa_struct_reorg::check_type_and_push (tree newdecl, srdecl *decl,
void
ipa_struct_reorg::check_alloc_num (gimple *stmt, srtype *type)
{
- if (current_layout_opt_level == COMPLETE_STRUCT_RELAYOUT
+ if (current_layout_opt_level >= COMPLETE_STRUCT_RELAYOUT
&& handled_allocation_stmt (stmt))
{
tree arg0 = gimple_call_arg (stmt, 0);
@@ -4388,6 +4478,22 @@ ipa_struct_reorg::check_alloc_num (gimple *stmt, srtype *type)
? type->has_alloc_array
: type->has_alloc_array + 1;
}
+ if (current_layout_opt_level & POINTER_COMPRESSION_SAFE
+ && TREE_CODE (arg0) == INTEGER_CST)
+ {
+ /* Only known size during compilation can be optimized
+ at this level. */
+ unsigned HOST_WIDE_INT max_alloc_size = 0;
+ switch (compressed_size)
+ {
+ case 8: max_alloc_size = 0xff; break; // max of uint8
+ case 16: max_alloc_size = 0xffff; break; // max of uint16
+ case 32: max_alloc_size = 0xffffffff; break; // max of uint32
+ default: gcc_unreachable (); break;
+ }
+ if (tree_to_uhwi (arg0) < max_alloc_size)
+ type->has_legal_alloc_num = true;
+ }
}
}
@@ -4530,7 +4636,11 @@ ipa_struct_reorg::check_definition (srdecl *decl, vec<srdecl*> &worklist)
&& SSA_NAME_VAR (ssa_name)
&& VOID_POINTER_P (TREE_TYPE (SSA_NAME_VAR (ssa_name))))
{
- type->mark_escape (escape_cast_void, SSA_NAME_DEF_STMT (ssa_name));
+ if (current_layout_opt_level < POINTER_COMPRESSION_SAFE
+ || !safe_void_cmp_p (ssa_name, type))
+ {
+ type->mark_escape (escape_cast_void, SSA_NAME_DEF_STMT (ssa_name));
+ }
}
gimple *stmt = SSA_NAME_DEF_STMT (ssa_name);
@@ -5509,6 +5619,8 @@ ipa_struct_reorg::create_new_types (void)
for (unsigned i = 0; i < types.length (); i++)
newtypes += types[i]->create_new_type ();
+ /* Some new types may not have been created at create_new_type (), so
+ recreate new type for all struct fields. */
if (current_layout_opt_level >= STRUCT_REORDER_FIELDS)
{
for (unsigned i = 0; i < types.length (); i++)
@@ -5519,9 +5631,18 @@ ipa_struct_reorg::create_new_types (void)
for (unsigned j = 0; j < fields->length (); j++)
{
tree field = (*fields)[j];
- TREE_TYPE (field)
- = reconstruct_complex_type (TREE_TYPE (field),
- types[i]->newtype[0]);
+ if (types[i]->pc_candidate)
+ {
+ TREE_TYPE (field)
+ = make_unsigned_type (compressed_size);
+ SET_DECL_ALIGN (field, compressed_size);
+ }
+ else
+ {
+ TREE_TYPE (field)
+ = reconstruct_complex_type (TREE_TYPE (field),
+ types[i]->newtype[0]);
+ }
}
}
}
@@ -5906,6 +6027,556 @@ ipa_struct_reorg::rewrite_expr (tree expr, tree newexpr[max_split], bool ignore_
return true;
}
+/* Emit a series of gimples to compress the pointer to the index relative to
+ the global header. The basic blocks where gsi is located must have at least
+ one stmt. */
+
+tree
+ipa_struct_reorg::compress_ptr_to_offset (tree xhs, srtype *type,
+ gimple_stmt_iterator *gsi)
+{
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "\nCompress candidate pointer:\n");
+ print_generic_expr (dump_file, xhs);
+ fprintf (dump_file, "\nto offset:\n");
+ }
+
+ /* Emit gimple _X1 = ptr - gptr. */
+ tree pointer_addr = fold_convert (long_unsigned_type_node, xhs);
+ tree gptr_addr = fold_convert (long_unsigned_type_node, type->pc_gptr);
+ tree step1 = gimplify_build2 (gsi, MINUS_EXPR, long_unsigned_type_node,
+ pointer_addr, gptr_addr);
+
+ /* Emit gimple _X2 = _X1 / sizeof (struct). */
+ tree step2 = gimplify_build2 (gsi, TRUNC_DIV_EXPR, long_unsigned_type_node,
+ step1, TYPE_SIZE_UNIT (type->newtype[0]));
+
+ /* Emit gimple _X3 = _X2 + 1. */
+ tree step3 = gimplify_build2 (gsi, PLUS_EXPR, long_unsigned_type_node,
+ step2, build_one_cst (long_unsigned_type_node));
+
+ /* Emit _X4 = (compressed_size) _X3. */
+ tree step4 = gimplify_build1 (gsi, NOP_EXPR,
+ make_unsigned_type (compressed_size), step3);
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ print_generic_expr (dump_file, step3);
+ fprintf (dump_file, "\n");
+ }
+ return step4;
+}
+
+/* Emit a series of gimples to decompress the index into the original
+ pointer. The basic blocks where gsi is located must have at least
+ one stmt. */
+
+tree
+ipa_struct_reorg::decompress_offset_to_ptr (tree xhs, srtype *type,
+ gimple_stmt_iterator *gsi)
+{
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "\nDecompress candidate offset:\n");
+ print_generic_expr (dump_file, xhs);
+ fprintf (dump_file, "\nto pointer:\n");
+ }
+
+ /* Emit _X1 = xhs - 1. */
+ tree offset = fold_convert (long_unsigned_type_node, xhs);
+ tree step1 = gimplify_build2 (gsi, MINUS_EXPR, long_unsigned_type_node,
+ offset,
+ build_one_cst (long_unsigned_type_node));
+
+ /* Emit _X2 = _X1 * sizeof (struct). */
+ tree step2 = gimplify_build2 (gsi, MULT_EXPR, long_unsigned_type_node,
+ step1, TYPE_SIZE_UNIT (type->newtype[0]));
+
+ /* Emit _X3 = phead + _X2. */
+ tree gptr_addr = fold_convert (long_unsigned_type_node, type->pc_gptr);
+ tree step3 = gimplify_build2 (gsi, PLUS_EXPR, long_unsigned_type_node,
+ gptr_addr, step2);
+
+ /* Emit _X4 = (struct *) _X3. */
+ tree step4 = gimplify_build1 (gsi, NOP_EXPR, TREE_TYPE (type->pc_gptr),
+ step3);
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ print_generic_expr (dump_file, step3);
+ fprintf (dump_file, "\n");
+ }
+ return step4;
+}
+
+/* Return the compression candidate srtype of SSA_NAME or COMPONENT_REF. */
+
+srtype *
+ipa_struct_reorg::get_compression_candidate_type (tree xhs)
+{
+ if (xhs == NULL_TREE)
+ return NULL;
+
+ if (TREE_CODE (xhs) == SSA_NAME || TREE_CODE (xhs) == COMPONENT_REF)
+ {
+ srtype *access_type = find_type (inner_type (TREE_TYPE (xhs)));
+ if (access_type != NULL && access_type->pc_candidate)
+ return access_type;
+ }
+ return NULL;
+}
+
+/* True if the input type is the candidate type for pointer compression. */
+
+bool
+ipa_struct_reorg::pc_candidate_st_type_p (tree type)
+{
+ if (type == NULL_TREE)
+ return false;
+
+ if (TREE_CODE (type) == POINTER_TYPE)
+ {
+ if (TREE_CODE (TREE_TYPE (type)) == RECORD_TYPE)
+ {
+ srtype *access_type = find_type (TREE_TYPE (type));
+ if (access_type != NULL && access_type->pc_candidate)
+ return true;
+ }
+ }
+ return false;
+}
+
+/* True if the input xhs is a candidate for pointer compression. */
+
+bool
+ipa_struct_reorg::pc_candidate_tree_p (tree xhs)
+{
+ if (xhs == NULL_TREE)
+ return false;
+
+ if (TREE_CODE (xhs) == COMPONENT_REF)
+ {
+ srtype *base_type = find_type (TREE_TYPE (TREE_OPERAND (xhs, 0)));
+ if (base_type == NULL || base_type->has_escaped ())
+ return false;
+
+ return pc_candidate_st_type_p (TREE_TYPE (xhs));
+ }
+ return false;
+}
+
+/* True if xhs is a component_ref that base has escaped but uses a compression
+ candidate type. */
+
+bool
+ipa_struct_reorg::pc_type_conversion_candidate_p (tree xhs)
+{
+ if (xhs == NULL_TREE)
+ return false;
+
+ if (TREE_CODE (xhs) == COMPONENT_REF)
+ {
+ srtype *base_type = find_type (TREE_TYPE (TREE_OPERAND (xhs, 0)));
+ if (base_type != NULL && base_type->has_escaped ())
+ return pc_candidate_st_type_p (TREE_TYPE (xhs));
+
+ }
+ return false;
+}
+
+/* Creates a new basic block with zero for compressed null pointers. */
+
+basic_block
+ipa_struct_reorg::create_bb_for_compress_nullptr (basic_block last_bb,
+ tree &phi)
+{
+ basic_block new_bb = create_empty_bb (last_bb);
+ if (last_bb->loop_father != NULL)
+ {
+ add_bb_to_loop (new_bb, last_bb->loop_father);
+ loops_state_set (LOOPS_NEED_FIXUP);
+ }
+
+ /* Emit phi = 0. */
+ gimple_stmt_iterator gsi = gsi_last_bb (new_bb);
+ phi = make_ssa_name (make_unsigned_type (compressed_size));
+ tree rhs = build_int_cst (make_unsigned_type (compressed_size), 0);
+ gimple *new_stmt = gimple_build_assign (phi, rhs);
+ gsi_insert_after (&gsi, new_stmt, GSI_NEW_STMT);
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "\nCreate bb %d for compress nullptr:\n",
+ new_bb->index);
+ gimple_dump_bb (dump_file, new_bb, 0, dump_flags);
+ }
+ return new_bb;
+}
+
+/* Create a new basic block to compress the pointer to the index relative to
+ the allocated memory pool header. */
+
+basic_block
+ipa_struct_reorg::create_bb_for_compress_candidate (basic_block last_bb,
+ tree new_rhs, srtype *type,
+ tree &phi)
+{
+ basic_block new_bb = create_empty_bb (last_bb);
+ if (last_bb->loop_father != NULL)
+ {
+ add_bb_to_loop (new_bb, last_bb->loop_father);
+ loops_state_set (LOOPS_NEED_FIXUP);
+ }
+
+ gimple_stmt_iterator gsi = gsi_last_bb (new_bb);
+ /* compress_ptr_to_offset () needs at least one stmt in target bb. */
+ gsi_insert_after (&gsi, gimple_build_nop (), GSI_NEW_STMT);
+ phi = compress_ptr_to_offset (new_rhs, type, &gsi);
+ /* Remove the NOP created above. */
+ gsi_remove (&gsi, true);
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "\nCreate bb %d for compress candidate:\n",
+ new_bb->index);
+ gimple_dump_bb (dump_file, new_bb, 0, dump_flags);
+ }
+ return new_bb;
+}
+
+/* Compression can be simplified by these following cases:
+ 1. if rhs is NULL, uses zero to represent it.
+ 2. if new_rhs has been converted into INTEGER_TYPE in the previous stmt,
+ just use it here. For example:
+ _1 = t->s
+ -> tt->s = _1. */
+
+bool
+ipa_struct_reorg::pc_direct_rewrite_chance_p (tree rhs, tree &new_rhs)
+{
+ if (integer_zerop (rhs))
+ {
+ new_rhs = build_int_cst (make_unsigned_type (compressed_size), 0);
+ return true;
+ }
+ else if (new_rhs && TREE_CODE (TREE_TYPE (new_rhs)) == INTEGER_TYPE)
+ {
+ return true;
+ }
+ return false;
+}
+
+/* Perform pointer compression with check. The conversion will be as shown in
+ the following example:
+ Orig bb:
+ bb <1>:
+ _1->t = _2
+
+ will be transformed to:
+ bb <1>:
+ _3 = _2
+ if (_2 == NULL)
+ goto bb <2>
+ else
+ goto bb <3>
+
+ bb <2>:
+ _3 = 0
+ goto bb <4>
+
+ bb <3>:
+ ...
+ _4 = compress (_2)
+ goto bb <4>
+
+ bb <4>:
+ _5 = PHI (_3, _4)
+ _1->t = _5
+ The gsi will move to the beginning of split dst bb <4>, _1->t = _5 will be
+ emitted by rewrite_assign (). */
+
+bool
+ipa_struct_reorg::compress_candidate_with_check (gimple_stmt_iterator *gsi,
+ tree rhs, tree &new_rhs)
+{
+ tree cond_lhs = make_ssa_name (TREE_TYPE (new_rhs));
+ gimple *assign_stmt = gimple_build_assign (cond_lhs, new_rhs);
+ gsi_insert_before (gsi, assign_stmt, GSI_SAME_STMT);
+
+ /* Insert cond stmt. */
+ tree rhs_pointer_type = build_pointer_type (TREE_TYPE (new_rhs));
+ gcond *cond = gimple_build_cond (EQ_EXPR, cond_lhs,
+ build_int_cst (rhs_pointer_type, 0),
+ NULL_TREE, NULL_TREE);
+ gimple_set_location (cond, UNKNOWN_LOCATION);
+ gsi_insert_before (gsi, cond, GSI_SAME_STMT);
+
+ gimple* cur_stmt = as_a <gimple *> (cond);
+ edge e = split_block (cur_stmt->bb, cur_stmt);
+ basic_block split_src_bb = e->src;
+ basic_block split_dst_bb = e->dest;
+
+ /* Create bb for nullptr. */
+ tree phi1 = NULL_TREE;
+ basic_block true_bb = create_bb_for_compress_nullptr (split_src_bb, phi1);
+
+ /* Create bb for comprssion. */
+ srtype *type = get_compression_candidate_type (rhs);
+ gcc_assert (type != NULL);
+ tree phi2 = NULL_TREE;
+ basic_block false_bb = create_bb_for_compress_candidate (true_bb, new_rhs,
+ type, phi2);
+
+ /* Rebuild and reset cfg. */
+ remove_edge_raw (e);
+
+ edge etrue = make_edge (split_src_bb, true_bb, EDGE_TRUE_VALUE);
+ etrue->probability = profile_probability::unlikely ();
+ true_bb->count = etrue->count ();
+
+ edge efalse = make_edge (split_src_bb, false_bb, EDGE_FALSE_VALUE);
+ efalse->probability = profile_probability::likely ();
+ false_bb->count = efalse->count ();
+
+ edge e1 = make_single_succ_edge (true_bb, split_dst_bb, EDGE_FALLTHRU);
+ edge e2 = make_single_succ_edge (false_bb, split_dst_bb, EDGE_FALLTHRU);
+
+ tree phi = make_ssa_name (make_unsigned_type (compressed_size));
+ gphi *phi_node = create_phi_node (phi, split_dst_bb);
+ add_phi_arg (phi_node, phi1, e1, UNKNOWN_LOCATION);
+ add_phi_arg (phi_node, phi2, e2, UNKNOWN_LOCATION);
+
+ if (dom_info_available_p (CDI_DOMINATORS))
+ {
+ set_immediate_dominator (CDI_DOMINATORS, split_dst_bb, split_src_bb);
+ set_immediate_dominator (CDI_DOMINATORS, true_bb, split_src_bb);
+ set_immediate_dominator (CDI_DOMINATORS, false_bb, split_src_bb);
+ }
+ *gsi = gsi_start_bb (split_dst_bb);
+ new_rhs = phi;
+ return true;
+}
+
+/* If there is a direct rewrite chance or simplification opportunity, perform
+ the simplified compression rewrite. Otherwise, create a cond expression and
+ two basic blocks to implement pointer compression. */
+
+bool
+ipa_struct_reorg::compress_candidate (gassign *stmt, gimple_stmt_iterator *gsi,
+ tree rhs, tree &new_rhs)
+{
+ if (pc_direct_rewrite_chance_p (rhs, new_rhs))
+ return true;
+
+ return compress_candidate_with_check (gsi, rhs, new_rhs);
+}
+
+/* Create a new basic block to decompress the index to null pointer. */
+
+basic_block
+ipa_struct_reorg::create_bb_for_decompress_nullptr (basic_block last_bb,
+ tree new_rhs,
+ tree &phi_node)
+{
+ basic_block new_bb = create_empty_bb (last_bb);
+ if (last_bb->loop_father != NULL)
+ {
+ add_bb_to_loop (new_bb, last_bb->loop_father);
+ loops_state_set (LOOPS_NEED_FIXUP);
+ }
+ gimple_stmt_iterator gsi = gsi_last_bb (new_bb);
+ tree rhs_pointer_type = build_pointer_type (TREE_TYPE (new_rhs));
+ phi_node = make_ssa_name (rhs_pointer_type);
+ gimple *new_stmt = gimple_build_assign (phi_node,
+ build_int_cst (rhs_pointer_type, 0));
+ gsi_insert_after (&gsi, new_stmt, GSI_NEW_STMT);
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "\nCreate bb %d for decompress nullptr:\n",
+ new_bb->index);
+ gimple_dump_bb (dump_file, new_bb, 0, dump_flags);
+ }
+ return new_bb;
+}
+
+/* Create a new basic block to decompress the index into original pointer. */
+
+basic_block
+ipa_struct_reorg::create_bb_for_decompress_candidate (basic_block last_bb,
+ tree lhs, srtype *type,
+ tree &phi_node)
+{
+ basic_block new_bb = create_empty_bb (last_bb);
+ if (last_bb->loop_father != NULL)
+ {
+ add_bb_to_loop (new_bb, last_bb->loop_father);
+ loops_state_set (LOOPS_NEED_FIXUP);
+ }
+ gimple_stmt_iterator gsi = gsi_last_bb (new_bb);
+ /* decompress_ptr_to_offset () needs at least one stmt in target bb. */
+ gsi_insert_after (&gsi, gimple_build_nop (), GSI_NEW_STMT);
+ phi_node = decompress_offset_to_ptr (lhs, type, &gsi);
+ /* Remove the NOP created above. */
+ gsi_remove (&gsi, true);
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "\nCreate bb %d for decompress candidate:\n",
+ new_bb->index);
+ gimple_dump_bb (dump_file, new_bb, 0, dump_flags);
+ }
+ return new_bb;
+}
+
+/* Perform pointer decompression with check. The conversion will be as shown
+ in the following example:
+ Orig bb:
+ bb <1>:
+ _1 = _2->t
+
+ will be transformed to:
+ bb <1>:
+ _3 = _2->t
+ if (_3 == 0)
+ goto bb <2>
+ else
+ goto bb <3>
+
+ bb <2>:
+ _4 = NULL
+ goto bb <4>
+
+ bb <3>:
+ ...
+ _5 = decompress (_3)
+ goto bb <4>
+
+ bb <4>:
+ _6 = PHI (_4, _5)
+ _1 = _6
+ The gsi will move to the beginning of split dst bb <4>, _1 = _6 will be
+ emitted by rewrite_assign (). */
+
+bool
+ipa_struct_reorg::decompress_candidate_with_check (gimple_stmt_iterator *gsi,
+ tree rhs, tree &new_rhs)
+{
+ /* Insert cond stmt. */
+ tree cond_lhs = make_ssa_name (TREE_TYPE (new_rhs));
+ gassign *cond_assign = gimple_build_assign (cond_lhs, new_rhs);
+ gsi_insert_before (gsi, cond_assign, GSI_SAME_STMT);
+
+ tree pc_type = make_unsigned_type (compressed_size);
+ gcond *cond = gimple_build_cond (EQ_EXPR, cond_lhs,
+ build_int_cst (pc_type, 0),
+ NULL_TREE, NULL_TREE);
+ gimple_set_location (cond, UNKNOWN_LOCATION);
+ gsi_insert_before (gsi, cond, GSI_SAME_STMT);
+
+ /* Split bb. */
+ gimple* cur_stmt = as_a <gimple *> (cond);
+ edge e = split_block (cur_stmt->bb, cur_stmt);
+ basic_block split_src_bb = e->src;
+ basic_block split_dst_bb = e->dest;
+
+ /* Create bb for decompress nullptr. */
+ tree phi1 = NULL_TREE;
+ basic_block true_bb = create_bb_for_decompress_nullptr (split_src_bb,
+ new_rhs, phi1);
+
+ /* Create bb for decomprssion candidate. */
+ tree phi2 = NULL_TREE;
+ srtype *type = get_compression_candidate_type (rhs);
+ gcc_assert (type != NULL);
+ basic_block false_bb = create_bb_for_decompress_candidate (true_bb, cond_lhs,
+ type, phi2);
+
+ /* Refresh and reset cfg. */
+ remove_edge_raw (e);
+
+ edge etrue = make_edge (split_src_bb, true_bb, EDGE_TRUE_VALUE);
+ etrue->probability = profile_probability::unlikely ();
+ true_bb->count = etrue->count ();
+
+ edge efalse = make_edge (split_src_bb, false_bb, EDGE_FALSE_VALUE);
+ efalse->probability = profile_probability::likely ();
+ false_bb->count = efalse->count ();
+
+ edge e1 = make_single_succ_edge (true_bb, split_dst_bb, EDGE_FALLTHRU);
+ edge e2 = make_single_succ_edge (false_bb, split_dst_bb, EDGE_FALLTHRU);
+
+ tree phi = make_ssa_name (build_pointer_type (TREE_TYPE (cond_lhs)));
+ gphi *phi_node = create_phi_node (phi, split_dst_bb);
+ add_phi_arg (phi_node, phi1, e1, UNKNOWN_LOCATION);
+ add_phi_arg (phi_node, phi2, e2, UNKNOWN_LOCATION);
+
+ if (dom_info_available_p (CDI_DOMINATORS))
+ {
+ set_immediate_dominator (CDI_DOMINATORS, split_dst_bb, split_src_bb);
+ set_immediate_dominator (CDI_DOMINATORS, true_bb, split_src_bb);
+ set_immediate_dominator (CDI_DOMINATORS, false_bb, split_src_bb);
+ }
+ *gsi = gsi_start_bb (split_dst_bb);
+ new_rhs = phi;
+ return true;
+}
+
+/* If there is a simplification opportunity, perform the simplified
+ decompression rewrite. Otherwise, create a cond expression and two basic
+ blocks to implement pointer decompression. */
+
+bool
+ipa_struct_reorg::decompress_candidate (gimple_stmt_iterator *gsi,
+ tree lhs, tree rhs, tree &new_lhs,
+ tree &new_rhs)
+{
+ // TODO: simplifiy check and rewrite will be pushed in next PR.
+ return decompress_candidate_with_check (gsi, rhs, new_rhs);
+}
+
+/* Try to perform pointer compression and decompression. */
+
+void
+ipa_struct_reorg::try_rewrite_with_pointer_compression (gassign *stmt,
+ gimple_stmt_iterator
+ *gsi, tree lhs,
+ tree rhs, tree &new_lhs,
+ tree &new_rhs)
+{
+ bool l = pc_candidate_tree_p (lhs);
+ bool r = pc_candidate_tree_p (rhs);
+ if (!l && !r)
+ {
+ tree tmp_rhs = new_rhs == NULL_TREE ? rhs : new_rhs;
+ if (pc_type_conversion_candidate_p (lhs))
+ {
+ /* Transfer MEM[(struct *)_1].files = _4;
+ to MEM[(struct *)_1].files = (struct *)_4; */
+ new_rhs = fold_convert (TREE_TYPE (lhs), tmp_rhs);
+ }
+ else if (pc_type_conversion_candidate_p (rhs))
+ {
+ /* Transfer _4 = MEM[(struct *)_1].nodes;
+ to _4 = (new_struct *) MEM[(struct *)_1].nodes; */
+ new_rhs = fold_convert (TREE_TYPE (new_lhs), tmp_rhs);
+ }
+ }
+ else if (l && r)
+ gcc_unreachable ();
+ else if (l)
+ {
+ if (!compress_candidate (stmt, gsi, rhs, new_rhs))
+ gcc_unreachable ();
+ }
+ else if (r)
+ {
+ if (!decompress_candidate (gsi, lhs, rhs, new_lhs, new_rhs))
+ gcc_unreachable ();
+ }
+}
+
bool
ipa_struct_reorg::rewrite_assign (gassign *stmt, gimple_stmt_iterator *gsi)
{
@@ -6109,6 +6780,9 @@ ipa_struct_reorg::rewrite_assign (gassign *stmt, gimple_stmt_iterator *gsi)
fprintf (dump_file, "replaced with:\n");
for (unsigned i = 0; i < max_split && (newlhs[i] || newrhs[i]); i++)
{
+ if (current_layout_opt_level >= POINTER_COMPRESSION_SAFE)
+ try_rewrite_with_pointer_compression (stmt, gsi, lhs, rhs,
+ newlhs[i], newrhs[i]);
gimple *newstmt = gimple_build_assign (newlhs[i] ? newlhs[i] : lhs, newrhs[i] ? newrhs[i] : rhs);
if (dump_file && (dump_flags & TDF_DETAILS))
{
@@ -6183,6 +6857,13 @@ ipa_struct_reorg::rewrite_call (gcall *stmt, gimple_stmt_iterator *gsi)
gcc_assert (false);
gimple_call_set_lhs (g, decl->newdecl[i]);
gsi_insert_before (gsi, g, GSI_SAME_STMT);
+ if (type->pc_candidate)
+ {
+ /* Init global header for pointer compression. */
+ gassign *gptr
+ = gimple_build_assign (type->pc_gptr, decl->newdecl[i]);
+ gsi_insert_before (gsi, gptr, GSI_SAME_STMT);
+ }
}
return true;
}
@@ -6649,6 +7330,12 @@ ipa_struct_reorg::rewrite_functions (void)
push_cfun (DECL_STRUCT_FUNCTION (node->decl));
current_function = f;
+ if (current_layout_opt_level >= POINTER_COMPRESSION_SAFE)
+ {
+ calculate_dominance_info (CDI_DOMINATORS);
+ loop_optimizer_init (0);
+ }
+
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "\nBefore rewrite: %dth_%s\n",
@@ -6724,6 +7411,9 @@ ipa_struct_reorg::rewrite_functions (void)
free_dominance_info (CDI_DOMINATORS);
+ if (current_layout_opt_level >= POINTER_COMPRESSION_SAFE)
+ loop_optimizer_finalize ();
+
if (dump_file)
{
fprintf (dump_file, "\nAfter rewrite: %dth_%s\n",
@@ -6758,6 +7448,10 @@ ipa_struct_reorg::execute_struct_relayout (void)
{
continue;
}
+ if (get_type_name (types[i]->type) == NULL)
+ {
+ continue;
+ }
retval |= ipa_struct_relayout (type, this).execute ();
}
@@ -6778,6 +7472,132 @@ ipa_struct_reorg::execute_struct_relayout (void)
return retval;
}
+
+/* True if the var with void type is only used to compare with the same
+ target type. */
+
+bool
+ipa_struct_reorg::safe_void_cmp_p (tree var, srtype *type)
+{
+ imm_use_iterator imm_iter;
+ use_operand_p use_p;
+ FOR_EACH_IMM_USE_FAST (use_p, imm_iter, var)
+ {
+ gimple *use_stmt = USE_STMT (use_p);
+ if (is_gimple_debug (use_stmt))
+ continue;
+
+ if (gimple_code (use_stmt) == GIMPLE_COND)
+ {
+ tree lhs = gimple_cond_lhs (use_stmt);
+ tree rhs = gimple_cond_rhs (use_stmt);
+ tree xhs = lhs == var ? rhs : lhs;
+ if (types_compatible_p (inner_type (TREE_TYPE (xhs)), type->type))
+ continue;
+
+ }
+ return false;
+ }
+ return true;
+}
+
+/* Mark the structure that should perform pointer compression. */
+
+void
+ipa_struct_reorg::check_and_prune_struct_for_pointer_compression (void)
+{
+ unsigned pc_transform_num = 0;
+
+ if (dump_file)
+ fprintf (dump_file, "\nMark the structure that should perform pointer"
+ " compression:\n");
+
+ for (unsigned i = 0; i < types.length (); i++)
+ {
+ srtype *type = types[i];
+ if (dump_file)
+ print_generic_expr (dump_file, type->type);
+
+ if (type->has_escaped ())
+ {
+ if (dump_file)
+ fprintf (dump_file, " has escaped by %s, skip compression.\n",
+ type->escape_reason ());
+ continue;
+ }
+ if (TYPE_FIELDS (type->type) == NULL)
+ {
+ if (dump_file)
+ fprintf (dump_file, " has zero field, skip compression.\n");
+ continue;
+ }
+ if (type->chain_type)
+ {
+ if (dump_file)
+ fprintf (dump_file, " is chain_type, skip compression.\n");
+ continue;
+ }
+ if (type->has_alloc_array != 1)
+ {
+ if (dump_file)
+ fprintf (dump_file, " has alloc number: %d, skip compression.\n",
+ type->has_alloc_array);
+ continue;
+ }
+ if (get_type_name (type->type) == NULL)
+ {
+ if (dump_file)
+ fprintf (dump_file, " has empty struct name,"
+ " skip compression.\n");
+ continue;
+ }
+ if ((current_layout_opt_level & POINTER_COMPRESSION_SAFE)
+ && !type->has_legal_alloc_num)
+ {
+ if (dump_file)
+ fprintf (dump_file, " has illegal struct array size,"
+ " skip compression.\n");
+ continue;
+ }
+ pc_transform_num++;
+ type->pc_candidate = true;
+ if (dump_file)
+ fprintf (dump_file, " attemps to do pointer compression.\n");
+ }
+
+ if (dump_file)
+ {
+ if (pc_transform_num)
+ fprintf (dump_file, "\nNumber of structures to transform in "
+ "pointer compression is %d\n", pc_transform_num);
+ else
+ fprintf (dump_file, "\nNo structures to transform in "
+ "pointer compression.\n");
+ }
+}
+
+/* Init pointer size from parameter param_pointer_compression_size. */
+
+static void
+init_pointer_size_for_pointer_compression (void)
+{
+ switch (param_pointer_compression_size)
+ {
+ case 8:
+ compressed_size = 8; // sizeof (uint8)
+ break;
+ case 16:
+ compressed_size = 16; // sizeof (uint16)
+ break;
+ case 32:
+ compressed_size = 32; // sizeof (uint32)
+ break;
+ default:
+ error ("Invalid pointer compression size, using the following param: "
+ "\"--param pointer-compression-size=[8,16,32]\"");
+ }
+}
+
unsigned int
ipa_struct_reorg::execute (unsigned int opt)
{
@@ -6798,6 +7618,8 @@ ipa_struct_reorg::execute (unsigned int opt)
{
analyze_types ();
}
+ if (opt >= POINTER_COMPRESSION_SAFE)
+ check_and_prune_struct_for_pointer_compression ();
ret = rewrite_functions ();
}
@@ -6850,6 +7672,8 @@ public:
unsigned int level = 0;
switch (struct_layout_optimize_level)
{
+ case 4: level |= POINTER_COMPRESSION_SAFE;
+ // FALLTHRU
case 3: level |= DEAD_FIELD_ELIMINATION;
// FALLTHRU
case 2: level |= STRUCT_REORDER_FIELDS;
@@ -6862,6 +7686,9 @@ public:
default: gcc_unreachable ();
}
+ if (level & POINTER_COMPRESSION_SAFE)
+ init_pointer_size_for_pointer_compression ();
+
/* Preserved for backward compatibility, reorder fields needs run before
struct split and complete struct relayout. */
if (flag_ipa_reorder_fields && level < STRUCT_REORDER_FIELDS)
diff --git a/gcc/ipa-struct-reorg/ipa-struct-reorg.h b/gcc/ipa-struct-reorg/ipa-struct-reorg.h
index 936c0fa6f..d88799982 100644
--- a/gcc/ipa-struct-reorg/ipa-struct-reorg.h
+++ b/gcc/ipa-struct-reorg/ipa-struct-reorg.h
@@ -122,7 +122,10 @@ private:
public:
tree newtype[max_split];
+ tree pc_gptr;
bool visited;
+ bool pc_candidate;
+ bool has_legal_alloc_num;
int has_alloc_array;
// Constructors
@@ -144,6 +147,7 @@ public:
void analyze (void);
bool has_dead_field (void);
void mark_escape (escape_type, gimple *stmt);
+ void create_global_ptr_for_pc ();
bool has_escaped (void)
{
return escapes != does_not_escape;
diff --git a/gcc/params.opt b/gcc/params.opt
index 9d1faa7ab..1d355819c 100644
--- a/gcc/params.opt
+++ b/gcc/params.opt
@@ -984,4 +984,8 @@ High execution rate loops to be analyzed in prefetch (in%).
Common Joined UInteger Var(param_prefetch_func_counts_threshold) Init(100) Param Optimization
Threshold functions of cache miss counts to be analyzed in prefetching.
+-param=compressed-pointer-size=
+Common Joined UInteger Var(param_pointer_compression_size) Init(32) IntegerRange(8, 32) Param Optimization
+Target size of compressed pointer, which should be 8, 16 or 32.
+
; This comment is to ensure we retain the blank line above.
--
2.27.0.windows.1
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/wangding16/src-gcc.git
git@gitee.com:wangding16/src-gcc.git
wangding16
src-gcc
src-gcc
master

搜索帮助