[llvm-commits] CVS: llvm-gcc/gcc/llvm-representation.h llvm-types.c

Chris Lattner lattner at cs.uiuc.edu
Fri Jul 22 11:53:49 PDT 2005



Changes in directory llvm-gcc/gcc:

llvm-representation.h updated: 1.17 -> 1.18
llvm-types.c updated: 1.23 -> 1.24
---
Log message:

Two changes: 
  1. fix some warnings in llvm-types.c
  2. Add the ability to determine the alignment of llvm-types as the LLVM
     code generator will see them.  This will be used in the future.

No functionality change here.



---
Diffs of the changes:  (+106 -4)

 llvm-representation.h |   10 ++++-
 llvm-types.c          |  100 ++++++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 106 insertions(+), 4 deletions(-)


Index: llvm-gcc/gcc/llvm-representation.h
diff -u llvm-gcc/gcc/llvm-representation.h:1.17 llvm-gcc/gcc/llvm-representation.h:1.18
--- llvm-gcc/gcc/llvm-representation.h:1.17	Thu Jul  7 12:32:46 2005
+++ llvm-gcc/gcc/llvm-representation.h	Fri Jul 22 13:53:38 2005
@@ -392,7 +392,8 @@
     struct {
       char *TypeName;          /* Name given to the type */
       unsigned Size;           /* The size (in bytes) of the structure */
-
+      unsigned Alignment;      /* The LLVM alignment of the struct */
+      
       /* MemberOffsets - If non-null, contains an entry for each type element
        * with its offset from start of the structure.
        */
@@ -400,6 +401,7 @@
     } Struct;
     struct {
       unsigned Size;           /* Number of elements in the array */
+      unsigned Alignment;      /* LLVM Alignment of the type */
     } Array;
     struct {
       char *TypeName;          /* Name given to opaque struct type */
@@ -433,6 +435,12 @@
 
 unsigned llvm_type_get_size(llvm_type *Ty);
 
+/* llvm_type_get_alignment - Return the alignment of the specified LLVM type as
+ * it will be handled by the target.  Note that LLVM types may be less aligned
+ * than the corresponding C types.
+ */
+unsigned llvm_type_get_alignment(llvm_type *Ty);
+
 unsigned llvm_type_get_composite_num_elements(llvm_type *Ty);
 llvm_type *llvm_type_get_composite_element(llvm_type *Ty, unsigned N);
 llvm_type *llvm_type_get_integer(unsigned NumBits, int isUnsigned);


Index: llvm-gcc/gcc/llvm-types.c
diff -u llvm-gcc/gcc/llvm-types.c:1.23 llvm-gcc/gcc/llvm-types.c:1.24
--- llvm-gcc/gcc/llvm-types.c:1.23	Sat Jun 18 16:11:20 2005
+++ llvm-gcc/gcc/llvm-types.c	Fri Jul 22 13:53:38 2005
@@ -27,6 +27,7 @@
 #include "llvm-representation.h"
 #include "llvm-internals.h"
 #include "hashtab.h"
+#include "langhooks.h"
 #include <assert.h>
 #include <string.h>
 
@@ -69,6 +70,84 @@
   }
 }
 
+/* PrimitiveAlignments - This contains the alignments of all of the primitive
+ * LLVM types on this target.
+ */
+static unsigned PrimitiveAlignments[OpaqueTyID];
+
+static unsigned getMinTargetAlignment(tree Type) {
+  unsigned BasicAlignment = TYPE_ALIGN(Type);
+  unsigned TestAlignment;
+  
+  /* Some targets do funny things with structs.  Form a struct that has a
+   * character member as the first element, then Type as the second element.
+   * If that alignment is less than BasicAlignment, use it.
+   */
+  tree recordtype = (*lang_hooks.types.make_type) (RECORD_TYPE);
+  tree field, fields;
+  /* First character field. */
+  fields = build_decl (FIELD_DECL, NULL_TREE, unsigned_intQI_type_node);
+
+  /* A field of type Type. */
+  field = build_decl (FIELD_DECL, NULL_TREE, Type);
+  TREE_CHAIN (field) = fields;
+  finish_builtin_struct(recordtype, "", field, NULL_TREE);
+
+  llvm_type_dump(llvm_type_get_from_tree(recordtype));
+  
+  TestAlignment = TYPE_ALIGN(recordtype);
+  BasicAlignment = MIN(BasicAlignment, TestAlignment);
+  return BasicAlignment/8;
+}
+
+static void InitializeAlignments(void) {
+  /* Figure out the alignments of the primitive types. */
+  PrimitiveAlignments[BoolTyID]   = 1;
+  PrimitiveAlignments[SByteTyID]  = 1;
+  PrimitiveAlignments[UByteTyID]  = 1;
+  PrimitiveAlignments[ShortTyID]  = getMinTargetAlignment(intHI_type_node);
+  PrimitiveAlignments[UShortTyID] =
+    getMinTargetAlignment(unsigned_intHI_type_node);
+  PrimitiveAlignments[IntTyID]  = getMinTargetAlignment(intSI_type_node);
+  PrimitiveAlignments[UIntTyID] = 
+    getMinTargetAlignment(unsigned_intSI_type_node);
+  PrimitiveAlignments[LongTyID]  = getMinTargetAlignment(intDI_type_node);
+  PrimitiveAlignments[ULongTyID] =
+    getMinTargetAlignment(unsigned_intDI_type_node);
+  PrimitiveAlignments[FloatTyID] = getMinTargetAlignment(float_type_node);
+  PrimitiveAlignments[DoubleTyID]  = getMinTargetAlignment(double_type_node);
+  PrimitiveAlignments[PointerTyID] = getMinTargetAlignment(ptr_type_node);
+}
+
+unsigned llvm_type_get_alignment(llvm_type *Ty) {
+  switch (Ty->ID) {
+    case BoolTyID:   
+    case SByteTyID:  
+    case UByteTyID:  return 1;
+    case ShortTyID:  
+    case UShortTyID: 
+    case UIntTyID:   
+    case FloatTyID:  
+    case IntTyID:    
+    case ULongTyID:  
+    case LongTyID:   
+    case DoubleTyID:
+    case PointerTyID: {/* Target dependant pointer size */
+      static int AlignmentInited = 0;
+      if (AlignmentInited == 0) { AlignmentInited = 1; InitializeAlignments(); }
+      return PrimitiveAlignments[Ty->ID];
+    }
+    case ArrayTyID: return Ty->x.Array.Alignment;
+    case StructTyID: return Ty->x.Struct.Alignment;
+    default: 
+      fprintf(stderr, "ERROR: Type doesn't have size: ");
+      llvm_type_dump(Ty);
+      fprintf(stderr, "\n");
+      abort();
+  }
+}
+
+
 /* All of the primitive types... */
 static llvm_type TheVoidTy   = { VoidTyID, 0, {{0}}, 0, {0} };
 static llvm_type TheBoolTy   = { BoolTyID , 0, {{0}}, 0, {0} };
