[cfe-commits] r41215 - in /cfe/trunk/CodeGen: CGAggExpr.cpp CGExpr.cpp CodeGenFunction.h
Chris Lattner
sabre at nondot.org
Mon Aug 20 21:59:28 PDT 2007
Author: lattner
Date: Mon Aug 20 23:59:27 2007
New Revision: 41215
URL: http://llvm.org/viewvc/llvm-project?rev=41215&view=rev
Log:
reimplement addition of complex numbers.
Modified:
cfe/trunk/CodeGen/CGAggExpr.cpp
cfe/trunk/CodeGen/CGExpr.cpp
cfe/trunk/CodeGen/CodeGenFunction.h
Modified: cfe/trunk/CodeGen/CGAggExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/CodeGen/CGAggExpr.cpp?rev=41215&r1=41214&r2=41215&view=diff
==============================================================================
--- cfe/trunk/CodeGen/CGAggExpr.cpp (original)
+++ cfe/trunk/CodeGen/CGAggExpr.cpp Mon Aug 20 23:59:27 2007
@@ -20,40 +20,6 @@
using namespace clang;
using namespace CodeGen;
-// FIXME: Handle volatility!
-void CodeGenFunction::EmitAggregateCopy(llvm::Value *DestPtr,
- llvm::Value *SrcPtr, QualType Ty) {
- // Don't use memcpy for complex numbers.
- if (Ty->isComplexType()) {
- llvm::Value *Real, *Imag;
- EmitLoadOfComplex(RValue::getAggregate(SrcPtr), Real, Imag);
- EmitStoreOfComplex(Real, Imag, DestPtr);
- return;
- }
-
- // Aggregate assignment turns into llvm.memcpy.
- const llvm::Type *BP = llvm::PointerType::get(llvm::Type::Int8Ty);
- if (DestPtr->getType() != BP)
- DestPtr = Builder.CreateBitCast(DestPtr, BP, "tmp");
- if (SrcPtr->getType() != BP)
- SrcPtr = Builder.CreateBitCast(SrcPtr, BP, "tmp");
-
- // Get size and alignment info for this aggregate.
- std::pair<uint64_t, unsigned> TypeInfo =
- getContext().getTypeInfo(Ty, SourceLocation());
-
- // FIXME: Handle variable sized types.
- const llvm::Type *IntPtr = llvm::IntegerType::get(LLVMPointerWidth);
-
- llvm::Value *MemCpyOps[4] = {
- DestPtr, SrcPtr,
- llvm::ConstantInt::get(IntPtr, TypeInfo.first),
- llvm::ConstantInt::get(llvm::Type::Int32Ty, TypeInfo.second)
- };
-
- Builder.CreateCall(CGM.getMemCpyFn(), MemCpyOps, MemCpyOps+4);
-}
-
//===----------------------------------------------------------------------===//
// Aggregate Expression Emitter
//===----------------------------------------------------------------------===//
@@ -68,11 +34,26 @@
: CGF(cgf), DestPtr(destPtr), VolatileDest(volatileDest) {
}
+ typedef std::pair<llvm::Value *, llvm::Value *> ComplexPairTy;
+
+ //===--------------------------------------------------------------------===//
+ // Utilities
+ //===--------------------------------------------------------------------===//
+
/// EmitAggLoadOfLValue - Given an expression with aggregate type that
/// represents a value lvalue, this method emits the address of the lvalue,
/// then loads the result into DestPtr.
void EmitAggLoadOfLValue(const Expr *E);
+ /// EmitComplexExpr - Emit the specified complex expression, returning the
+ /// real and imaginary values.
+ ComplexPairTy EmitComplexExpr(const Expr *E);
+
+
+ //===--------------------------------------------------------------------===//
+ // Visitor Methods
+ //===--------------------------------------------------------------------===//
+
void VisitStmt(Stmt *S) {
fprintf(stderr, "Unimplemented agg expr!\n");
S->dump();
@@ -89,6 +70,7 @@
// case Expr::CastExprClass:
// case Expr::CallExprClass:
void VisitBinaryOperator(const BinaryOperator *BO);
+ void VisitBinAdd(const BinaryOperator *E);
void VisitBinAssign(const BinaryOperator *E);
@@ -97,20 +79,26 @@
};
} // end anonymous namespace.
+//===----------------------------------------------------------------------===//
+// Utilities
+//===----------------------------------------------------------------------===//
-
-
-/// EmitAggExpr - Emit the computation of the specified expression of
-/// aggregate type. The result is computed into DestPtr. Note that if
-/// DestPtr is null, the value of the aggregate expression is not needed.
-void CodeGenFunction::EmitAggExpr(const Expr *E, llvm::Value *DestPtr,
- bool VolatileDest) {
- assert(E && hasAggregateLLVMType(E->getType()) &&
- "Invalid aggregate expression to emit");
-
- AggExprEmitter(*this, DestPtr, VolatileDest).Visit(const_cast<Expr*>(E));
+/// EmitComplexExpr - Emit the specified complex expression, returning the
+/// real and imaginary values.
+AggExprEmitter::ComplexPairTy AggExprEmitter::EmitComplexExpr(const Expr *E) {
+ // Create a temporary alloca to hold this result.
+ llvm::Value *TmpPtr = CGF.CreateTempAlloca(CGF.ConvertType(E->getType()));
+
+ // Emit the expression into TmpPtr.
+ AggExprEmitter(CGF, TmpPtr, false).Visit(const_cast<Expr*>(E));
+
+ // Return the real/imag values by reloading them from the stack.
+ llvm::Value *Real, *Imag;
+ CGF.EmitLoadOfComplex(TmpPtr, Real, Imag);
+ return std::make_pair(Real, Imag);
}
+
/// EmitAggLoadOfLValue - Given an expression with aggregate type that
/// represents a value lvalue, this method emits the address of the lvalue,
/// then loads the result into DestPtr.
@@ -127,6 +115,10 @@
CGF.EmitAggregateCopy(DestPtr, SrcPtr, E->getType());
}
+//===----------------------------------------------------------------------===//
+// Visitor Methods
+//===----------------------------------------------------------------------===//
+
void AggExprEmitter::VisitBinaryOperator(const BinaryOperator *E) {
fprintf(stderr, "Unimplemented aggregate binary expr!\n");
E->dump();
@@ -258,6 +250,17 @@
#endif
}
+void AggExprEmitter::VisitBinAdd(const BinaryOperator *E) {
+ // This must be a complex number.
+ ComplexPairTy LHS = EmitComplexExpr(E->getLHS());
+ ComplexPairTy RHS = EmitComplexExpr(E->getRHS());
+
+ llvm::Value *ResR = CGF.Builder.CreateAdd(LHS.first, RHS.first, "add.r");
+ llvm::Value *ResI = CGF.Builder.CreateAdd(LHS.second, RHS.second, "add.i");
+
+ CGF.EmitStoreOfComplex(ResR, ResI, DestPtr /*FIXME: Volatile!*/);
+}
+
void AggExprEmitter::VisitBinAssign(const BinaryOperator *E) {
assert(E->getLHS()->getType().getCanonicalType() ==
E->getRHS()->getType().getCanonicalType() && "Invalid assignment");
@@ -298,3 +301,53 @@
CGF.EmitBlock(ContBlock);
}
+
+//===----------------------------------------------------------------------===//
+// Entry Points into this File
+//===----------------------------------------------------------------------===//
+
+/// EmitAggExpr - Emit the computation of the specified expression of
+/// aggregate type. The result is computed into DestPtr. Note that if
+/// DestPtr is null, the value of the aggregate expression is not needed.
+void CodeGenFunction::EmitAggExpr(const Expr *E, llvm::Value *DestPtr,
+ bool VolatileDest) {
+ assert(E && hasAggregateLLVMType(E->getType()) &&
+ "Invalid aggregate expression to emit");
+
+ AggExprEmitter(*this, DestPtr, VolatileDest).Visit(const_cast<Expr*>(E));
+}
+
+
+// FIXME: Handle volatility!
+void CodeGenFunction::EmitAggregateCopy(llvm::Value *DestPtr,
+ llvm::Value *SrcPtr, QualType Ty) {
+ // Don't use memcpy for complex numbers.
+ if (Ty->isComplexType()) {
+ llvm::Value *Real, *Imag;
+ EmitLoadOfComplex(SrcPtr, Real, Imag);
+ EmitStoreOfComplex(Real, Imag, DestPtr);
+ return;
+ }
+
+ // Aggregate assignment turns into llvm.memcpy.
+ const llvm::Type *BP = llvm::PointerType::get(llvm::Type::Int8Ty);
+ if (DestPtr->getType() != BP)
+ DestPtr = Builder.CreateBitCast(DestPtr, BP, "tmp");
+ if (SrcPtr->getType() != BP)
+ SrcPtr = Builder.CreateBitCast(SrcPtr, BP, "tmp");
+
+ // Get size and alignment info for this aggregate.
+ std::pair<uint64_t, unsigned> TypeInfo =
+ getContext().getTypeInfo(Ty, SourceLocation());
+
+ // FIXME: Handle variable sized types.
+ const llvm::Type *IntPtr = llvm::IntegerType::get(LLVMPointerWidth);
+
+ llvm::Value *MemCpyOps[4] = {
+ DestPtr, SrcPtr,
+ llvm::ConstantInt::get(IntPtr, TypeInfo.first),
+ llvm::ConstantInt::get(llvm::Type::Int32Ty, TypeInfo.second)
+ };
+
+ Builder.CreateCall(CGM.getMemCpyFn(), MemCpyOps, MemCpyOps+4);
+}
Modified: cfe/trunk/CodeGen/CGExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/CodeGen/CGExpr.cpp?rev=41215&r1=41214&r2=41215&view=diff
==============================================================================
--- cfe/trunk/CodeGen/CGExpr.cpp (original)
+++ cfe/trunk/CodeGen/CGExpr.cpp Mon Aug 20 23:59:27 2007
@@ -42,15 +42,13 @@
/// EmitLoadOfComplex - Given an RValue reference for a complex, emit code to
/// load the real and imaginary pieces, returning them as Real/Imag.
-void CodeGenFunction::EmitLoadOfComplex(RValue V,
+void CodeGenFunction::EmitLoadOfComplex(llvm::Value *SrcPtr,
llvm::Value *&Real, llvm::Value *&Imag){
- llvm::Value *Ptr = V.getAggregateAddr();
-
llvm::Constant *Zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0);
llvm::Constant *One = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1);
// FIXME: It would be nice to make this "Ptr->getName()+realp"
- llvm::Value *RealPtr = Builder.CreateGEP(Ptr, Zero, Zero, "realp");
- llvm::Value *ImagPtr = Builder.CreateGEP(Ptr, Zero, One, "imagp");
+ llvm::Value *RealPtr = Builder.CreateGEP(SrcPtr, Zero, Zero, "realp");
+ llvm::Value *ImagPtr = Builder.CreateGEP(SrcPtr, Zero, One, "imagp");
// FIXME: Handle volatility.
// FIXME: It would be nice to make this "Ptr->getName()+real"
@@ -1106,12 +1104,12 @@
}
RValue CodeGenFunction::EmitMul(RValue LHS, RValue RHS, QualType ResTy) {
- if (LHS.isScalar())
- return RValue::get(Builder.CreateMul(LHS.getVal(), RHS.getVal(), "mul"));
+ return RValue::get(Builder.CreateMul(LHS.getVal(), RHS.getVal(), "mul"));
+#if 0
// Otherwise, this must be a complex number.
llvm::Value *LHSR, *LHSI, *RHSR, *RHSI;
-
+
EmitLoadOfComplex(LHS, LHSR, LHSI);
EmitLoadOfComplex(RHS, RHSR, RHSI);
@@ -1126,6 +1124,7 @@
llvm::Value *Res = CreateTempAlloca(ConvertType(ResTy));
EmitStoreOfComplex(ResR, ResI, Res);
return RValue::getAggregate(Res);
+#endif
}
RValue CodeGenFunction::EmitDiv(RValue LHS, RValue RHS, QualType ResTy) {
@@ -1157,21 +1156,7 @@
}
RValue CodeGenFunction::EmitAdd(RValue LHS, RValue RHS, QualType ResTy) {
- if (LHS.isScalar())
- return RValue::get(Builder.CreateAdd(LHS.getVal(), RHS.getVal(), "add"));
-
- // Otherwise, this must be a complex number.
- llvm::Value *LHSR, *LHSI, *RHSR, *RHSI;
-
- EmitLoadOfComplex(LHS, LHSR, LHSI);
- EmitLoadOfComplex(RHS, RHSR, RHSI);
-
- llvm::Value *ResR = Builder.CreateAdd(LHSR, RHSR, "add.r");
- llvm::Value *ResI = Builder.CreateAdd(LHSI, RHSI, "add.i");
-
- llvm::Value *Res = CreateTempAlloca(ConvertType(ResTy));
- EmitStoreOfComplex(ResR, ResI, Res);
- return RValue::getAggregate(Res);
+ return RValue::get(Builder.CreateAdd(LHS.getVal(), RHS.getVal(), "add"));
}
RValue CodeGenFunction::EmitPointerAdd(RValue LHS, QualType LHSTy,
@@ -1285,6 +1270,7 @@
LHS.getVal(), RHS.getVal(), "cmp");
}
} else {
+#if 0
// Struct/union/complex
llvm::Value *LHSR, *LHSI, *RHSR, *RHSI, *ResultR, *ResultI;
EmitLoadOfComplex(LHS, LHSR, LHSI);
@@ -1303,6 +1289,7 @@
} else {
assert(0 && "Complex comparison other than == or != ?");
}
+#endif
}
// ZExt result to int.
Modified: cfe/trunk/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/CodeGen/CodeGenFunction.h?rev=41215&r1=41214&r2=41215&view=diff
==============================================================================
--- cfe/trunk/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/CodeGen/CodeGenFunction.h Mon Aug 20 23:59:27 2007
@@ -249,7 +249,8 @@
/// EmitLoadOfComplex - Given an RValue reference for a complex, emit code to
/// load the real and imaginary pieces, returning them as Real/Imag.
- void EmitLoadOfComplex(RValue V, llvm::Value *&Real, llvm::Value *&Imag);
+ void EmitLoadOfComplex(llvm::Value *SrcPtr, llvm::Value *&Real,
+ llvm::Value *&Imag);
/// EmitStoreOfComplex - Store the specified real/imag parts into the
/// specified value pointer.
More information about the cfe-commits
mailing list