[llvm-commits] [dragonegg] r107618 - in /dragonegg/trunk: llvm-convert.cpp llvm-internal.h

Duncan Sands baldrick at free.fr
Mon Jul 5 07:12:49 PDT 2010


Author: baldrick
Date: Mon Jul  5 09:12:49 2010
New Revision: 107618

URL: http://llvm.org/viewvc/llvm-project?rev=107618&view=rev
Log:
Add support for TARGET_MEM_REF, which is generated by the GCC optimizers
when they are turned on using -fplugin-arg-dragonegg-enable-gcc-optzns.

Modified:
    dragonegg/trunk/llvm-convert.cpp
    dragonegg/trunk/llvm-internal.h

Modified: dragonegg/trunk/llvm-convert.cpp
URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/llvm-convert.cpp?rev=107618&r1=107617&r2=107618&view=diff
==============================================================================
--- dragonegg/trunk/llvm-convert.cpp (original)
+++ dragonegg/trunk/llvm-convert.cpp Mon Jul  5 09:12:49 2010
@@ -1254,6 +1254,9 @@
   case SSA_NAME:
     LV = EmitLV_SSA_NAME(exp);
     break;
+  case TARGET_MEM_REF:
+    LV = EmitLV_TARGET_MEM_REF(exp);
+    break;
 
   // Constants.
   case LABEL_DECL: {
@@ -5647,6 +5650,51 @@
   return LValue(Temp, 1);
 }
 
+LValue TreeToLLVM::EmitLV_TARGET_MEM_REF(tree exp) {
+  // TODO: Take the address space into account.
+  // TODO: Improve the alignment estimate.
+  struct mem_address addr;
+  get_address_description (exp, &addr);
+
+  LValue Ref;
+  Value *Delta = 0; // Offset from base pointer in units
+  if (addr.symbol) {
+    Ref = EmitLV(addr.symbol);
+    if (addr.base && !integer_zerop (addr.base))
+      Delta = EmitRegister(addr.base);
+  } else {
+    assert(addr.base && "TARGET_MEM_REF has neither base nor symbol!");
+    Ref = LValue(EmitRegister(addr.base), 1);
+  }
+
+  if (addr.index) {
+    Value *Index = EmitRegister(addr.index);
+    if (addr.step && !integer_onep (addr.step))
+      Index = Builder.CreateMul(Index, EmitRegisterConstant(addr.step));
+    Delta = Delta ? Builder.CreateAdd(Delta, Index) : Index;
+  }
+
+  if (addr.offset && !integer_zerop (addr.offset)) {
+    Constant *Offset = EmitRegisterConstant(addr.offset);
+    Delta = Delta ? Builder.CreateAdd(Delta, Offset) : Offset;
+  }
+
+  if (Delta) {
+    // Advance the base pointer by the given number of units.
+    Ref.Ptr = Builder.CreateBitCast(Ref.Ptr, GetUnitPointerType(Context));
+    Ref.Ptr = POINTER_TYPE_OVERFLOW_UNDEFINED ?
+      Builder.CreateInBoundsGEP(Ref.Ptr, Delta)
+      : Builder.CreateGEP(Ref.Ptr, Delta);
+    Ref.setAlignment(1); // Let the optimizers compute the alignment.
+  }
+
+  // The result can be of a different pointer type even if we didn't advance it.
+  Ref.Ptr = UselesslyTypeConvert(Ref.Ptr,
+                                 GetRegType(TREE_TYPE(exp))->getPointerTo());
+
+  return Ref;
+}
+
 Constant *TreeToLLVM::EmitLV_LABEL_DECL(tree exp) {
   return BlockAddress::get(Fn, getLabelDeclBlock(exp));
 }
@@ -7503,6 +7551,7 @@
   case IMAGPART_EXPR:
   case INDIRECT_REF:
   case REALPART_EXPR:
+  case TARGET_MEM_REF:
   case VIEW_CONVERT_EXPR:
     return EmitLoadOfLValue(rhs); // Load from memory.
 

Modified: dragonegg/trunk/llvm-internal.h
URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/llvm-internal.h?rev=107618&r1=107617&r2=107618&view=diff
==============================================================================
--- dragonegg/trunk/llvm-internal.h (original)
+++ dragonegg/trunk/llvm-internal.h Mon Jul  5 09:12:49 2010
@@ -222,6 +222,14 @@
   return TheTypeConverter->ConvertType(type);
 }
 
+/// GetUnitPointerType - Returns an LLVM pointer type which points to memory one
+/// address unit wide.  For example, on a machine which has 16 bit bytes returns
+/// an i16*.
+inline const Type *GetUnitPointerType(LLVMContext &C, unsigned AddrSpace = 0) {
+  assert(!(BITS_PER_UNIT & 7) && "Unit size not a multiple of 8 bits!");
+  return IntegerType::get(C, BITS_PER_UNIT)->getPointerTo(AddrSpace);
+}
+
 /// GetFieldIndex - Return the index of the field in the given LLVM type that
 /// corresponds to the GCC field declaration 'decl'.  This means that the LLVM
 /// and GCC fields start in the same byte (if 'decl' is a bitfield, this means
@@ -327,6 +335,10 @@
   uint32_t getAlignment() const {
     return 1U << LogAlign;
   }
+
+  void setAlignment(uint32_t A) {
+    LogAlign = Log2_32(A);
+  }
 };
 
 /// LValue - This struct represents an lvalue in the program.  In particular,
@@ -780,6 +792,7 @@
   LValue EmitLV_WITH_SIZE_EXPR(tree_node *exp);
   LValue EmitLV_XXXXPART_EXPR(tree_node *exp, unsigned Idx);
   LValue EmitLV_SSA_NAME(tree_node *exp);
+  LValue EmitLV_TARGET_MEM_REF(tree_node *exp);
 
   // Constant Expressions.
   Value *EmitINTEGER_CST(tree_node *exp);





More information about the llvm-commits mailing list