[llvm-commits] [llvm-gcc-4.2] r74069 - in /llvm-gcc-4.2/trunk/gcc: llvm-convert.cpp llvm-internal.h

Duncan Sands baldrick at free.fr
Wed Jun 24 01:17:35 PDT 2009


Author: baldrick
Date: Wed Jun 24 03:17:34 2009
New Revision: 74069

URL: http://llvm.org/viewvc/llvm-project?rev=74069&view=rev
Log:
Add some trivial lvalue emission helpers, and reorder
the emission functions alphabetically.  Strip some
trailing whitespace.  No functionality change.

Modified:
    llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp
    llvm-gcc-4.2/trunk/gcc/llvm-internal.h

Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=74069&r1=74068&r2=74069&view=diff

==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Wed Jun 24 03:17:34 2009
@@ -1026,15 +1026,10 @@
 
   // Trivial Cases.
   case WITH_SIZE_EXPR:
-    // The address is the address of the operand.
-    LV = EmitLV(TREE_OPERAND(exp, 0));
+    LV = EmitLV_WITH_SIZE_EXPR(exp);
     break;
   case INDIRECT_REF:
-    // The lvalue is just the address.
-    LV = LValue(Emit(TREE_OPERAND(exp, 0), 0), expr_align(exp) / 8);
-    // Correct for implicit type conversion: INDIRECT_REF can be applied to a
-    // void*, resulting in a non-void type.
-    LV.Ptr = BitCastToType(LV.Ptr, ConvertType(TREE_TYPE(exp))->getPointerTo());
+    LV = EmitLV_INDIRECT_REF(exp);
     break;
   }
 
@@ -5877,85 +5872,91 @@
 //                         ... L-Value Expressions ...
 //===----------------------------------------------------------------------===//
 
