[llvm-commits] [dragonegg] r90259 - /dragonegg/trunk/llvm-convert.cpp
Duncan Sands
baldrick at free.fr
Tue Dec 1 13:18:10 PST 2009
Author: baldrick
Date: Tue Dec 1 15:18:10 2009
New Revision: 90259
URL: http://llvm.org/viewvc/llvm-project?rev=90259&view=rev
Log:
Since EmitLoadOfLValue, EmitADDR_EXPR, EmitOBJ_TYPE_REF and EmitCONSTRUCTOR
now exist solely for the benefit of EmitGimpleAssignSingleRHS, move them to
just before this method. (EmitADDR_EXPR is used in one other place, but
philosophically it belongs here).
Modified:
dragonegg/trunk/llvm-convert.cpp
Modified: dragonegg/trunk/llvm-convert.cpp
URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/llvm-convert.cpp?rev=90259&r1=90258&r2=90259&view=diff
==============================================================================
--- dragonegg/trunk/llvm-convert.cpp (original)
+++ dragonegg/trunk/llvm-convert.cpp Tue Dec 1 15:18:10 2009
@@ -2206,6 +2206,210 @@
return C;
}
+/// EmitLoadOfLValue - When an l-value expression is used in a context that
+/// requires an r-value, this method emits the lvalue computation, then loads
+/// the result.
+Value *TreeToLLVM::EmitLoadOfLValue(tree exp, const MemRef *DestLoc) {
+ if (canEmitRegisterVariable(exp))
+ // If this is a register variable, EmitLV can't handle it (there is no
+ // l-value of a register variable). Emit an inline asm node that copies the
+ // value out of the specified register.
+ return EmitReadOfRegisterVariable(exp, DestLoc);
+
+ LValue LV = EmitLV(exp);
+ bool isVolatile = TREE_THIS_VOLATILE(exp);
+ const Type *Ty = ConvertType(TREE_TYPE(exp));
+ unsigned Alignment = LV.getAlignment();
+ if (TREE_CODE(exp) == COMPONENT_REF)
+ if (const StructType *STy =
+ dyn_cast<StructType>(ConvertType(TREE_TYPE(TREE_OPERAND(exp, 0)))))
+ if (STy->isPacked())
+ // Packed struct members use 1 byte alignment
+ Alignment = 1;
+
+
+ if (!LV.isBitfield()) {
+ if (!DestLoc) {
+ // Scalar value: emit a load.
+ Value *Ptr = Builder.CreateBitCast(LV.Ptr, Ty->getPointerTo());
+ LoadInst *LI = Builder.CreateLoad(Ptr, isVolatile);
+ LI->setAlignment(Alignment);
+ return LI;
+ } else {
+ EmitAggregateCopy(*DestLoc, MemRef(LV.Ptr, Alignment, isVolatile),
+ TREE_TYPE(exp));
+ return 0;
+ }
+ } else {
+ // This is a bitfield reference.
+ if (!LV.BitSize)
+ return Constant::getNullValue(Ty);
+
+ const Type *ValTy = cast<PointerType>(LV.Ptr->getType())->getElementType();
+ unsigned ValSizeInBits = ValTy->getPrimitiveSizeInBits();
+
+ // The number of loads needed to read the entire bitfield.
+ unsigned Strides = 1 + (LV.BitStart + LV.BitSize - 1) / ValSizeInBits;
+
+ assert(ValTy->isInteger() && "Invalid bitfield lvalue!");
+ assert(ValSizeInBits > LV.BitStart && "Bad bitfield lvalue!");
+ assert(ValSizeInBits >= LV.BitSize && "Bad bitfield lvalue!");
+ assert(2*ValSizeInBits > LV.BitSize+LV.BitStart && "Bad bitfield lvalue!");
+
+ Value *Result = NULL;
+
+ for (unsigned I = 0; I < Strides; I++) {
+ unsigned Index = BYTES_BIG_ENDIAN ? I : Strides - I - 1; // MSB first
+ unsigned ThisFirstBit = Index * ValSizeInBits;
+ unsigned ThisLastBitPlusOne = ThisFirstBit + ValSizeInBits;
+ if (ThisFirstBit < LV.BitStart)
+ ThisFirstBit = LV.BitStart;
+ if (ThisLastBitPlusOne > LV.BitStart+LV.BitSize)
+ ThisLastBitPlusOne = LV.BitStart+LV.BitSize;
+
+ Value *Ptr = Index ?
+ Builder.CreateGEP(LV.Ptr,
+ ConstantInt::get(Type::getInt32Ty(Context), Index)) :
+ LV.Ptr;
+ LoadInst *LI = Builder.CreateLoad(Ptr, isVolatile);
+ LI->setAlignment(Alignment);
+ Value *Val = LI;
+
+ unsigned BitsInVal = ThisLastBitPlusOne - ThisFirstBit;
+ unsigned FirstBitInVal = ThisFirstBit % ValSizeInBits;
+
+ if (BYTES_BIG_ENDIAN)
+ FirstBitInVal = ValSizeInBits-FirstBitInVal-BitsInVal;
+
+ // Mask the bits out by shifting left first, then shifting right. The
+ // LLVM optimizer will turn this into an AND if this is an unsigned
+ // expression.
+
+ if (FirstBitInVal+BitsInVal != ValSizeInBits) {
+ Value *ShAmt = ConstantInt::get(ValTy, ValSizeInBits -
+ (FirstBitInVal+BitsInVal));
+ Val = Builder.CreateShl(Val, ShAmt);
+ }
+
+ // Shift right required?
+ if (ValSizeInBits != BitsInVal) {
+ bool AddSignBits = !TYPE_UNSIGNED(TREE_TYPE(exp)) && !Result;
+ Value *ShAmt = ConstantInt::get(ValTy, ValSizeInBits-BitsInVal);
+ Val = AddSignBits ?
+ Builder.CreateAShr(Val, ShAmt) : Builder.CreateLShr(Val, ShAmt);
+ }
+
+ if (Result) {
+ Value *ShAmt = ConstantInt::get(ValTy, BitsInVal);
+ Result = Builder.CreateShl(Result, ShAmt);
+ Result = Builder.CreateOr(Result, Val);
+ } else {
+ Result = Val;
+ }
+ }
+
+ return Builder.CreateIntCast(Result, Ty,
+ /*isSigned*/!TYPE_UNSIGNED(TREE_TYPE(exp)));
+ }
+}
+
+Value *TreeToLLVM::EmitADDR_EXPR(tree exp) {
+ LValue LV = EmitLV(TREE_OPERAND(exp, 0));
+ assert((!LV.isBitfield() || LV.BitStart == 0) &&
+ "It is illegal to take the address of a bitfield!");
+ // Perform a cast here if necessary. For example, GCC sometimes forms an
+ // ADDR_EXPR where the operand is an array, and the ADDR_EXPR type is a
+ // pointer to the first element.
+ return Builder.CreateBitCast(LV.Ptr, ConvertType(TREE_TYPE(exp)));
+}
+
+Value *TreeToLLVM::EmitOBJ_TYPE_REF(tree exp) {
+ return Builder.CreateBitCast(EmitGimpleReg(OBJ_TYPE_REF_EXPR(exp)),
+ ConvertType(TREE_TYPE(exp)));
+}
+
+/// EmitCONSTRUCTOR - emit the constructor into the location specified by
+/// DestLoc.
+Value *TreeToLLVM::EmitCONSTRUCTOR(tree exp, const MemRef *DestLoc) {
+ tree type = TREE_TYPE(exp);
+ const Type *Ty = ConvertType(type);
+ if (const VectorType *VTy = dyn_cast<VectorType>(Ty)) {
+ assert(DestLoc == 0 && "Dest location for vector value?");
+ std::vector<Value *> BuildVecOps;
+ BuildVecOps.reserve(VTy->getNumElements());
+
+ // Insert all of the elements here.
+ unsigned HOST_WIDE_INT idx;
+ tree value;
+ FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (exp), idx, value) {
+ Value *Elt = EmitGimpleReg(value);
+
+ if (const VectorType *EltTy = dyn_cast<VectorType>(Elt->getType())) {
+ // GCC allows vectors to be built up from vectors. Extract all of the
+ // vector elements and add them to the list of build vector operands.
+ for (unsigned i = 0, e = EltTy->getNumElements(); i != e; ++i) {
+ Value *Index = ConstantInt::get(llvm::Type::getInt32Ty(Context), i);
+ BuildVecOps.push_back(Builder.CreateExtractElement(Elt, Index));
+ }
+ } else {
+ assert(Elt->getType() == VTy->getElementType() &&
+ "Unexpected type for vector constructor!");
+ BuildVecOps.push_back(Elt);
+ }
+ }
+
+ // Insert zero for any unspecified values.
+ while (BuildVecOps.size() < VTy->getNumElements())
+ BuildVecOps.push_back(Constant::getNullValue(VTy->getElementType()));
+ assert(BuildVecOps.size() == VTy->getNumElements() &&
+ "Vector constructor specified too many values!");
+
+ return BuildVector(BuildVecOps);
+ }
+
+ assert(AGGREGATE_TYPE_P(type) && "Constructor for scalar type??");
+
+ // Start out with the value zero'd out.
+ EmitAggregateZero(*DestLoc, type);
+
+ VEC(constructor_elt, gc) *elt = CONSTRUCTOR_ELTS(exp);
+ switch (TREE_CODE(TREE_TYPE(exp))) {
+ case ARRAY_TYPE:
+ case RECORD_TYPE:
+ default:
+ if (elt && VEC_length(constructor_elt, elt)) {
+ // We don't handle elements yet.
+
+ TODO(exp);
+ }
+ return 0;
+ case QUAL_UNION_TYPE:
+ case UNION_TYPE:
+ // Store each element of the constructor into the corresponding field of
+ // DEST.
+ if (!elt || VEC_empty(constructor_elt, elt)) return 0; // no elements
+ assert(VEC_length(constructor_elt, elt) == 1
+ && "Union CONSTRUCTOR should have one element!");
+ tree tree_purpose = VEC_index(constructor_elt, elt, 0)->index;
+ tree tree_value = VEC_index(constructor_elt, elt, 0)->value;
+ if (!tree_purpose)
+ return 0; // Not actually initialized?
+
+ if (AGGREGATE_TYPE_P(TREE_TYPE(tree_purpose))) {
+ EmitAggregate(tree_value, *DestLoc);
+ } else {
+ // Scalar value. Evaluate to a register, then do the store.
+ Value *V = EmitGimpleReg(tree_value);
+ Value *Ptr = Builder.CreateBitCast(DestLoc->Ptr,
+ PointerType::getUnqual(V->getType()));
+ StoreInst *St = Builder.CreateStore(V, Ptr, DestLoc->Volatile);
+ St->setAlignment(DestLoc->getAlignment());
+ }
+ break;
+ }
+ return 0;
+}
+
Value *TreeToLLVM::EmitGimpleAssignSingleRHS(tree rhs, const MemRef *DestLoc) {
assert((AGGREGATE_TYPE_P(TREE_TYPE(rhs)) == (DestLoc != 0)) &&
"DestLoc for aggregate types only!");
@@ -2375,128 +2579,6 @@
}
}
-/// EmitLoadOfLValue - When an l-value expression is used in a context that
-/// requires an r-value, this method emits the lvalue computation, then loads
-/// the result.
-Value *TreeToLLVM::EmitLoadOfLValue(tree exp, const MemRef *DestLoc) {
- if (canEmitRegisterVariable(exp))
- // If this is a register variable, EmitLV can't handle it (there is no
- // l-value of a register variable). Emit an inline asm node that copies the
- // value out of the specified register.
- return EmitReadOfRegisterVariable(exp, DestLoc);
-
- LValue LV = EmitLV(exp);
- bool isVolatile = TREE_THIS_VOLATILE(exp);
- const Type *Ty = ConvertType(TREE_TYPE(exp));
- unsigned Alignment = LV.getAlignment();
- if (TREE_CODE(exp) == COMPONENT_REF)
- if (const StructType *STy =
- dyn_cast<StructType>(ConvertType(TREE_TYPE(TREE_OPERAND(exp, 0)))))
- if (STy->isPacked())
- // Packed struct members use 1 byte alignment
- Alignment = 1;
-
-
- if (!LV.isBitfield()) {
- if (!DestLoc) {
- // Scalar value: emit a load.
- Value *Ptr = Builder.CreateBitCast(LV.Ptr, Ty->getPointerTo());
- LoadInst *LI = Builder.CreateLoad(Ptr, isVolatile);
- LI->setAlignment(Alignment);
- return LI;
- } else {
- EmitAggregateCopy(*DestLoc, MemRef(LV.Ptr, Alignment, isVolatile),
- TREE_TYPE(exp));
- return 0;
- }
- } else {
- // This is a bitfield reference.
- if (!LV.BitSize)
- return Constant::getNullValue(Ty);
-
- const Type *ValTy = cast<PointerType>(LV.Ptr->getType())->getElementType();
- unsigned ValSizeInBits = ValTy->getPrimitiveSizeInBits();
-
- // The number of loads needed to read the entire bitfield.
- unsigned Strides = 1 + (LV.BitStart + LV.BitSize - 1) / ValSizeInBits;
-
- assert(ValTy->isInteger() && "Invalid bitfield lvalue!");
- assert(ValSizeInBits > LV.BitStart && "Bad bitfield lvalue!");
- assert(ValSizeInBits >= LV.BitSize && "Bad bitfield lvalue!");
- assert(2*ValSizeInBits > LV.BitSize+LV.BitStart && "Bad bitfield lvalue!");
-
- Value *Result = NULL;
-
- for (unsigned I = 0; I < Strides; I++) {
- unsigned Index = BYTES_BIG_ENDIAN ? I : Strides - I - 1; // MSB first
- unsigned ThisFirstBit = Index * ValSizeInBits;
- unsigned ThisLastBitPlusOne = ThisFirstBit + ValSizeInBits;
- if (ThisFirstBit < LV.BitStart)
- ThisFirstBit = LV.BitStart;
- if (ThisLastBitPlusOne > LV.BitStart+LV.BitSize)
- ThisLastBitPlusOne = LV.BitStart+LV.BitSize;
-
- Value *Ptr = Index ?
- Builder.CreateGEP(LV.Ptr,
- ConstantInt::get(Type::getInt32Ty(Context), Index)) :
- LV.Ptr;
- LoadInst *LI = Builder.CreateLoad(Ptr, isVolatile);
- LI->setAlignment(Alignment);
- Value *Val = LI;
-
- unsigned BitsInVal = ThisLastBitPlusOne - ThisFirstBit;
- unsigned FirstBitInVal = ThisFirstBit % ValSizeInBits;
-
- if (BYTES_BIG_ENDIAN)
- FirstBitInVal = ValSizeInBits-FirstBitInVal-BitsInVal;
-
- // Mask the bits out by shifting left first, then shifting right. The
- // LLVM optimizer will turn this into an AND if this is an unsigned
- // expression.
-
- if (FirstBitInVal+BitsInVal != ValSizeInBits) {
- Value *ShAmt = ConstantInt::get(ValTy, ValSizeInBits -
- (FirstBitInVal+BitsInVal));
- Val = Builder.CreateShl(Val, ShAmt);
- }
-
- // Shift right required?
- if (ValSizeInBits != BitsInVal) {
- bool AddSignBits = !TYPE_UNSIGNED(TREE_TYPE(exp)) && !Result;
- Value *ShAmt = ConstantInt::get(ValTy, ValSizeInBits-BitsInVal);
- Val = AddSignBits ?
- Builder.CreateAShr(Val, ShAmt) : Builder.CreateLShr(Val, ShAmt);
- }
-
- if (Result) {
- Value *ShAmt = ConstantInt::get(ValTy, BitsInVal);
- Result = Builder.CreateShl(Result, ShAmt);
- Result = Builder.CreateOr(Result, Val);
- } else {
- Result = Val;
- }
- }
-
- return Builder.CreateIntCast(Result, Ty,
- /*isSigned*/!TYPE_UNSIGNED(TREE_TYPE(exp)));
- }
-}
-
-Value *TreeToLLVM::EmitADDR_EXPR(tree exp) {
- LValue LV = EmitLV(TREE_OPERAND(exp, 0));
- assert((!LV.isBitfield() || LV.BitStart == 0) &&
- "It is illegal to take the address of a bitfield!");
- // Perform a cast here if necessary. For example, GCC sometimes forms an
- // ADDR_EXPR where the operand is an array, and the ADDR_EXPR type is a
- // pointer to the first element.
- return Builder.CreateBitCast(LV.Ptr, ConvertType(TREE_TYPE(exp)));
-}
-
-Value *TreeToLLVM::EmitOBJ_TYPE_REF(tree exp) {
- return Builder.CreateBitCast(EmitGimpleReg(OBJ_TYPE_REF_EXPR(exp)),
- ConvertType(TREE_TYPE(exp)));
-}
-
Value *TreeToLLVM::EmitGimpleCallRHS(gimple stmt, const MemRef *DestLoc) {
// Check for a built-in function call. If we can lower it directly, do so
// now.
@@ -6913,88 +6995,6 @@
// ... Constant Expressions ...
//===----------------------------------------------------------------------===//
-/// EmitCONSTRUCTOR - emit the constructor into the location specified by
-/// DestLoc.
-Value *TreeToLLVM::EmitCONSTRUCTOR(tree exp, const MemRef *DestLoc) {
- tree type = TREE_TYPE(exp);
- const Type *Ty = ConvertType(type);
- if (const VectorType *VTy = dyn_cast<VectorType>(Ty)) {
- assert(DestLoc == 0 && "Dest location for vector value?");
- std::vector<Value *> BuildVecOps;
- BuildVecOps.reserve(VTy->getNumElements());
-
- // Insert all of the elements here.
- unsigned HOST_WIDE_INT idx;
- tree value;
- FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (exp), idx, value) {
- Value *Elt = EmitGimpleReg(value);
-
- if (const VectorType *EltTy = dyn_cast<VectorType>(Elt->getType())) {
- // GCC allows vectors to be built up from vectors. Extract all of the
- // vector elements and add them to the list of build vector operands.
- for (unsigned i = 0, e = EltTy->getNumElements(); i != e; ++i) {
- Value *Index = ConstantInt::get(llvm::Type::getInt32Ty(Context), i);
- BuildVecOps.push_back(Builder.CreateExtractElement(Elt, Index));
- }
- } else {
- assert(Elt->getType() == VTy->getElementType() &&
- "Unexpected type for vector constructor!");
- BuildVecOps.push_back(Elt);
- }
- }
-
- // Insert zero for any unspecified values.
- while (BuildVecOps.size() < VTy->getNumElements())
- BuildVecOps.push_back(Constant::getNullValue(VTy->getElementType()));
- assert(BuildVecOps.size() == VTy->getNumElements() &&
- "Vector constructor specified too many values!");
-
- return BuildVector(BuildVecOps);
- }
-
- assert(AGGREGATE_TYPE_P(type) && "Constructor for scalar type??");
-
- // Start out with the value zero'd out.
- EmitAggregateZero(*DestLoc, type);
-
- VEC(constructor_elt, gc) *elt = CONSTRUCTOR_ELTS(exp);
- switch (TREE_CODE(TREE_TYPE(exp))) {
- case ARRAY_TYPE:
- case RECORD_TYPE:
- default:
- if (elt && VEC_length(constructor_elt, elt)) {
- // We don't handle elements yet.
-
- TODO(exp);
- }
- return 0;
- case QUAL_UNION_TYPE:
- case UNION_TYPE:
- // Store each element of the constructor into the corresponding field of
- // DEST.
- if (!elt || VEC_empty(constructor_elt, elt)) return 0; // no elements
- assert(VEC_length(constructor_elt, elt) == 1
- && "Union CONSTRUCTOR should have one element!");
- tree tree_purpose = VEC_index(constructor_elt, elt, 0)->index;
- tree tree_value = VEC_index(constructor_elt, elt, 0)->value;
- if (!tree_purpose)
- return 0; // Not actually initialized?
-
- if (AGGREGATE_TYPE_P(TREE_TYPE(tree_purpose))) {
- EmitAggregate(tree_value, *DestLoc);
- } else {
- // Scalar value. Evaluate to a register, then do the store.
- Value *V = EmitGimpleReg(tree_value);
- Value *Ptr = Builder.CreateBitCast(DestLoc->Ptr,
- PointerType::getUnqual(V->getType()));
- StoreInst *St = Builder.CreateStore(V, Ptr, DestLoc->Volatile);
- St->setAlignment(DestLoc->getAlignment());
- }
- break;
- }
- return 0;
-}
-
Constant *TreeConstantToLLVM::Convert(tree exp) {
assert((TREE_CONSTANT(exp) || TREE_CODE(exp) == STRING_CST) &&
"Isn't a constant!");
More information about the llvm-commits
mailing list