@@ -203,11 +282,11 @@
 
   /* Commonly used derived types... */
   VoidPtrTy = llvm_type_get_pointer(VoidTy);
-
   IntPtrTy = llvm_type_get_size(VoidPtrTy) == 4 ? IntTy : LongTy;
 }
 
 llvm_type *llvm_type_get_cannonical_struct(llvm_type *Ty) {
+  unsigned i, e, MaxAlignment;
   void **Slot = htab_find_slot(StructTable, Ty, INSERT);
   if (*Slot) {    /* Found a match! */
     if (*Slot != Ty) free(Ty);
@@ -220,6 +299,14 @@
   Ty->NextTypeLink = DerivedTypesList;
   DerivedTypesList = Ty;
 
+  /* Set the alignment of the struct as the max alignment of all members. */
+  MaxAlignment = 1;
+  for (i = 0, e = Ty->NumElements; i != e; ++i) {
+    unsigned EltAlign = llvm_type_get_alignment(Ty->Elements[i]);
+    if (EltAlign > MaxAlignment) MaxAlignment = EltAlign;
+  }
+  Ty->x.Struct.Alignment = MaxAlignment;
+
   /*printf("Created new type: "); DebugType(Ty); printf("\n"); */
   return *Slot = Ty;
 }
@@ -259,6 +346,11 @@
   Result->NumElements = 1;
   Result->Elements[0] = Ty;
   Result->x.Array.Size = NumElements;
+
+  /* Alignment of the array is alignment of the element. */
+  Result->x.Array.Alignment = llvm_type_get_alignment(Ty);
+  
+  /* Add array to list of arrays we have seen. */
   Result->NextTypeLink = ArrayTypesList;
   ArrayTypesList = Result;
   return Result;
@@ -304,6 +396,7 @@
 llvm_type *llvm_type_create_struct(unsigned NumElements, unsigned Size) {
   /* The amount of space  we need to allocate for the type */
   unsigned type_size;
+  llvm_type *Result;
 
   /*
    * Determine the amount of memory needed for the type.  Note that
@@ -313,7 +406,7 @@
   type_size += ((NumElements) ? (NumElements-1)*sizeof(llvm_type*) : 0);
 
   /* Do the memory allocation and type initialization. */
-  llvm_type * Result = (llvm_type*)xcalloc(1, type_size);
+  Result = (llvm_type*)xcalloc(1, type_size);
   Result->ID = StructTyID;
   Result->NumElements = NumElements;
   Result->x.Struct.Size = Size;
@@ -617,8 +710,9 @@
  * structure.
  */
 static unsigned GetFieldOffset(tree Field) {
+  unsigned Result;
   assert(DECL_FIELD_BIT_OFFSET(Field) != 0 && DECL_FIELD_OFFSET(Field) != 0);
-  unsigned Result = TREE_INT_CST_LOW(DECL_FIELD_BIT_OFFSET(Field));
+  Result = TREE_INT_CST_LOW(DECL_FIELD_BIT_OFFSET(Field));
   if (TREE_CODE(DECL_FIELD_OFFSET(Field)) == INTEGER_CST)
     Result += TREE_INT_CST_LOW(DECL_FIELD_OFFSET(Field))*8;
   return Result;






More information about the llvm-commits mailing list