This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Little infrastructure for IP constant propagation
- From: Jan Hubicka <jh at suse dot cz>
- To: gcc-patches at gcc dot gnu dot org, rguenther at suse dot de
- Date: Sat, 23 Aug 2008 21:33:23 +0200
- Subject: Little infrastructure for IP constant propagation
Hi,
at the moment IPCP is propagating just selected FUNCTION_DECLs constants etc.
This patch adds is_gimple_ip_invariant check that is equivalent to is_gimple_min_invariant
but verify that value is invariant at interprocedural level; in particular that no addresses
of local variables are involved.
Bootstrapped/regtested with IP-CP using this predicate. OK?
Honza
* tree.c (decl_address_ip_invariant_p): New function.
* tree.h (decl_address_ip_invariant_p): Declare.
* gimple.c (strip_invariant_refs): Break out from ...
(is_gimple_invariant_address): ... here
(is_gimple_ip_invariant_address): New function.
(is_gimple_ip_invariant): New function.
* gimple.h (is_gimple_ip_invariant_address, is_gimple_ip_invariant):
Declare.
Index: tree.c
===================================================================
*** tree.c (revision 139391)
--- tree.c (working copy)
*************** decl_address_invariant_p (const_tree op)
*** 2172,2177 ****
--- 2172,2211 ----
return false;
}
+ /* Return whether OP is a DECL whose address is interprocedural-invariant. */
+
+ bool
+ decl_address_ip_invariant_p (const_tree op)
+ {
+ /* The conditions below are slightly less strict than the one in
+ staticp. */
+
+ switch (TREE_CODE (op))
+ {
+ case LABEL_DECL:
+ case FUNCTION_DECL:
+ case STRING_CST:
+ return true;
+
+ case VAR_DECL:
+ if (((TREE_STATIC (op) || DECL_EXTERNAL (op))
+ && !DECL_DLLIMPORT_P (op))
+ || DECL_THREAD_LOCAL_P (op))
+ return true;
+ break;
+
+ case CONST_DECL:
+ if ((TREE_STATIC (op) || DECL_EXTERNAL (op)))
+ return true;
+ break;
+
+ default:
+ break;
+ }
+
+ return false;
+ }
+
/* Return true if T is function-invariant (internal function, does
not handle arithmetic; that's handled in skip_simple_arithmetic and
Index: tree.h
===================================================================
*** tree.h (revision 139391)
--- tree.h (working copy)
*************** extern tree strip_float_extensions (tree
*** 4868,4873 ****
--- 4868,4874 ----
/* In tree.c */
extern int really_constant_p (const_tree);
extern bool decl_address_invariant_p (const_tree);
+ extern bool decl_address_ip_invariant_p (const_tree);
extern int int_fits_type_p (const_tree, const_tree);
#ifndef GENERATOR_FILE
extern void get_type_static_bounds (const_tree, mpz_t, mpz_t);
Index: gimple.c
===================================================================
*** gimple.c (revision 139391)
--- gimple.c (working copy)
*************** is_gimple_address (const_tree t)
*** 2730,2746 ****
}
}
! /* Return true if T is a gimple invariant address. */
! bool
! is_gimple_invariant_address (const_tree t)
{
- tree op;
-
- if (TREE_CODE (t) != ADDR_EXPR)
- return false;
-
- op = TREE_OPERAND (t, 0);
while (handled_component_p (op))
{
switch (TREE_CODE (op))
--- 2730,2741 ----
}
}
! /* Strip out all handled components that produce invariant
! offsets. */
! static const_tree
! strip_invariant_refs (const_tree op)
{
while (handled_component_p (op))
{
switch (TREE_CODE (op))
*************** is_gimple_invariant_address (const_tree
*** 2750,2761 ****
if (!is_gimple_constant (TREE_OPERAND (op, 1))
|| TREE_OPERAND (op, 2) != NULL_TREE
|| TREE_OPERAND (op, 3) != NULL_TREE)
! return false;
break;
case COMPONENT_REF:
if (TREE_OPERAND (op, 2) != NULL_TREE)
! return false;
break;
default:;
--- 2745,2756 ----
if (!is_gimple_constant (TREE_OPERAND (op, 1))
|| TREE_OPERAND (op, 2) != NULL_TREE
|| TREE_OPERAND (op, 3) != NULL_TREE)
! return NULL;
break;
case COMPONENT_REF:
if (TREE_OPERAND (op, 2) != NULL_TREE)
! return NULL;
break;
default:;
*************** is_gimple_invariant_address (const_tree
*** 2763,2769 ****
op = TREE_OPERAND (op, 0);
}
! return CONSTANT_CLASS_P (op) || decl_address_invariant_p (op);
}
/* Return true if T is a GIMPLE minimal invariant. It's a restricted
--- 2758,2795 ----
op = TREE_OPERAND (op, 0);
}
! return op;
! }
!
! /* Return true if T is a gimple invariant address. */
!
! bool
! is_gimple_invariant_address (const_tree t)
! {
! const_tree op;
!
! if (TREE_CODE (t) != ADDR_EXPR)
! return false;
!
! op = strip_invariant_refs (TREE_OPERAND (t, 0));
!
! return op && (CONSTANT_CLASS_P (op) || decl_address_invariant_p (op));
! }
!
! /* Return true if T is a gimple invariant address at IPA level
! (so addresses of variables on stack are not allowed). */
!
! bool
! is_gimple_ip_invariant_address (const_tree t)
! {
! const_tree op;
!
! if (TREE_CODE (t) != ADDR_EXPR)
! return false;
!
! op = strip_invariant_refs (TREE_OPERAND (t, 0));
!
! return op && (CONSTANT_CLASS_P (op) || decl_address_ip_invariant_p (op));
}
/* Return true if T is a GIMPLE minimal invariant. It's a restricted
*************** is_gimple_min_invariant (const_tree t)
*** 2778,2783 ****
--- 2804,2821 ----
return is_gimple_constant (t);
}
+ /* Return true if T is a GIMPLE interprocedural invariant. It's a restricted
+ form of gimple minimal invariant. */
+
+ bool
+ is_gimple_ip_invariant (const_tree t)
+ {
+ if (TREE_CODE (t) == ADDR_EXPR)
+ return is_gimple_ip_invariant_address (t);
+
+ return is_gimple_constant (t);
+ }
+
/* Return true if T looks like a valid GIMPLE statement. */
bool
Index: gimple.h
===================================================================
*** gimple.h (revision 139391)
--- gimple.h (working copy)
*************** extern bool is_gimple_lvalue (tree);
*** 872,881 ****
--- 872,886 ----
bool is_gimple_address (const_tree);
/* Returns true iff T is a GIMPLE invariant address. */
bool is_gimple_invariant_address (const_tree);
+ /* Returns true iff T is a GIMPLE invariant address at interprocedural
+ level. */
+ bool is_gimple_ip_invariant_address (const_tree);
/* Returns true iff T is a valid GIMPLE constant. */
bool is_gimple_constant (const_tree);
/* Returns true iff T is a GIMPLE restricted function invariant. */
extern bool is_gimple_min_invariant (const_tree);
+ /* Returns true iff T is a GIMPLE restricted interprecodural invariant. */
+ extern bool is_gimple_ip_invariant (const_tree);
/* Returns true iff T is a GIMPLE rvalue. */
extern bool is_gimple_val (tree);
/* Returns true iff T is a GIMPLE asm statement input. */