-LValue TreeToLLVM::EmitLV_DECL(tree exp) {
-  if (TREE_CODE(exp) == PARM_DECL || TREE_CODE(exp) == VAR_DECL || 
-      TREE_CODE(exp) == CONST_DECL) {
-    // If a static var's type was incomplete when the decl was written,
-    // but the type is complete now, lay out the decl now.
-    if (DECL_SIZE(exp) == 0 && COMPLETE_OR_UNBOUND_ARRAY_TYPE_P(TREE_TYPE(exp))
-        && (TREE_STATIC(exp) || DECL_EXTERNAL(exp))) {
-      layout_decl(exp, 0);
-      
-      // This mirrors code in layout_decl for munging the RTL.  Here we actually
-      // emit a NEW declaration for the global variable, now that it has been
-      // laid out.  We then tell the compiler to "forward" any uses of the old
-      // global to this new one.
-      if (Value *Val = DECL_LLVM_IF_SET(exp)) {
-        //fprintf(stderr, "***\n*** SHOULD HANDLE GLOBAL VARIABLES!\n***\n");
-        //assert(0 && "Reimplement this with replace all uses!");
-#if 0
-        SET_DECL_LLVM(exp, 0);
-        // Create a new global variable declaration
-        llvm_assemble_external(exp);
-        V2GV(Val)->ForwardedGlobal = V2GV(DECL_LLVM(exp));
-#endif
-      }
-    }
-  }
+/// getFieldOffsetInBits - Return the offset (in bits) of a FIELD_DECL in a
+/// structure.
+static unsigned getFieldOffsetInBits(tree Field) {
+  assert(DECL_FIELD_BIT_OFFSET(Field) != 0 && DECL_FIELD_OFFSET(Field) != 0);
+  unsigned 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;
+}
 
-  assert(!isGimpleTemporary(exp) &&
-         "Cannot use a gimple temporary as an l-value");
-  
-  Value *Decl = DECL_LLVM(exp);
-  if (Decl == 0) {
-    if (errorcount || sorrycount) {
-      const Type *Ty = ConvertType(TREE_TYPE(exp));
-      const PointerType *PTy = PointerType::getUnqual(Ty);
-      LValue LV(ConstantPointerNull::get(PTy), 1);
-      return LV;
-    }
-    assert(0 && "INTERNAL ERROR: Referencing decl that hasn't been laid out");
-    abort();
-  }
-  
-  // Ensure variable marked as used even if it doesn't go through a parser.  If
-  // it hasn't been used yet, write out an external definition.
-  if (!TREE_USED(exp)) {
-    assemble_external(exp);
-    TREE_USED(exp) = 1;
-    Decl = DECL_LLVM(exp);
-  }
-  
-  if (GlobalValue *GV = dyn_cast<GlobalValue>(Decl)) {
-    // If this is an aggregate, emit it to LLVM now.  GCC happens to
-    // get this case right by forcing the initializer into memory.
-    if (TREE_CODE(exp) == CONST_DECL || TREE_CODE(exp) == VAR_DECL) {
-      if ((DECL_INITIAL(exp) || !TREE_PUBLIC(exp)) && !DECL_EXTERNAL(exp) &&
-          GV->isDeclaration() &&
-          !BOGUS_CTOR(exp)) {
-        emit_global_to_llvm(exp);
-        Decl = DECL_LLVM(exp);     // Decl could have change if it changed type.
-      }
-    } else {
-      // Otherwise, inform cgraph that we used the global.
-      mark_decl_referenced(exp);
-      if (tree ID = DECL_ASSEMBLER_NAME(exp))
-        mark_referenced(ID);
+/// getComponentRefOffsetInBits - Return the offset (in bits) of the field
+/// referenced in a COMPONENT_REF exp.
+static unsigned getComponentRefOffsetInBits(tree exp) {
+  assert(TREE_CODE(exp) == COMPONENT_REF && "not a COMPONENT_REF!");
+  tree field = TREE_OPERAND(exp, 1);
+  assert(TREE_CODE(field) == FIELD_DECL && "not a FIELD_DECL!");
+  tree field_offset = component_ref_field_offset (exp);
+  assert(DECL_FIELD_BIT_OFFSET(field) && field_offset);
+  unsigned Result = TREE_INT_CST_LOW(DECL_FIELD_BIT_OFFSET(field));
+  if (TREE_CODE(field_offset) == INTEGER_CST)
+    Result += TREE_INT_CST_LOW(field_offset)*8;
+  return Result;
+}
+
+Value *TreeToLLVM::EmitFieldAnnotation(Value *FieldPtr, tree FieldDecl) {
+  tree AnnotateAttr = lookup_attribute("annotate", DECL_ATTRIBUTES(FieldDecl));
+
+  const Type *OrigPtrTy = FieldPtr->getType();
+  const Type *SBP = PointerType::getUnqual(Type::Int8Ty);
+
+  Function *Fn = Intrinsic::getDeclaration(TheModule,
+                                           Intrinsic::ptr_annotation,
+                                           &SBP, 1);
+
+  // Get file and line number.  FIXME: Should this be for the decl or the
+  // use.  Is there a location info for the use?
+  Constant *LineNo = ConstantInt::get(Type::Int32Ty,
+                                      DECL_SOURCE_LINE(FieldDecl));
+  Constant *File = ConvertMetadataStringToGV(DECL_SOURCE_FILE(FieldDecl));
+
+  File = TheFolder->CreateBitCast(File, SBP);
+
+  // There may be multiple annotate attributes. Pass return of lookup_attr
+  //  to successive lookups.
+  while (AnnotateAttr) {
+    // Each annotate attribute is a tree list.
+    // Get value of list which is our linked list of args.
+    tree args = TREE_VALUE(AnnotateAttr);
+
+    // Each annotate attribute may have multiple args.
+    // Treat each arg as if it were a separate annotate attribute.
+    for (tree a = args; a; a = TREE_CHAIN(a)) {
+      // Each element of the arg list is a tree list, so get value
+      tree val = TREE_VALUE(a);
+
+      // Assert its a string, and then get that string.
+      assert(TREE_CODE(val) == STRING_CST &&
+             "Annotate attribute arg should always be a string");
+
+      Constant *strGV = TreeConstantToLLVM::EmitLV_STRING_CST(val);
+
+      // We can not use the IRBuilder because it will constant fold away
+      // the GEP that is critical to distinguish between an annotate
+      // attribute on a whole struct from one on the first element of the
+      // struct.
+      BitCastInst *CastFieldPtr = new BitCastInst(FieldPtr,  SBP,
+                                                  FieldPtr->getNameStart());
+      Builder.Insert(CastFieldPtr);
+
+      Value *Ops[4] = {
+        CastFieldPtr, BitCastToType(strGV, SBP),
+        File,  LineNo
+      };
+
+      const Type* FieldPtrType = FieldPtr->getType();
+      FieldPtr = Builder.CreateCall(Fn, Ops, Ops+4);
+      FieldPtr = BitCastToType(FieldPtr, FieldPtrType);
     }
-  }
 
-  const Type *Ty = ConvertType(TREE_TYPE(exp));
-  // If we have "extern void foo", make the global have type {} instead of
-  // type void.
-  if (Ty == Type::VoidTy) Ty = StructType::get(NULL, NULL);
-  const PointerType *PTy = PointerType::getUnqual(Ty);
-  unsigned Alignment = Ty->isSized() ? TD.getABITypeAlignment(Ty) : 1;
-  if (DECL_ALIGN(exp)) {
-    if (DECL_USER_ALIGN(exp) || 8 * Alignment < (unsigned)DECL_ALIGN(exp))
-      Alignment = DECL_ALIGN(exp) / 8;
+    // Get next annotate attribute.
+    AnnotateAttr = TREE_CHAIN(AnnotateAttr);
+    if (AnnotateAttr)
+      AnnotateAttr = lookup_attribute("annotate", AnnotateAttr);
   }
-
-  return LValue(BitCastToType(Decl, PTy), Alignment);
+  return FieldPtr;
 }
 
 LValue TreeToLLVM::EmitLV_ARRAY_REF(tree exp) {
@@ -6043,126 +6044,76 @@
                 Alignment);
 }
 
-/// getFieldOffsetInBits - Return the offset (in bits) of a FIELD_DECL in a
-/// structure.
-static unsigned getFieldOffsetInBits(tree Field) {
-  assert(DECL_FIELD_BIT_OFFSET(Field) != 0 && DECL_FIELD_OFFSET(Field) != 0);
-  unsigned 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;
-}
+LValue TreeToLLVM::EmitLV_BIT_FIELD_REF(tree exp) {
+  LValue Ptr = EmitLV(TREE_OPERAND(exp, 0));
+  assert(!Ptr.isBitfield() && "BIT_FIELD_REF operands cannot be bitfields!");
 
-/// getComponentRefOffsetInBits - Return the offset (in bits) of the field
-/// referenced in a COMPONENT_REF exp.
-static unsigned getComponentRefOffsetInBits(tree exp) {
-  assert(TREE_CODE(exp) == COMPONENT_REF && "not a COMPONENT_REF!");
-  tree field = TREE_OPERAND(exp, 1);
-  assert(TREE_CODE(field) == FIELD_DECL && "not a FIELD_DECL!");
-  tree field_offset = component_ref_field_offset (exp);
-  assert(DECL_FIELD_BIT_OFFSET(field) && field_offset);
-  unsigned Result = TREE_INT_CST_LOW(DECL_FIELD_BIT_OFFSET(field));
-  if (TREE_CODE(field_offset) == INTEGER_CST)
-    Result += TREE_INT_CST_LOW(field_offset)*8;
-  return Result;
-}
+  unsigned BitStart = (unsigned)TREE_INT_CST_LOW(TREE_OPERAND(exp, 2));
+  unsigned BitSize = (unsigned)TREE_INT_CST_LOW(TREE_OPERAND(exp, 1));
+  const Type *ValTy = ConvertType(TREE_TYPE(exp));
 
-Value *TreeToLLVM::EmitFieldAnnotation(Value *FieldPtr, tree FieldDecl) {
-  tree AnnotateAttr = lookup_attribute("annotate", DECL_ATTRIBUTES(FieldDecl));
+  unsigned ValueSizeInBits = TD.getTypeSizeInBits(ValTy);
+  assert(BitSize <= ValueSizeInBits &&
+         "ValTy isn't large enough to hold the value loaded!");
 
-  const Type *OrigPtrTy = FieldPtr->getType();
-  const Type *SBP = PointerType::getUnqual(Type::Int8Ty);
-  
-  Function *Fn = Intrinsic::getDeclaration(TheModule, 
-                                           Intrinsic::ptr_annotation,
-                                           &SBP, 1);
-  
-  // Get file and line number.  FIXME: Should this be for the decl or the
-  // use.  Is there a location info for the use?
-  Constant *LineNo = ConstantInt::get(Type::Int32Ty,
-                                      DECL_SOURCE_LINE(FieldDecl));
-  Constant *File = ConvertMetadataStringToGV(DECL_SOURCE_FILE(FieldDecl));
-  
-  File = TheFolder->CreateBitCast(File, SBP);
-  
-  // There may be multiple annotate attributes. Pass return of lookup_attr 
-  //  to successive lookups.
-  while (AnnotateAttr) {
-    // Each annotate attribute is a tree list.
-    // Get value of list which is our linked list of args.
-    tree args = TREE_VALUE(AnnotateAttr);
-    
-    // Each annotate attribute may have multiple args.
-    // Treat each arg as if it were a separate annotate attribute.
-    for (tree a = args; a; a = TREE_CHAIN(a)) {
-      // Each element of the arg list is a tree list, so get value
-      tree val = TREE_VALUE(a);
-      
-      // Assert its a string, and then get that string.
-      assert(TREE_CODE(val) == STRING_CST &&
-             "Annotate attribute arg should always be a string");
-      
-      Constant *strGV = TreeConstantToLLVM::EmitLV_STRING_CST(val);
-      
-      // We can not use the IRBuilder because it will constant fold away
-      // the GEP that is critical to distinguish between an annotate 
-      // attribute on a whole struct from one on the first element of the
-      // struct.
-      BitCastInst *CastFieldPtr = new BitCastInst(FieldPtr,  SBP, 
-                                                  FieldPtr->getNameStart());
-      Builder.Insert(CastFieldPtr);
-      
-      Value *Ops[4] = {
-        CastFieldPtr, BitCastToType(strGV, SBP), 
-        File,  LineNo
-      };
-      
-      const Type* FieldPtrType = FieldPtr->getType();
-      FieldPtr = Builder.CreateCall(Fn, Ops, Ops+4);
-      FieldPtr = BitCastToType(FieldPtr, FieldPtrType);
-    }
-    
-    // Get next annotate attribute.
-    AnnotateAttr = TREE_CHAIN(AnnotateAttr);
-    if (AnnotateAttr)
-      AnnotateAttr = lookup_attribute("annotate", AnnotateAttr);
+  assert(ValueSizeInBits == TD.getTypeAllocSizeInBits(ValTy) &&
+         "FIXME: BIT_FIELD_REF logic is broken for non-round types");
+
+  // BIT_FIELD_REF values can have BitStart values that are quite large.  We
+  // know that the thing we are loading is ValueSizeInBits large.  If BitStart
+  // is larger than ValueSizeInBits, bump the pointer over to where it should
+  // be.
+  if (unsigned UnitOffset = BitStart / ValueSizeInBits) {
+    // TODO: If Ptr.Ptr is a struct type or something, we can do much better
+    // than this.  e.g. check out when compiling unwind-dw2-fde-darwin.c.
+    Ptr.Ptr = BitCastToType(Ptr.Ptr, PointerType::getUnqual(ValTy));
+    Ptr.Ptr = Builder.CreateGEP(Ptr.Ptr,
+                                ConstantInt::get(Type::Int32Ty, UnitOffset));
+    BitStart -= UnitOffset*ValueSizeInBits;
   }
-  return FieldPtr;
-}
 
+  // If this is referring to the whole field, return the whole thing.
+  if (BitStart == 0 && BitSize == ValueSizeInBits) {
+    return LValue(BitCastToType(Ptr.Ptr, PointerType::getUnqual(ValTy)),
+                  Ptr.getAlignment());
+  }
+
+  return LValue(BitCastToType(Ptr.Ptr, PointerType::getUnqual(ValTy)), 1,
+                BitStart, BitSize);
+}
 
 LValue TreeToLLVM::EmitLV_COMPONENT_REF(tree exp) {
   LValue StructAddrLV = EmitLV(TREE_OPERAND(exp, 0));
-  tree FieldDecl = TREE_OPERAND(exp, 1); 
+  tree FieldDecl = TREE_OPERAND(exp, 1);
   unsigned LVAlign = StructAddrLV.getAlignment();
- 
+
   assert((TREE_CODE(DECL_CONTEXT(FieldDecl)) == RECORD_TYPE ||
           TREE_CODE(DECL_CONTEXT(FieldDecl)) == UNION_TYPE  ||
           TREE_CODE(DECL_CONTEXT(FieldDecl)) == QUAL_UNION_TYPE));
-  
+
   // Ensure that the struct type has been converted, so that the fielddecls
   // are laid out.  Note that we convert to the context of the Field, not to the
   // type of Operand #0, because GCC doesn't always have the field match up with
   // operand #0's type.
   const Type *StructTy = ConvertType(DECL_CONTEXT(FieldDecl));
-  
-  assert((!StructAddrLV.isBitfield() || 
+
+  assert((!StructAddrLV.isBitfield() ||
           StructAddrLV.BitStart == 0) && "structs cannot be bitfields!");
-  
+
   StructAddrLV.Ptr = BitCastToType(StructAddrLV.Ptr,
                                    PointerType::getUnqual(StructTy));
   const Type *FieldTy = ConvertType(getDeclaredType(FieldDecl));
-  
+
   // BitStart - This is the actual offset of the field from the start of the
   // struct, in bits.  For bitfields this may be on a non-byte boundary.
   unsigned BitStart = getComponentRefOffsetInBits(exp);
   Value *FieldPtr;
-  
+
   tree field_offset = component_ref_field_offset (exp);
   // If this is a normal field at a fixed offset from the start, handle it.
   if (TREE_CODE(field_offset) == INTEGER_CST) {
     unsigned int MemberIndex = GetFieldIndex(FieldDecl);
-    
+
     // If the LLVM struct has zero field, don't try to index into it, just use
     // the current pointer.
     FieldPtr = StructAddrLV.Ptr;
@@ -6171,14 +6122,14 @@
              "Field Idx out of range!");
       FieldPtr = Builder.CreateStructGEP(FieldPtr, MemberIndex);
     }
-    
+
     // Now that we did an offset from the start of the struct, subtract off
     // the offset from BitStart.
     if (MemberIndex) {
       const StructLayout *SL = TD.getStructLayout(cast<StructType>(StructTy));
       unsigned Offset = SL->getElementOffset(MemberIndex);
       BitStart -= Offset * 8;
-      
+
       // If the base is known to be 8-byte aligned, and we're adding a 4-byte
       // offset, the field is known to be 4-byte aligned.
       LVAlign = MinAlign(LVAlign, Offset);
@@ -6195,7 +6146,7 @@
         DECL_ALIGN(FieldDecl))
       LVAlign = std::max(LVAlign, unsigned(DECL_ALIGN(FieldDecl)) / 8);
 #endif
-    
+
     // If the FIELD_DECL has an annotate attribute on it, emit it.
     if (lookup_attribute("annotate", DECL_ATTRIBUTES(FieldDecl)))
       FieldPtr = EmitFieldAnnotation(FieldPtr, FieldDecl);
@@ -6223,10 +6174,10 @@
       LVAlign = MinAlign(LVAlign, ByteOffset);
     }
 
-    Value *Ptr = CastToType(Instruction::PtrToInt, StructAddrLV.Ptr, 
+    Value *Ptr = CastToType(Instruction::PtrToInt, StructAddrLV.Ptr,
                             Offset->getType());
     Ptr = Builder.CreateAdd(Ptr, Offset);
-    FieldPtr = CastToType(Instruction::IntToPtr, Ptr, 
+    FieldPtr = CastToType(Instruction::IntToPtr, Ptr,
                           PointerType::getUnqual(FieldTy));
   }
 
@@ -6328,57 +6279,112 @@
   return LValue(FieldPtr, LVAlign);
 }
 
-LValue TreeToLLVM::EmitLV_BIT_FIELD_REF(tree exp) {
-  LValue Ptr = EmitLV(TREE_OPERAND(exp, 0));
-  assert(!Ptr.isBitfield() && "BIT_FIELD_REF operands cannot be bitfields!");
-  
-  unsigned BitStart = (unsigned)TREE_INT_CST_LOW(TREE_OPERAND(exp, 2));
-  unsigned BitSize = (unsigned)TREE_INT_CST_LOW(TREE_OPERAND(exp, 1));
-  const Type *ValTy = ConvertType(TREE_TYPE(exp));
-  
-  unsigned ValueSizeInBits = TD.getTypeSizeInBits(ValTy);
-  assert(BitSize <= ValueSizeInBits &&
-         "ValTy isn't large enough to hold the value loaded!");
+LValue TreeToLLVM::EmitLV_DECL(tree exp) {
+  if (TREE_CODE(exp) == PARM_DECL || TREE_CODE(exp) == VAR_DECL ||
+      TREE_CODE(exp) == CONST_DECL) {
+    // If a static var's type was incomplete when the decl was written,
+    // but the type is complete now, lay out the decl now.
+    if (DECL_SIZE(exp) == 0 && COMPLETE_OR_UNBOUND_ARRAY_TYPE_P(TREE_TYPE(exp))
+        && (TREE_STATIC(exp) || DECL_EXTERNAL(exp))) {
+      layout_decl(exp, 0);
 
-  assert(ValueSizeInBits == TD.getTypeAllocSizeInBits(ValTy) &&
-         "FIXME: BIT_FIELD_REF logic is broken for non-round types");
+      // This mirrors code in layout_decl for munging the RTL.  Here we actually
+      // emit a NEW declaration for the global variable, now that it has been
+      // laid out.  We then tell the compiler to "forward" any uses of the old
+      // global to this new one.
+      if (Value *Val = DECL_LLVM_IF_SET(exp)) {
+        //fprintf(stderr, "***\n*** SHOULD HANDLE GLOBAL VARIABLES!\n***\n");
+        //assert(0 && "Reimplement this with replace all uses!");
+#if 0
+        SET_DECL_LLVM(exp, 0);
+        // Create a new global variable declaration
+        llvm_assemble_external(exp);
+        V2GV(Val)->ForwardedGlobal = V2GV(DECL_LLVM(exp));
+#endif
+      }
+    }
+  }
 
-  // BIT_FIELD_REF values can have BitStart values that are quite large.  We
-  // know that the thing we are loading is ValueSizeInBits large.  If BitStart
-  // is larger than ValueSizeInBits, bump the pointer over to where it should
-  // be.
-  if (unsigned UnitOffset = BitStart / ValueSizeInBits) {
-    // TODO: If Ptr.Ptr is a struct type or something, we can do much better
-    // than this.  e.g. check out when compiling unwind-dw2-fde-darwin.c.
-    Ptr.Ptr = BitCastToType(Ptr.Ptr, PointerType::getUnqual(ValTy));
-    Ptr.Ptr = Builder.CreateGEP(Ptr.Ptr,
-                                ConstantInt::get(Type::Int32Ty, UnitOffset));
-    BitStart -= UnitOffset*ValueSizeInBits;
+  assert(!isGimpleTemporary(exp) &&
+         "Cannot use a gimple temporary as an l-value");
+
+  Value *Decl = DECL_LLVM(exp);
+  if (Decl == 0) {
+    if (errorcount || sorrycount) {
+      const Type *Ty = ConvertType(TREE_TYPE(exp));
+      const PointerType *PTy = PointerType::getUnqual(Ty);
+      LValue LV(ConstantPointerNull::get(PTy), 1);
+      return LV;
+    }
+    assert(0 && "INTERNAL ERROR: Referencing decl that hasn't been laid out");
+    abort();
   }
-  
-  // If this is referring to the whole field, return the whole thing.
-  if (BitStart == 0 && BitSize == ValueSizeInBits) {
-    return LValue(BitCastToType(Ptr.Ptr, PointerType::getUnqual(ValTy)),
-                  Ptr.getAlignment());
+
+  // Ensure variable marked as used even if it doesn't go through a parser.  If
+  // it hasn't been used yet, write out an external definition.
+  if (!TREE_USED(exp)) {
+    assemble_external(exp);
+    TREE_USED(exp) = 1;
+    Decl = DECL_LLVM(exp);
   }
-  
-  return LValue(BitCastToType(Ptr.Ptr, PointerType::getUnqual(ValTy)), 1,
-                BitStart, BitSize);
+
+  if (GlobalValue *GV = dyn_cast<GlobalValue>(Decl)) {
+    // If this is an aggregate, emit it to LLVM now.  GCC happens to
+    // get this case right by forcing the initializer into memory.
+    if (TREE_CODE(exp) == CONST_DECL || TREE_CODE(exp) == VAR_DECL) {
+      if ((DECL_INITIAL(exp) || !TREE_PUBLIC(exp)) && !DECL_EXTERNAL(exp) &&
+          GV->isDeclaration() &&
+          !BOGUS_CTOR(exp)) {
+        emit_global_to_llvm(exp);
+        Decl = DECL_LLVM(exp);     // Decl could have change if it changed type.
+      }
+    } else {
+      // Otherwise, inform cgraph that we used the global.
+      mark_decl_referenced(exp);
+      if (tree ID = DECL_ASSEMBLER_NAME(exp))
+        mark_referenced(ID);
+    }
+  }
+
+  const Type *Ty = ConvertType(TREE_TYPE(exp));
+  // If we have "extern void foo", make the global have type {} instead of
+  // type void.
+  if (Ty == Type::VoidTy) Ty = StructType::get(NULL, NULL);
+  const PointerType *PTy = PointerType::getUnqual(Ty);
+  unsigned Alignment = Ty->isSized() ? TD.getABITypeAlignment(Ty) : 1;
+  if (DECL_ALIGN(exp)) {
+    if (DECL_USER_ALIGN(exp) || 8 * Alignment < (unsigned)DECL_ALIGN(exp))
+      Alignment = DECL_ALIGN(exp) / 8;
+  }
+
+  return LValue(BitCastToType(Decl, PTy), Alignment);
 }
 
-LValue TreeToLLVM::EmitLV_XXXXPART_EXPR(tree exp, unsigned Idx) {
-  LValue Ptr = EmitLV(TREE_OPERAND(exp, 0));
-  assert(!Ptr.isBitfield() &&
-         "REALPART_EXPR / IMAGPART_EXPR operands cannot be bitfields!");
-  unsigned Alignment;
-  if (Idx == 0)
-    // REALPART alignment is same as the complex operand.
-    Alignment = Ptr.getAlignment();
-  else
-    // IMAGPART alignment = MinAlign(Ptr.Alignment, sizeof field);
-    Alignment = MinAlign(Ptr.getAlignment(),
-                         TD.getTypeAllocSize(Ptr.Ptr->getType()));
-  return LValue(Builder.CreateStructGEP(Ptr.Ptr, Idx), Alignment);
+LValue TreeToLLVM::EmitLV_EXC_PTR_EXPR(tree exp) {
+  CreateExceptionValues();
+  // Cast the address pointer to the expected type.
+  unsigned Alignment = TD.getABITypeAlignment(cast<PointerType>(ExceptionValue->
+                                                  getType())->getElementType());
+  return LValue(BitCastToType(ExceptionValue,
+                              PointerType::getUnqual(ConvertType(TREE_TYPE(exp)))),
+                Alignment);
+}
+
+LValue TreeToLLVM::EmitLV_FILTER_EXPR(tree exp) {
+  CreateExceptionValues();
+  unsigned Alignment =
+    TD.getABITypeAlignment(cast<PointerType>(ExceptionSelectorValue->
+                                             getType())->getElementType());
+  return LValue(ExceptionSelectorValue, Alignment);
+}
+
+LValue TreeToLLVM::EmitLV_INDIRECT_REF(tree exp) {
+  // The lvalue is just the address.
+  LValue LV = LValue(Emit(TREE_OPERAND(exp, 0), 0), expr_align(exp) / 8);
+  // Correct for implicit type conversion: INDIRECT_REF can be applied to a
+  // void*, resulting in a non-void type.
+  LV.Ptr = BitCastToType(LV.Ptr, ConvertType(TREE_TYPE(exp))->getPointerTo());
+  return LV;
 }
 
 LValue TreeToLLVM::EmitLV_VIEW_CONVERT_EXPR(tree exp) {
@@ -6388,7 +6394,7 @@
     // If the input is an aggregate, the address is the address of the operand.
     LValue LV = EmitLV(Op);
     // The type is the type of the expression.
-    LV.Ptr = BitCastToType(LV.Ptr, 
+    LV.Ptr = BitCastToType(LV.Ptr,
                            PointerType::getUnqual(ConvertType(TREE_TYPE(exp))));
     return LV;
   } else {
@@ -6396,30 +6402,33 @@
     Value *Dest = CreateTemporary(ConvertType(TREE_TYPE(Op)));
     StoreInst *S = Builder.CreateStore(Emit(Op, 0), Dest);
     // The type is the type of the expression.
-    Dest = BitCastToType(Dest,  
+    Dest = BitCastToType(Dest,
                          PointerType::getUnqual(ConvertType(TREE_TYPE(exp))));
     return LValue(Dest, 1);
   }
 }
 
-LValue TreeToLLVM::EmitLV_EXC_PTR_EXPR(tree exp) {
-  CreateExceptionValues();
-  // Cast the address pointer to the expected type.
-  unsigned Alignment = TD.getABITypeAlignment(cast<PointerType>(ExceptionValue->
-                                                  getType())->getElementType());
-  return LValue(BitCastToType(ExceptionValue,
-                              PointerType::getUnqual(ConvertType(TREE_TYPE(exp)))),
-                Alignment);
+LValue TreeToLLVM::EmitLV_WITH_SIZE_EXPR(tree exp) {
+  // The address is the address of the operand.
+  return EmitLV(TREE_OPERAND(exp, 0));
 }
 
-LValue TreeToLLVM::EmitLV_FILTER_EXPR(tree exp) {
-  CreateExceptionValues();
-  unsigned Alignment =
-    TD.getABITypeAlignment(cast<PointerType>(ExceptionSelectorValue->
-                                             getType())->getElementType());
-  return LValue(ExceptionSelectorValue, Alignment);
+LValue TreeToLLVM::EmitLV_XXXXPART_EXPR(tree exp, unsigned Idx) {
+  LValue Ptr = EmitLV(TREE_OPERAND(exp, 0));
+  assert(!Ptr.isBitfield() &&
+         "REALPART_EXPR / IMAGPART_EXPR operands cannot be bitfields!");
+  unsigned Alignment;
+  if (Idx == 0)
+    // REALPART alignment is same as the complex operand.
+    Alignment = Ptr.getAlignment();
+  else
+    // IMAGPART alignment = MinAlign(Ptr.Alignment, sizeof field);
+    Alignment = MinAlign(Ptr.getAlignment(),
+                         TD.getTypeAllocSize(Ptr.Ptr->getType()));
+  return LValue(Builder.CreateStructGEP(Ptr.Ptr, Idx), Alignment);
 }
 
+
 //===----------------------------------------------------------------------===//
 //                       ... Constant Expressions ...
 //===----------------------------------------------------------------------===//

Modified: llvm-gcc-4.2/trunk/gcc/llvm-internal.h
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-internal.h?rev=74069&r1=74068&r2=74069&view=diff

==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-internal.h (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-internal.h Wed Jun 24 03:17:34 2009
@@ -527,6 +527,7 @@
   Value *EmitCEIL_DIV_EXPR(tree_node *exp);
   Value *EmitFLOOR_DIV_EXPR(tree_node *exp);
   Value *EmitROUND_DIV_EXPR(tree_node *exp);
+  Value *EmitFieldAnnotation(Value *FieldPtr, tree_node *FieldDecl);
 
   // Exception Handling.
   Value *EmitEXC_PTR_EXPR(tree_node *exp);
@@ -589,15 +590,16 @@
   Value *EmitComplexBinOp(tree_node *exp, const MemRef *DestLoc);
 
   // L-Value Expressions.
-  LValue EmitLV_DECL(tree_node *exp);
   LValue EmitLV_ARRAY_REF(tree_node *exp);
-  LValue EmitLV_COMPONENT_REF(tree_node *exp);
-  Value *EmitFieldAnnotation(Value *FieldPtr, tree_node *FieldDecl);
   LValue EmitLV_BIT_FIELD_REF(tree_node *exp);
-  LValue EmitLV_XXXXPART_EXPR(tree_node *exp, unsigned Idx);
-  LValue EmitLV_VIEW_CONVERT_EXPR(tree_node *exp);
+  LValue EmitLV_COMPONENT_REF(tree_node *exp);
+  LValue EmitLV_DECL(tree_node *exp);
   LValue EmitLV_EXC_PTR_EXPR(tree_node *exp);
   LValue EmitLV_FILTER_EXPR(tree_node *exp);
+  LValue EmitLV_INDIRECT_REF(tree_node *exp);
+  LValue EmitLV_VIEW_CONVERT_EXPR(tree_node *exp);
+  LValue EmitLV_WITH_SIZE_EXPR(tree_node *exp);
+  LValue EmitLV_XXXXPART_EXPR(tree_node *exp, unsigned Idx);
 
   // Constant Expressions.
   Value *EmitINTEGER_CST(tree_node *exp);





More information about the llvm-commits mailing list