blob: 0382796501dff8ab7542e07a7ab947ff3a19e4c4 [file] [log] [blame]
Chris Lattnerb6ef18a2007-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 Lattner05ba49c2007-08-21 05:54:53 +000024// Complex Expression Emitter
Chris Lattnerb6ef18a2007-08-21 05:54:00 +000025//===----------------------------------------------------------------------===//
26
Chris Lattner58dee102007-08-21 16:57:55 +000027typedef CodeGenFunction::ComplexPairTy ComplexPairTy;
Chris Lattnerb6ef18a2007-08-21 05:54:00 +000028
29namespace {
30class VISIBILITY_HIDDEN ComplexExprEmitter
31 : public StmtVisitor<ComplexExprEmitter, ComplexPairTy> {
32 CodeGenFunction &CGF;
Chris Lattner5083a532007-08-21 17:39:38 +000033 llvm::LLVMBuilder &Builder;
Chris Lattnerb6ef18a2007-08-21 05:54:00 +000034public:
Chris Lattner5083a532007-08-21 17:39:38 +000035 ComplexExprEmitter(CodeGenFunction &cgf) : CGF(cgf), Builder(CGF.Builder) {
Chris Lattnerb6ef18a2007-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 Lattner46d7d9f2007-08-21 17:28:34 +000046 ComplexPairTy EmitLoadOfLValue(const Expr *E) {
47 return EmitLoadOfComplex(CGF.EmitLValue(E).getAddress());
48 }
Chris Lattnerb6ef18a2007-08-21 05:54:00 +000049
Chris Lattner46d7d9f2007-08-21 17:28:34 +000050 /// EmitLoadOfComplex - Given a pointer to a complex value, emit code to load
51 /// the real and imaginary pieces.
52 ComplexPairTy EmitLoadOfComplex(llvm::Value *SrcPtr);
53
54 /// EmitStoreOfComplex - Store the specified real/imag parts into the
55 /// specified value pointer.
56 void EmitStoreOfComplex(ComplexPairTy Val, llvm::Value *ResPtr);
Chris Lattnerb6ef18a2007-08-21 05:54:00 +000057
58 //===--------------------------------------------------------------------===//
59 // Visitor Methods
60 //===--------------------------------------------------------------------===//
61
62 ComplexPairTy VisitStmt(Stmt *S) {
63 fprintf(stderr, "Unimplemented agg expr!\n");
64 S->dump();
65 return ComplexPairTy();
66 }
67 ComplexPairTy VisitParenExpr(ParenExpr *PE) { return Visit(PE->getSubExpr());}
68
69 // l-values.
70 ComplexPairTy VisitDeclRefExpr(DeclRefExpr *DRE) {
71 return EmitLoadOfLValue(DRE);
72 }
73 // case Expr::ArraySubscriptExprClass:
74
75 // Operators.
76 // case Expr::UnaryOperatorClass:
77 // case Expr::ImplicitCastExprClass:
78 // case Expr::CastExprClass:
79 // case Expr::CallExprClass:
80 ComplexPairTy VisitBinaryOperator(const BinaryOperator *BO);
Chris Lattner2823c192007-08-21 16:34:16 +000081 ComplexPairTy VisitBinMul (const BinaryOperator *E);
Chris Lattnerb6ef18a2007-08-21 05:54:00 +000082 ComplexPairTy VisitBinAdd (const BinaryOperator *E);
Chris Lattner4034edb2007-08-21 17:12:50 +000083 // FIXME: div/rem
84 // GCC rejects and/or/xor for integer complex.
85 // Logical and/or always return int, never complex.
Chris Lattner58dee102007-08-21 16:57:55 +000086
87 // No comparisons produce a complex result.
Chris Lattnerb6ef18a2007-08-21 05:54:00 +000088 ComplexPairTy VisitBinAssign (const BinaryOperator *E);
89
Chris Lattner756a4d82007-08-21 17:15:50 +000090 ComplexPairTy VisitBinComma (const BinaryOperator *E);
91
Chris Lattnerb6ef18a2007-08-21 05:54:00 +000092
93 ComplexPairTy VisitConditionalOperator(const ConditionalOperator *CO);
94 // case Expr::ChooseExprClass:
95};
96} // end anonymous namespace.
97
98//===----------------------------------------------------------------------===//
99// Utilities
100//===----------------------------------------------------------------------===//
101
Chris Lattner46d7d9f2007-08-21 17:28:34 +0000102/// EmitLoadOfComplex - Given an RValue reference for a complex, emit code to
103/// load the real and imaginary pieces, returning them as Real/Imag.
104ComplexPairTy ComplexExprEmitter::EmitLoadOfComplex(llvm::Value *SrcPtr) {
105 llvm::Constant *Zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0);
106 llvm::Constant *One = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1);
107 // FIXME: It would be nice to make this "Ptr->getName()+realp"
Chris Lattner5083a532007-08-21 17:39:38 +0000108 llvm::Value *RealPtr = Builder.CreateGEP(SrcPtr, Zero, Zero, "realp");
109 llvm::Value *ImagPtr = Builder.CreateGEP(SrcPtr, Zero, One, "imagp");
Chris Lattnerb6ef18a2007-08-21 05:54:00 +0000110
Chris Lattner46d7d9f2007-08-21 17:28:34 +0000111 // FIXME: Handle volatility.
112 // FIXME: It would be nice to make this "Ptr->getName()+real"
Chris Lattner5083a532007-08-21 17:39:38 +0000113 llvm::Value *Real = Builder.CreateLoad(RealPtr, "real");
114 llvm::Value *Imag = Builder.CreateLoad(ImagPtr, "imag");
Chris Lattnerb6ef18a2007-08-21 05:54:00 +0000115 return ComplexPairTy(Real, Imag);
116}
117
Chris Lattner46d7d9f2007-08-21 17:28:34 +0000118/// EmitStoreOfComplex - Store the specified real/imag parts into the
119/// specified value pointer.
120void ComplexExprEmitter::EmitStoreOfComplex(ComplexPairTy V, llvm::Value *Ptr) {
121 llvm::Constant *Zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0);
122 llvm::Constant *One = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1);
Chris Lattner5083a532007-08-21 17:39:38 +0000123 llvm::Value *RealPtr = Builder.CreateGEP(Ptr, Zero, Zero, "real");
124 llvm::Value *ImagPtr = Builder.CreateGEP(Ptr, Zero, One, "imag");
Chris Lattner46d7d9f2007-08-21 17:28:34 +0000125
126 // FIXME: Handle volatility.
Chris Lattner5083a532007-08-21 17:39:38 +0000127 Builder.CreateStore(V.first, RealPtr);
128 Builder.CreateStore(V.second, ImagPtr);
Chris Lattner46d7d9f2007-08-21 17:28:34 +0000129}
130
131
132
Chris Lattnerb6ef18a2007-08-21 05:54:00 +0000133//===----------------------------------------------------------------------===//
134// Visitor Methods
135//===----------------------------------------------------------------------===//
136
137ComplexPairTy ComplexExprEmitter::VisitBinaryOperator(const BinaryOperator *E) {
Chris Lattner05ba49c2007-08-21 05:54:53 +0000138 fprintf(stderr, "Unimplemented complex binary expr!\n");
Chris Lattnerb6ef18a2007-08-21 05:54:00 +0000139 E->dump();
140 return ComplexPairTy();
Chris Lattnerb6ef18a2007-08-21 05:54:00 +0000141}
142
143ComplexPairTy ComplexExprEmitter::VisitBinAdd(const BinaryOperator *E) {
Chris Lattnerb6ef18a2007-08-21 05:54:00 +0000144 ComplexPairTy LHS = Visit(E->getLHS());
145 ComplexPairTy RHS = Visit(E->getRHS());
146
Chris Lattner5083a532007-08-21 17:39:38 +0000147 llvm::Value *ResR = Builder.CreateAdd(LHS.first, RHS.first, "add.r");
148 llvm::Value *ResI = Builder.CreateAdd(LHS.second, RHS.second, "add.i");
Chris Lattnerb6ef18a2007-08-21 05:54:00 +0000149
150 return ComplexPairTy(ResR, ResI);
151}
152
Chris Lattner2823c192007-08-21 16:34:16 +0000153ComplexPairTy ComplexExprEmitter::VisitBinMul(const BinaryOperator *E) {
154 ComplexPairTy LHS = Visit(E->getLHS());
155 ComplexPairTy RHS = Visit(E->getRHS());
156
Chris Lattner5083a532007-08-21 17:39:38 +0000157 llvm::Value *ResRl = Builder.CreateMul(LHS.first, RHS.first, "mul.rl");
158 llvm::Value *ResRr = Builder.CreateMul(LHS.second, RHS.second, "mul.rr");
159 llvm::Value *ResR = Builder.CreateSub(ResRl, ResRr, "mul.r");
Chris Lattner2823c192007-08-21 16:34:16 +0000160
Chris Lattner5083a532007-08-21 17:39:38 +0000161 llvm::Value *ResIl = Builder.CreateMul(LHS.second, RHS.first, "mul.il");
162 llvm::Value *ResIr = Builder.CreateMul(LHS.first, RHS.second, "mul.ir");
163 llvm::Value *ResI = Builder.CreateAdd(ResIl, ResIr, "mul.i");
Chris Lattner2823c192007-08-21 16:34:16 +0000164
165 return ComplexPairTy(ResR, ResI);
166}
167
Chris Lattnerb6ef18a2007-08-21 05:54:00 +0000168ComplexPairTy ComplexExprEmitter::VisitBinAssign(const BinaryOperator *E) {
169 assert(E->getLHS()->getType().getCanonicalType() ==
170 E->getRHS()->getType().getCanonicalType() && "Invalid assignment");
171 // Emit the RHS.
172 ComplexPairTy Val = Visit(E->getRHS());
173
174 // Compute the address to store into.
175 LValue LHS = CGF.EmitLValue(E->getLHS());
176
177 // Store into it.
178 // FIXME: Volatility!
Chris Lattner46d7d9f2007-08-21 17:28:34 +0000179 EmitStoreOfComplex(Val, LHS.getAddress());
Chris Lattnerb6ef18a2007-08-21 05:54:00 +0000180 return Val;
181}
182
Chris Lattner756a4d82007-08-21 17:15:50 +0000183ComplexPairTy ComplexExprEmitter::VisitBinComma(const BinaryOperator *E) {
184 CGF.EmitStmt(E->getLHS());
185 return Visit(E->getRHS());
186}
Chris Lattnerb6ef18a2007-08-21 05:54:00 +0000187
188ComplexPairTy ComplexExprEmitter::
189VisitConditionalOperator(const ConditionalOperator *E) {
190 llvm::BasicBlock *LHSBlock = new llvm::BasicBlock("cond.?");
191 llvm::BasicBlock *RHSBlock = new llvm::BasicBlock("cond.:");
192 llvm::BasicBlock *ContBlock = new llvm::BasicBlock("cond.cont");
193
194 llvm::Value *Cond = CGF.EvaluateExprAsBool(E->getCond());
Chris Lattner5083a532007-08-21 17:39:38 +0000195 Builder.CreateCondBr(Cond, LHSBlock, RHSBlock);
Chris Lattnerb6ef18a2007-08-21 05:54:00 +0000196
197 CGF.EmitBlock(LHSBlock);
198
199 // Handle the GNU extension for missing LHS.
Chris Lattner05ba49c2007-08-21 05:54:53 +0000200 assert(E->getLHS() && "Must have LHS for complex value");
Chris Lattnerb6ef18a2007-08-21 05:54:00 +0000201
202 ComplexPairTy LHS = Visit(E->getLHS());
Chris Lattner5083a532007-08-21 17:39:38 +0000203 Builder.CreateBr(ContBlock);
204 LHSBlock = Builder.GetInsertBlock();
Chris Lattnerb6ef18a2007-08-21 05:54:00 +0000205
206 CGF.EmitBlock(RHSBlock);
207
208 ComplexPairTy RHS = Visit(E->getRHS());
Chris Lattner5083a532007-08-21 17:39:38 +0000209 Builder.CreateBr(ContBlock);
210 RHSBlock = Builder.GetInsertBlock();
Chris Lattnerb6ef18a2007-08-21 05:54:00 +0000211
212 CGF.EmitBlock(ContBlock);
213
214 // Create a PHI node for the real part.
Chris Lattner5083a532007-08-21 17:39:38 +0000215 llvm::PHINode *RealPN = Builder.CreatePHI(LHS.first->getType(), "cond.r");
Chris Lattnerb6ef18a2007-08-21 05:54:00 +0000216 RealPN->reserveOperandSpace(2);
217 RealPN->addIncoming(LHS.first, LHSBlock);
218 RealPN->addIncoming(RHS.first, RHSBlock);
219
220 // Create a PHI node for the imaginary part.
Chris Lattner5083a532007-08-21 17:39:38 +0000221 llvm::PHINode *ImagPN = Builder.CreatePHI(LHS.first->getType(), "cond.i");
Chris Lattnerb6ef18a2007-08-21 05:54:00 +0000222 ImagPN->reserveOperandSpace(2);
223 ImagPN->addIncoming(LHS.second, LHSBlock);
224 ImagPN->addIncoming(RHS.second, RHSBlock);
225
226 return ComplexPairTy(RealPN, ImagPN);
227}
228
229//===----------------------------------------------------------------------===//
230// Entry Point into this File
231//===----------------------------------------------------------------------===//
232
233/// EmitComplexExpr - Emit the computation of the specified expression of
234/// complex type, ignoring the result.
Chris Lattner58dee102007-08-21 16:57:55 +0000235ComplexPairTy CodeGenFunction::EmitComplexExpr(const Expr *E) {
Chris Lattnerb6ef18a2007-08-21 05:54:00 +0000236 assert(E && E->getType()->isComplexType() &&
237 "Invalid complex expression to emit");
238
Chris Lattner58dee102007-08-21 16:57:55 +0000239 return ComplexExprEmitter(*this).Visit(const_cast<Expr*>(E));
Chris Lattnerb6ef18a2007-08-21 05:54:00 +0000240}
241