[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