[cfe-commits] r39673 - in /cfe/cfe/trunk/CodeGen: CGDecl.cpp CGExpr.cpp CodeGenFunction.h
clattner at cs.uiuc.edu
clattner at cs.uiuc.edu
Wed Jul 11 09:47:00 PDT 2007
Author: clattner
Date: Wed Jul 11 11:47:00 2007
New Revision: 39673
URL: http://llvm.org/viewvc/llvm-project?rev=39673&view=rev
Log:
add some infrastructure for codegen'ing complex numbers. implement addition
of complex. We now produce optimal code for:
void test(_Complex float *Y) {
*Y = *Y + *Y;
}
$ clang -emit-llvm cg.c | llvm-as | opt -std-compile-opts | llc -march=x86-64
..
_test:
movss (%rdi), %xmm0
addss %xmm0, %xmm0
movss 4(%rdi), %xmm1
movss %xmm0, (%rdi)
addss %xmm1, %xmm1
movss %xmm1, 4(%rdi)
ret
Modified:
cfe/cfe/trunk/CodeGen/CGDecl.cpp
cfe/cfe/trunk/CodeGen/CGExpr.cpp
cfe/cfe/trunk/CodeGen/CodeGenFunction.h
Modified: cfe/cfe/trunk/CodeGen/CGDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/CodeGen/CGDecl.cpp?rev=39673&r1=39672&r2=39673&view=diff
==============================================================================
--- cfe/cfe/trunk/CodeGen/CGDecl.cpp (original)
+++ cfe/cfe/trunk/CodeGen/CGDecl.cpp Wed Jul 11 11:47:00 2007
@@ -74,7 +74,7 @@
// A normal fixed sized variable becomes an alloca in the entry block.
const llvm::Type *LTy = ConvertType(Ty);
// TODO: Alignment
- DeclPtr = new llvm::AllocaInst(LTy, 0, D.getName(), AllocaInsertPt);
+ DeclPtr = CreateTempAlloca(LTy, D.getName());
} else {
// TODO: Create a dynamic alloca.
assert(0 && "FIXME: Local VLAs not implemented yet");
Modified: cfe/cfe/trunk/CodeGen/CGExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/CodeGen/CGExpr.cpp?rev=39673&r1=39672&r2=39673&view=diff
==============================================================================
--- cfe/cfe/trunk/CodeGen/CGExpr.cpp (original)
+++ cfe/cfe/trunk/CodeGen/CGExpr.cpp Wed Jul 11 11:47:00 2007
@@ -25,6 +25,12 @@
// Miscellaneous Helper Methods
//===--------------------------------------------------------------------===//
+/// CreateTempAlloca - This creates a alloca and inserts it into the entry
+/// block.
+llvm::AllocaInst *CodeGenFunction::CreateTempAlloca(const llvm::Type *Ty,
+ const char *Name) {
+ return new llvm::AllocaInst(Ty, 0, Name, AllocaInsertPt);
+}
/// EvaluateExprAsBool - Perform the usual unary conversions on the specified
/// expression and compare the result against zero, returning an Int1Ty value.
@@ -34,6 +40,36 @@
return ConvertScalarValueToBool(Val, Ty);
}
+/// 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,
+ 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);
+ llvm::Value *RealPtr = Builder.CreateGEP(Ptr, Zero, Zero, "realp");
+ llvm::Value *ImagPtr = Builder.CreateGEP(Ptr, Zero, One, "imagp");
+
+ // FIXME: Handle volatility.
+ Real = Builder.CreateLoad(RealPtr, "real");
+ Imag = Builder.CreateLoad(ImagPtr, "imag");
+}
+
+/// EmitStoreOfComplex - Store the specified real/imag parts into the
+/// specified value pointer.
+void CodeGenFunction::EmitStoreOfComplex(llvm::Value *Real, llvm::Value *Imag,
+ llvm::Value *ResPtr) {
+ llvm::Constant *Zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0);
+ llvm::Constant *One = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1);
+ llvm::Value *RealPtr = Builder.CreateGEP(ResPtr, Zero, Zero, "real");
+ llvm::Value *ImagPtr = Builder.CreateGEP(ResPtr, Zero, One, "imag");
+
+ // FIXME: Handle volatility.
+ Builder.CreateStore(Real, RealPtr);
+ Builder.CreateStore(Imag, ImagPtr);
+}
+
//===--------------------------------------------------------------------===//
// Conversions
//===--------------------------------------------------------------------===//
@@ -260,6 +296,14 @@
return;
}
+ // Don't use memcpy for complex numbers.
+ if (Ty->isComplexType()) {
+ llvm::Value *Real, *Imag;
+ EmitLoadOfComplex(Src, Real, Imag);
+ EmitStoreOfComplex(Real, Imag, Dst.getAddress());
+ return;
+ }
+
// Aggregate assignment turns into llvm.memcpy.
const llvm::Type *SBP = llvm::PointerType::get(llvm::Type::Int8Ty);
llvm::Value *SrcAddr = Src.getAggregateAddr();
@@ -759,9 +803,19 @@
if (LHS.isScalar())
return RValue::get(Builder.CreateAdd(LHS.getVal(), RHS.getVal(), "add"));
-
- assert(0 && "FIXME: This doesn't handle complex operands yet");
+ // 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(E->getType()));
+ EmitStoreOfComplex(ResR, ResI, Res);
+ return RValue::getAggregate(Res);
}
RValue CodeGenFunction::EmitBinarySub(const BinaryOperator *E) {
Modified: cfe/cfe/trunk/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/CodeGen/CodeGenFunction.h?rev=39673&r1=39672&r2=39673&view=diff
==============================================================================
--- cfe/cfe/trunk/CodeGen/CodeGenFunction.h (original)
+++ cfe/cfe/trunk/CodeGen/CodeGenFunction.h Wed Jul 11 11:47:00 2007
@@ -160,11 +160,29 @@
void EmitBlock(llvm::BasicBlock *BB);
-
+ //===--------------------------------------------------------------------===//
+ // Helpers
+ //===--------------------------------------------------------------------===//
+
+ /// CreateTempAlloca - This creates a alloca and inserts it into the entry
+ /// block.
+ llvm::AllocaInst *CreateTempAlloca(const llvm::Type *Ty,
+ const char *Name = "tmp");
+
/// EvaluateExprAsBool - Perform the usual unary conversions on the specified
/// expression and compare the result against zero, returning an Int1Ty value.
llvm::Value *EvaluateExprAsBool(const Expr *E);
+
+ /// 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);
+
+ /// EmitStoreOfComplex - Store the specified real/imag parts into the
+ /// specified value pointer.
+ void EmitStoreOfComplex(llvm::Value *Real, llvm::Value *Imag,
+ llvm::Value *ResPtr);
+
//===--------------------------------------------------------------------===//
// Conversions
//===--------------------------------------------------------------------===//
More information about the cfe-commits
mailing list