summaryrefslogtreecommitdiff
path: root/gcc/ada/exp_pakd.adb
diff options
context:
space:
mode:
authorbosch <bosch@138bc75d-0d04-0410-961f-82ee72b054a4>2001-12-11 22:11:45 +0000
committerbosch <bosch@138bc75d-0d04-0410-961f-82ee72b054a4>2001-12-11 22:11:45 +0000
commitc2b56224d60d27cd619e50d0a5250219ea251975 (patch)
tree9a2ec6960caa6e0b10445d061c7f8838db87d84c /gcc/ada/exp_pakd.adb
parent57f302e522c72c1aa7848b435f7c890aadb437d7 (diff)
downloadgcc-c2b56224d60d27cd619e50d0a5250219ea251975.tar.gz
* einfo.ads: Minor reformatting
* exp_ch5.adb: Add comment for previous.change * ali.adb: New interface for extended typeref stuff. * ali.ads: New interface for typeref stuff. * checks.adb (Apply_Alignment_Check): New procedure. * debug.adb: Add -gnatdM for modified ALI output * exp_pakd.adb (Known_Aligned_Enough): Replaces Known_Aligned_Enough. * lib-xref.adb: Extend generation of <..> notation to cover subtype/object types. Note that this is a complete rewrite, getting rid of the very nasty quadratic algorithm previously used for derived type output. * lib-xref.ads: Extend description of <..> notation to cover subtype/object types. Uses {..} for these other cases. Also use (..) for pointer types. * sem_util.adb (Check_Potentially_Blocking_Operation): Slight cleanup. * exp_pakd.adb: Minor reformatting. Note that prevous RH should say: (Known_Aligned_Enough): Replaces Must_Be_Aligned. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@47896 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/ada/exp_pakd.adb')
-rw-r--r--gcc/ada/exp_pakd.adb133
1 files changed, 130 insertions, 3 deletions
diff --git a/gcc/ada/exp_pakd.adb b/gcc/ada/exp_pakd.adb
index 2cc4f255473..5656569669c 100644
--- a/gcc/ada/exp_pakd.adb
+++ b/gcc/ada/exp_pakd.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- $Revision: 1.125 $
+-- $Revision$
-- --
-- Copyright (C) 1992-2001 Free Software Foundation, Inc. --
-- --
@@ -453,6 +453,16 @@ package body Exp_Pakd is
-- expression whose type is the implementation type used to represent
-- the packed array. Aexp is analyzed and resolved on entry and on exit.
+ function Known_Aligned_Enough (Obj : Node_Id; Csiz : Nat) return Boolean;
+ -- There are two versions of the Set routines, the ones used when the
+ -- object is known to be sufficiently well aligned given the number of
+ -- bits, and the ones used when the object is not known to be aligned.
+ -- This routine is used to determine which set to use. Obj is a reference
+ -- to the object, and Csiz is the component size of the packed array.
+ -- True is returned if the alignment of object is known to be sufficient,
+ -- defined as 1 for odd bit sizes, 4 for bit sizes divisible by 4, and
+ -- 2 otherwise.
+
function Make_Shift_Left (N : Node_Id; S : Node_Id) return Node_Id;
-- Build a left shift node, checking for the case of a shift count of zero
@@ -1426,7 +1436,7 @@ package body Exp_Pakd is
-- Acquire proper Set entity. We use the aligned or unaligned
-- case as appropriate.
- if Must_Be_Aligned (Obj) then
+ if Known_Aligned_Enough (Obj, Csiz) then
Set_nn := RTE (Set_Id (Csiz));
else
Set_nn := RTE (SetU_Id (Csiz));
@@ -1816,7 +1826,7 @@ package body Exp_Pakd is
-- Acquire proper Get entity. We use the aligned or unaligned
-- case as appropriate.
- if Must_Be_Aligned (Obj) then
+ if Known_Aligned_Enough (Obj, Csiz) then
Get_nn := RTE (Get_Id (Csiz));
else
Get_nn := RTE (GetU_Id (Csiz));
@@ -2088,6 +2098,122 @@ package body Exp_Pakd is
end if;
end Involves_Packed_Array_Reference;
+ --------------------------
+ -- Known_Aligned_Enough --
+ --------------------------
+
+ function Known_Aligned_Enough (Obj : Node_Id; Csiz : Nat) return Boolean is
+ Typ : constant Entity_Id := Etype (Obj);
+
+ function In_Partially_Packed_Record (Comp : Entity_Id) return Boolean;
+ -- If the component is in a record that contains previous packed
+ -- components, consider it unaligned because the back-end might
+ -- choose to pack the rest of the record. Lead to less efficient code,
+ -- but safer vis-a-vis of back-end choices.
+
+ --------------------------------
+ -- In_Partially_Packed_Record --
+ --------------------------------
+
+ function In_Partially_Packed_Record (Comp : Entity_Id) return Boolean is
+ Rec_Type : constant Entity_Id := Scope (Comp);
+ Prev_Comp : Entity_Id;
+
+ begin
+ Prev_Comp := First_Entity (Rec_Type);
+ while Present (Prev_Comp) loop
+ if Is_Packed (Etype (Prev_Comp)) then
+ return True;
+
+ elsif Prev_Comp = Comp then
+ return False;
+ end if;
+
+ Next_Entity (Prev_Comp);
+ end loop;
+
+ return False;
+ end In_Partially_Packed_Record;
+
+ -- Start of processing for Known_Aligned_Enough
+
+ begin
+ -- Odd bit sizes don't need alignment anyway
+
+ if Csiz mod 2 = 1 then
+ return True;
+
+ -- If we have a specified alignment, see if it is sufficient, if not
+ -- then we can't possibly be aligned enough in any case.
+
+ elsif Is_Entity_Name (Obj)
+ and then Known_Alignment (Entity (Obj))
+ then
+ -- Alignment required is 4 if size is a multiple of 4, and
+ -- 2 otherwise (e.g. 12 bits requires 4, 10 bits requires 2)
+
+ if Alignment (Entity (Obj)) < 4 - (Csiz mod 4) then
+ return False;
+ end if;
+ end if;
+
+ -- OK, alignment should be sufficient, if object is aligned
+
+ -- If object is strictly aligned, then it is definitely aligned
+
+ if Strict_Alignment (Typ) then
+ return True;
+
+ -- Case of subscripted array reference
+
+ elsif Nkind (Obj) = N_Indexed_Component then
+
+ -- If we have a pointer to an array, then this is definitely
+ -- aligned, because pointers always point to aligned versions.
+
+ if Is_Access_Type (Etype (Prefix (Obj))) then
+ return True;
+
+ -- Otherwise, go look at the prefix
+
+ else
+ return Known_Aligned_Enough (Prefix (Obj), Csiz);
+ end if;
+
+ -- Case of record field
+
+ elsif Nkind (Obj) = N_Selected_Component then
+
+ -- What is significant here is whether the record type is packed
+
+ if Is_Record_Type (Etype (Prefix (Obj)))
+ and then Is_Packed (Etype (Prefix (Obj)))
+ then
+ return False;
+
+ -- Or the component has a component clause which might cause
+ -- the component to become unaligned (we can't tell if the
+ -- backend is doing alignment computations).
+
+ elsif Present (Component_Clause (Entity (Selector_Name (Obj)))) then
+ return False;
+
+ elsif In_Partially_Packed_Record (Entity (Selector_Name (Obj))) then
+ return False;
+
+ -- In all other cases, go look at prefix
+
+ else
+ return Known_Aligned_Enough (Prefix (Obj), Csiz);
+ end if;
+
+ -- If not selected or indexed component, must be aligned
+
+ else
+ return True;
+ end if;
+ end Known_Aligned_Enough;
+
---------------------
-- Make_Shift_Left --
---------------------
@@ -2184,6 +2310,7 @@ package body Exp_Pakd is
-- All we have to do here is to find the subscripts that correspond
-- to the index positions that have non-standard enumeration types
-- and insert a Pos attribute to get the proper subscript value.
+
-- Finally the prefix must be uncheck converted to the corresponding
-- packed array type.