blob: f20157b3b1e870cadc92f370f4c4e9a2bee395cb [file] [log] [blame]
Chris Lattner8d0cc2f2007-08-21 05:54:00 +00001//===--- CGComplexExpr.cpp - Emit LLVM Code for Complex Exprs -------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file was developed by Chris Lattner and is distributed under
6// the University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This contains code to emit Expr nodes with complex types as LLVM code.
11//
12//===----------------------------------------------------------------------===//
13
14#include "CodeGenFunction.h"
15#include "CodeGenModule.h"
16#include "clang/AST/AST.h"
17#include "llvm/Constants.h"
18#include "llvm/Function.h"
19#include "llvm/Support/Compiler.h"
20using namespace clang;
21using namespace CodeGen;
22
23//===----------------------------------------------------------------------===//
Chris Lattneredb3bf02007-08-21 05:54:53 +000024// Complex Expression Emitter
Chris Lattner8d0cc2f2007-08-21 05:54:00 +000025//===----------------------------------------------------------------------===//
26
Chris Lattner5280c5f2007-08-21 16:57:55 +000027typedef CodeGenFunction::ComplexPairTy ComplexPairTy;
Chris Lattner8d0cc2f2007-08-21 05:54:00 +000028
29namespace {
30class VISIBILITY_HIDDEN ComplexExprEmitter
31 : public StmtVisitor<ComplexExprEmitter, ComplexPairTy> {
32 CodeGenFunction &CGF;
Chris Lattner950b5d92007-08-21 17:39:38 +000033 llvm::LLVMBuilder &Builder;
Chris Lattner8d0cc2f2007-08-21 05:54:00 +000034public:
Chris Lattner950b5d92007-08-21 17:39:38 +000035 ComplexExprEmitter(CodeGenFunction &cgf) : CGF(cgf), Builder(CGF.Builder) {
Chris Lattner8d0cc2f2007-08-21 05:54:00 +000036 }
37
38
39 //===--------------------------------------------------------------------===//
40 // Utilities
41 //===--------------------------------------------------------------------===//
42
43 /// EmitLoadOfLValue - Given an expression with complex type that represents a
44 /// value l-value, this method emits the address of the l-value, then loads
45 /// and returns the result.
Chris Lattner1cd8f5c2007-08-21 17:28:34 +000046 ComplexPairTy EmitLoadOfLValue(const Expr *E) {
Chris Lattner689bfe42007-08-21 18:02:02 +000047 LValue LV = CGF.EmitLValue(E);
48 // FIXME: Volatile
49 return EmitLoadOfComplex(LV.getAddress(), false);
Chris Lattner1cd8f5c2007-08-21 17:28:34 +000050 }
Chris Lattner8d0cc2f2007-08-21 05:54:00 +000051
Chris Lattner1cd8f5c2007-08-21 17:28:34 +000052 /// EmitLoadOfComplex - Given a pointer to a complex value, emit code to load
53 /// the real and imaginary pieces.
Chris Lattner689bfe42007-08-21 18:02:02 +000054 ComplexPairTy EmitLoadOfComplex(llvm::Value *SrcPtr, bool isVolatile);
Chris Lattner1cd8f5c2007-08-21 17:28:34 +000055
56 /// EmitStoreOfComplex - Store the specified real/imag parts into the
57 /// specified value pointer.
Chris Lattner689bfe42007-08-21 18:02:02 +000058 void EmitStoreOfComplex(ComplexPairTy Val, llvm::Value *ResPtr, bool isVol);
Chris Lattner8d0cc2f2007-08-21 05:54:00 +000059
60 //===--------------------------------------------------------------------===//
61 // Visitor Methods
62 //===--------------------------------------------------------------------===//
Chris Lattner7cff5302007-08-21 18:51:13 +000063
Chris Lattner8d0cc2f2007-08-21 05:54:00 +000064 ComplexPairTy VisitStmt(Stmt *S) {
Chris Lattner8d0cc2f2007-08-21 05:54:00 +000065 S->dump();
Chris Lattner7cff5302007-08-21 18:51:13 +000066 assert(0 && "Stmt can't have complex result type!");
Chris Lattner8d0cc2f2007-08-21 05:54:00 +000067 return ComplexPairTy();
68 }
Chris Lattner7cff5302007-08-21 18:51:13 +000069 ComplexPairTy VisitExpr(Expr *S);
Chris Lattner8d0cc2f2007-08-21 05:54:00 +000070 ComplexPairTy VisitParenExpr(ParenExpr *PE) { return Visit(PE->getSubExpr());}
71
72 // l-values.
Chris Lattner55029ed2007-08-21 18:03:58 +000073 ComplexPairTy VisitDeclRefExpr(Expr *E) { return EmitLoadOfLValue(E); }
74 ComplexPairTy VisitArraySubscriptExpr(Expr *E) { return EmitLoadOfLValue(E); }
Chris Lattner8d0cc2f2007-08-21 05:54:00 +000075
76 // Operators.
Chris Lattnerd4aae9b2007-08-21 20:08:23 +000077 ComplexPairTy VisitUnaryPlus (const UnaryOperator *E) {
78 return Visit(E->getSubExpr());
79 }
80 ComplexPairTy VisitUnaryMinus (const UnaryOperator *E);
Chris Lattner8d0cc2f2007-08-21 05:54:00 +000081 // case Expr::ImplicitCastExprClass:
82 // case Expr::CastExprClass:
83 // case Expr::CallExprClass:
Chris Lattner9a4e2c62007-08-21 16:34:16 +000084 ComplexPairTy VisitBinMul (const BinaryOperator *E);
Chris Lattner8d0cc2f2007-08-21 05:54:00 +000085 ComplexPairTy VisitBinAdd (const BinaryOperator *E);
Chris Lattner7c257f42007-08-21 17:12:50 +000086 // FIXME: div/rem
87 // GCC rejects and/or/xor for integer complex.
88 // Logical and/or always return int, never complex.
Chris Lattner5280c5f2007-08-21 16:57:55 +000089
90 // No comparisons produce a complex result.
Chris Lattner8d0cc2f2007-08-21 05:54:00 +000091 ComplexPairTy VisitBinAssign (const BinaryOperator *E);
92
Chris Lattnerc15b0db2007-08-21 17:15:50 +000093 ComplexPairTy VisitBinComma (const BinaryOperator *E);
94
Chris Lattner8d0cc2f2007-08-21 05:54:00 +000095
96 ComplexPairTy VisitConditionalOperator(const ConditionalOperator *CO);
97 // case Expr::ChooseExprClass:
98};
99} // end anonymous namespace.
100
101//===----------------------------------------------------------------------===//
102// Utilities
103//===----------------------------------------------------------------------===//
104
Chris Lattner1cd8f5c2007-08-21 17:28:34 +0000105/// EmitLoadOfComplex - Given an RValue reference for a complex, emit code to
106/// load the real and imaginary pieces, returning them as Real/Imag.
Chris Lattner689bfe42007-08-21 18:02:02 +0000107ComplexPairTy ComplexExprEmitter::EmitLoadOfComplex(llvm::Value *SrcPtr,
108 bool isVolatile) {
Chris Lattner1cd8f5c2007-08-21 17:28:34 +0000109 llvm::Constant *Zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0);
110 llvm::Constant *One = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1);
111 // FIXME: It would be nice to make this "Ptr->getName()+realp"
Chris Lattner950b5d92007-08-21 17:39:38 +0000112 llvm::Value *RealPtr = Builder.CreateGEP(SrcPtr, Zero, Zero, "realp");
113 llvm::Value *ImagPtr = Builder.CreateGEP(SrcPtr, Zero, One, "imagp");
Chris Lattner8d0cc2f2007-08-21 05:54:00 +0000114
Chris Lattner1cd8f5c2007-08-21 17:28:34 +0000115 // FIXME: It would be nice to make this "Ptr->getName()+real"
Chris Lattner689bfe42007-08-21 18:02:02 +0000116 llvm::Value *Real = Builder.CreateLoad(RealPtr, isVolatile, "real");
117 llvm::Value *Imag = Builder.CreateLoad(ImagPtr, isVolatile, "imag");
Chris Lattner8d0cc2f2007-08-21 05:54:00 +0000118 return ComplexPairTy(Real, Imag);
119}
120
Chris Lattner1cd8f5c2007-08-21 17:28:34 +0000121/// EmitStoreOfComplex - Store the specified real/imag parts into the
122/// specified value pointer.
Chris Lattner689bfe42007-08-21 18:02:02 +0000123void ComplexExprEmitter::EmitStoreOfComplex(ComplexPairTy Val, llvm::Value *Ptr,
124 bool isVolatile) {
Chris Lattner1cd8f5c2007-08-21 17:28:34 +0000125 llvm::Constant *Zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0);
126 llvm::Constant *One = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1);
Chris Lattner950b5d92007-08-21 17:39:38 +0000127 llvm::Value *RealPtr = Builder.CreateGEP(Ptr, Zero, Zero, "real");
128 llvm::Value *ImagPtr = Builder.CreateGEP(Ptr, Zero, One, "imag");
Chris Lattner1cd8f5c2007-08-21 17:28:34 +0000129
Chris Lattner689bfe42007-08-21 18:02:02 +0000130 Builder.CreateStore(Val.first, RealPtr, isVolatile);
131 Builder.CreateStore(Val.second, ImagPtr, isVolatile);
Chris Lattner1cd8f5c2007-08-21 17:28:34 +0000132}
133
134
135
Chris Lattner8d0cc2f2007-08-21 05:54:00 +0000136//===----------------------------------------------------------------------===//
137// Visitor Methods
138//===----------------------------------------------------------------------===//
139
Chris Lattner7cff5302007-08-21 18:51:13 +0000140ComplexPairTy ComplexExprEmitter::VisitExpr(Expr *E) {
141 fprintf(stderr, "Unimplemented complex expr!\n");
Chris Lattner8d0cc2f2007-08-21 05:54:00 +0000142 E->dump();
Chris Lattner7cff5302007-08-21 18:51:13 +0000143 const llvm::Type *EltTy =
144 CGF.ConvertType(E->getType()->getAsComplexType()->getElementType());
145 llvm::Value *U = llvm::UndefValue::get(EltTy);
146 return ComplexPairTy(U, U);
Chris Lattner8d0cc2f2007-08-21 05:54:00 +0000147}
148
Chris Lattnerd4aae9b2007-08-21 20:08:23 +0000149ComplexPairTy ComplexExprEmitter::VisitUnaryMinus(const UnaryOperator *E) {
150 ComplexPairTy Op = Visit(E->getSubExpr());
151 llvm::Value *ResR = Builder.CreateNeg(Op.first, "neg.r");
152 llvm::Value *ResI = Builder.CreateNeg(Op.second, "neg.i");
153 return ComplexPairTy(ResR, ResI);
154}
155
156
Chris Lattner8d0cc2f2007-08-21 05:54:00 +0000157ComplexPairTy ComplexExprEmitter::VisitBinAdd(const BinaryOperator *E) {
Chris Lattner8d0cc2f2007-08-21 05:54:00 +0000158 ComplexPairTy LHS = Visit(E->getLHS());
159 ComplexPairTy RHS = Visit(E->getRHS());
160
Chris Lattner950b5d92007-08-21 17:39:38 +0000161 llvm::Value *ResR = Builder.CreateAdd(LHS.first, RHS.first, "add.r");
162 llvm::Value *ResI = Builder.CreateAdd(LHS.second, RHS.second, "add.i");
Chris Lattner8d0cc2f2007-08-21 05:54:00 +0000163
164 return ComplexPairTy(ResR, ResI);
165}
166
Chris Lattner9a4e2c62007-08-21 16:34:16 +0000167ComplexPairTy ComplexExprEmitter::VisitBinMul(const BinaryOperator *E) {
168 ComplexPairTy LHS = Visit(E->getLHS());
169 ComplexPairTy RHS = Visit(E->getRHS());
170
Chris Lattner950b5d92007-08-21 17:39:38 +0000171 llvm::Value *ResRl = Builder.CreateMul(LHS.first, RHS.first, "mul.rl");
172 llvm::Value *ResRr = Builder.CreateMul(LHS.second, RHS.second, "mul.rr");
173 llvm::Value *ResR = Builder.CreateSub(ResRl, ResRr, "mul.r");
Chris Lattner9a4e2c62007-08-21 16:34:16 +0000174
Chris Lattner950b5d92007-08-21 17:39:38 +0000175 llvm::Value *ResIl = Builder.CreateMul(LHS.second, RHS.first, "mul.il");
176 llvm::Value *ResIr = Builder.CreateMul(LHS.first, RHS.second, "mul.ir");
177 llvm::Value *ResI = Builder.CreateAdd(ResIl, ResIr, "mul.i");
Chris Lattner9a4e2c62007-08-21 16:34:16 +0000178
179 return ComplexPairTy(ResR, ResI);
180}
181
Chris Lattner8d0cc2f2007-08-21 05:54:00 +0000182ComplexPairTy ComplexExprEmitter::VisitBinAssign(const BinaryOperator *E) {
183 assert(E->getLHS()->getType().getCanonicalType() ==
184 E->getRHS()->getType().getCanonicalType() && "Invalid assignment");
185 // Emit the RHS.
186 ComplexPairTy Val = Visit(E->getRHS());
187
188 // Compute the address to store into.
189 LValue LHS = CGF.EmitLValue(E->getLHS());
190
191 // Store into it.
192 // FIXME: Volatility!
Chris Lattner689bfe42007-08-21 18:02:02 +0000193 EmitStoreOfComplex(Val, LHS.getAddress(), false);
Chris Lattner8d0cc2f2007-08-21 05:54:00 +0000194 return Val;
195}
196
Chris Lattnerc15b0db2007-08-21 17:15:50 +0000197ComplexPairTy ComplexExprEmitter::VisitBinComma(const BinaryOperator *E) {
198 CGF.EmitStmt(E->getLHS());
199 return Visit(E->getRHS());
200}
Chris Lattner8d0cc2f2007-08-21 05:54:00 +0000201
202ComplexPairTy ComplexExprEmitter::
203VisitConditionalOperator(const ConditionalOperator *E) {
204 llvm::BasicBlock *LHSBlock = new llvm::BasicBlock("cond.?");
205 llvm::BasicBlock *RHSBlock = new llvm::BasicBlock("cond.:");
206 llvm::BasicBlock *ContBlock = new llvm::BasicBlock("cond.cont");
207
208 llvm::Value *Cond = CGF.EvaluateExprAsBool(E->getCond());
Chris Lattner950b5d92007-08-21 17:39:38 +0000209 Builder.CreateCondBr(Cond, LHSBlock, RHSBlock);
Chris Lattner8d0cc2f2007-08-21 05:54:00 +0000210
211 CGF.EmitBlock(LHSBlock);
212
213 // Handle the GNU extension for missing LHS.
Chris Lattneredb3bf02007-08-21 05:54:53 +0000214 assert(E->getLHS() && "Must have LHS for complex value");
Chris Lattner8d0cc2f2007-08-21 05:54:00 +0000215
216 ComplexPairTy LHS = Visit(E->getLHS());
Chris Lattner950b5d92007-08-21 17:39:38 +0000217 Builder.CreateBr(ContBlock);
218 LHSBlock = Builder.GetInsertBlock();
Chris Lattner8d0cc2f2007-08-21 05:54:00 +0000219
220 CGF.EmitBlock(RHSBlock);
221
222 ComplexPairTy RHS = Visit(E->getRHS());
Chris Lattner950b5d92007-08-21 17:39:38 +0000223 Builder.CreateBr(ContBlock);
224 RHSBlock = Builder.GetInsertBlock();
Chris Lattner8d0cc2f2007-08-21 05:54:00 +0000225
226 CGF.EmitBlock(ContBlock);
227
228 // Create a PHI node for the real part.
Chris Lattner950b5d92007-08-21 17:39:38 +0000229 llvm::PHINode *RealPN = Builder.CreatePHI(LHS.first->getType(), "cond.r");
Chris Lattner8d0cc2f2007-08-21 05:54:00 +0000230 RealPN->reserveOperandSpace(2);
231 RealPN->addIncoming(LHS.first, LHSBlock);
232 RealPN->addIncoming(RHS.first, RHSBlock);
233
234 // Create a PHI node for the imaginary part.
Chris Lattner950b5d92007-08-21 17:39:38 +0000235 llvm::PHINode *ImagPN = Builder.CreatePHI(LHS.first->getType(), "cond.i");
Chris Lattner8d0cc2f2007-08-21 05:54:00 +0000236 ImagPN->reserveOperandSpace(2);
237 ImagPN->addIncoming(LHS.second, LHSBlock);
238 ImagPN->addIncoming(RHS.second, RHSBlock);
239
240 return ComplexPairTy(RealPN, ImagPN);
241}
242
243//===----------------------------------------------------------------------===//
244// Entry Point into this File
245//===----------------------------------------------------------------------===//
246
247/// EmitComplexExpr - Emit the computation of the specified expression of
248/// complex type, ignoring the result.
Chris Lattner5280c5f2007-08-21 16:57:55 +0000249ComplexPairTy CodeGenFunction::EmitComplexExpr(const Expr *E) {
Chris Lattner8d0cc2f2007-08-21 05:54:00 +0000250 assert(E && E->getType()->isComplexType() &&
251 "Invalid complex expression to emit");
252
Chris Lattner5280c5f2007-08-21 16:57:55 +0000253 return ComplexExprEmitter(*this).Visit(const_cast<Expr*>(E));
Chris Lattner8d0cc2f2007-08-21 05:54:00 +0000254}
255