zcov: / lib/CodeGen/CGExprComplex.cpp


Files: 1 Branches Taken: 71.7% 43 / 60
Generated: 2010-02-10 01:31 Branches Executed: 96.7% 58 / 60
Line Coverage: 86.4% 298 / 345


Programs: 1 Runs 2897


       1                 : //===--- CGExprComplex.cpp - Emit LLVM Code for Complex Exprs -------------===//
       2                 : //
       3                 : //                     The LLVM Compiler Infrastructure
       4                 : //
       5                 : // This file is distributed under the University of Illinois Open Source
       6                 : // 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/ASTContext.h"
      17                 : #include "clang/AST/StmtVisitor.h"
      18                 : #include "llvm/Constants.h"
      19                 : #include "llvm/Function.h"
      20                 : #include "llvm/ADT/SmallString.h"
      21                 : using namespace clang;
      22                 : using namespace CodeGen;
      23                 : 
      24                 : //===----------------------------------------------------------------------===//
      25                 : //                        Complex Expression Emitter
      26                 : //===----------------------------------------------------------------------===//
      27                 : 
      28                 : typedef CodeGenFunction::ComplexPairTy ComplexPairTy;
      29                 : 
      30                 : namespace  {
      31                 : class ComplexExprEmitter
      32                 :   : public StmtVisitor<ComplexExprEmitter, ComplexPairTy> {
      33                 :   CodeGenFunction &CGF;
      34                 :   CGBuilderTy &Builder;
      35                 :   // True is we should ignore the value of a
      36                 :   bool IgnoreReal;
      37                 :   bool IgnoreImag;
      38                 :   // True if we should ignore the value of a=b
      39                 :   bool IgnoreRealAssign;
      40                 :   bool IgnoreImagAssign;
      41                 : public:
      42                 :   ComplexExprEmitter(CodeGenFunction &cgf, bool ir=false, bool ii=false,
      43              236:                      bool irn=false, bool iin=false)
      44                 :     : CGF(cgf), Builder(CGF.Builder), IgnoreReal(ir), IgnoreImag(ii),
      45              236:     IgnoreRealAssign(irn), IgnoreImagAssign(iin) {
      46              236:   }
      47                 : 
      48                 : 
      49                 :   //===--------------------------------------------------------------------===//
      50                 :   //                               Utilities
      51                 :   //===--------------------------------------------------------------------===//
      52                 : 
      53               95:   bool TestAndClearIgnoreReal() {
      54               95:     bool I = IgnoreReal;
      55               95:     IgnoreReal = false;
      56               95:     return I;
      57                 :   }
      58               95:   bool TestAndClearIgnoreImag() {
      59               95:     bool I = IgnoreImag;
      60               95:     IgnoreImag = false;
      61               95:     return I;
      62                 :   }
      63               94:   bool TestAndClearIgnoreRealAssign() {
      64               94:     bool I = IgnoreRealAssign;
      65               94:     IgnoreRealAssign = false;
      66               94:     return I;
      67                 :   }
      68               94:   bool TestAndClearIgnoreImagAssign() {
      69               94:     bool I = IgnoreImagAssign;
      70               94:     IgnoreImagAssign = false;
      71               94:     return I;
      72                 :   }
      73                 : 
      74                 :   /// EmitLoadOfLValue - Given an expression with complex type that represents a
      75                 :   /// value l-value, this method emits the address of the l-value, then loads
      76                 :   /// and returns the result.
      77              147:   ComplexPairTy EmitLoadOfLValue(const Expr *E) {
      78              147:     LValue LV = CGF.EmitLValue(E);
                      141: branch 1 taken
                        6: branch 2 taken
      79              147:     if (LV.isSimple())
      80              141:       return EmitLoadOfComplex(LV.getAddress(), LV.isVolatileQualified());
      81                 : 
                        2: branch 1 taken
                        4: branch 2 taken
      82                6:     if (LV.isPropertyRef())
      83                2:       return CGF.EmitObjCPropertyGet(LV.getPropertyRefExpr()).getComplexVal();
      84                 : 
                        4: branch 1 taken
                        0: branch 2 not taken
      85                4:     assert(LV.isKVCRef() && "Unknown LValue type!");
      86                4:     return CGF.EmitObjCPropertyGet(LV.getKVCRefExpr()).getComplexVal();
      87                 :   }
      88                 : 
      89                 :   /// EmitLoadOfComplex - Given a pointer to a complex value, emit code to load
      90                 :   /// the real and imaginary pieces.
      91                 :   ComplexPairTy EmitLoadOfComplex(llvm::Value *SrcPtr, bool isVolatile);
      92                 : 
      93                 :   /// EmitStoreOfComplex - Store the specified real/imag parts into the
      94                 :   /// specified value pointer.
      95                 :   void EmitStoreOfComplex(ComplexPairTy Val, llvm::Value *ResPtr, bool isVol);
      96                 : 
      97                 :   /// EmitComplexToComplexCast - Emit a cast from complex value Val to DestType.
      98                 :   ComplexPairTy EmitComplexToComplexCast(ComplexPairTy Val, QualType SrcType,
      99                 :                                          QualType DestType);
     100                 : 
     101                 :   //===--------------------------------------------------------------------===//
     102                 :   //                            Visitor Methods
     103                 :   //===--------------------------------------------------------------------===//
     104                 : 
     105                0:   ComplexPairTy VisitStmt(Stmt *S) {
     106                0:     S->dump(CGF.getContext().getSourceManager());
     107                0:     assert(0 && "Stmt can't have complex result type!");
     108                 :     return ComplexPairTy();
     109                 :   }
     110                 :   ComplexPairTy VisitExpr(Expr *S);
     111               25:   ComplexPairTy VisitParenExpr(ParenExpr *PE) { return Visit(PE->getSubExpr());}
     112                 :   ComplexPairTy VisitImaginaryLiteral(const ImaginaryLiteral *IL);
     113                 : 
     114                 :   // l-values.
     115              116:   ComplexPairTy VisitDeclRefExpr(const Expr *E) { return EmitLoadOfLValue(E); }
     116               22:   ComplexPairTy VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
     117               22:     return EmitLoadOfLValue(E);
     118                 :   }
     119                2:   ComplexPairTy VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
     120                2:     return EmitLoadOfLValue(E);
     121                 :   }
     122                 :   ComplexPairTy VisitObjCImplicitSetterGetterRefExpr(
     123                4:                                ObjCImplicitSetterGetterRefExpr *E) {
     124                4:     return EmitLoadOfLValue(E);
     125                 :   }
     126                2:   ComplexPairTy VisitObjCMessageExpr(ObjCMessageExpr *E) {
     127                2:     return CGF.EmitObjCMessageExpr(E).getComplexVal();
     128                 :   }
     129                0:   ComplexPairTy VisitArraySubscriptExpr(Expr *E) { return EmitLoadOfLValue(E); }
     130                2:   ComplexPairTy VisitMemberExpr(const Expr *E) { return EmitLoadOfLValue(E); }
     131                 : 
     132                 :   // FIXME: CompoundLiteralExpr
     133                 : 
     134                 :   ComplexPairTy EmitCast(Expr *Op, QualType DestTy);
     135               69:   ComplexPairTy VisitImplicitCastExpr(ImplicitCastExpr *E) {
     136                 :     // Unlike for scalars, we don't have to worry about function->ptr demotion
     137                 :     // here.
     138               69:     return EmitCast(E->getSubExpr(), E->getType());
     139                 :   }
     140                1:   ComplexPairTy VisitCastExpr(CastExpr *E) {
     141                1:     return EmitCast(E->getSubExpr(), E->getType());
     142                 :   }
     143                 :   ComplexPairTy VisitCallExpr(const CallExpr *E);
     144                 :   ComplexPairTy VisitStmtExpr(const StmtExpr *E);
     145                 : 
     146                 :   // Operators.
     147                 :   ComplexPairTy VisitPrePostIncDec(const UnaryOperator *E,
     148                8:                                    bool isInc, bool isPre) {
     149                8:     LValue LV = CGF.EmitLValue(E->getSubExpr());
     150                8:     return CGF.EmitComplexPrePostIncDec(E, LV, isInc, isPre);
     151                 :   }
     152                2:   ComplexPairTy VisitUnaryPostDec(const UnaryOperator *E) {
     153                2:     return VisitPrePostIncDec(E, false, false);
     154                 :   }
     155                2:   ComplexPairTy VisitUnaryPostInc(const UnaryOperator *E) {
     156                2:     return VisitPrePostIncDec(E, true, false);
     157                 :   }
     158                2:   ComplexPairTy VisitUnaryPreDec(const UnaryOperator *E) {
     159                2:     return VisitPrePostIncDec(E, false, true);
     160                 :   }
     161                2:   ComplexPairTy VisitUnaryPreInc(const UnaryOperator *E) {
     162                2:     return VisitPrePostIncDec(E, true, true);
     163                 :   }
     164                0:   ComplexPairTy VisitUnaryDeref(const Expr *E) { return EmitLoadOfLValue(E); }
     165                3:   ComplexPairTy VisitUnaryPlus     (const UnaryOperator *E) {
     166                3:     TestAndClearIgnoreReal();
     167                3:     TestAndClearIgnoreImag();
     168                3:     TestAndClearIgnoreRealAssign();
     169                3:     TestAndClearIgnoreImagAssign();
     170                3:     return Visit(E->getSubExpr());
     171                 :   }
     172                 :   ComplexPairTy VisitUnaryMinus    (const UnaryOperator *E);
     173                 :   ComplexPairTy VisitUnaryNot      (const UnaryOperator *E);
     174                 :   // LNot,Real,Imag never return complex.
     175                0:   ComplexPairTy VisitUnaryExtension(const UnaryOperator *E) {
     176                0:     return Visit(E->getSubExpr());
     177                 :   }
     178                5:   ComplexPairTy VisitCXXDefaultArgExpr(CXXDefaultArgExpr *DAE) {
     179                5:     return Visit(DAE->getExpr());
     180                 :   }
     181                0:   ComplexPairTy VisitCXXExprWithTemporaries(CXXExprWithTemporaries *E) {
     182                0:     return CGF.EmitCXXExprWithTemporaries(E).getComplexVal();
     183                 :   }
     184                2:   ComplexPairTy VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *E) {
                        2: branch 3 taken
                        0: branch 4 not taken
     185                2:     assert(E->getType()->isAnyComplexType() && "Expected complex type!");
     186                2:     QualType Elem = E->getType()->getAs<ComplexType>()->getElementType();
     187                2:     llvm::Constant *Null = llvm::Constant::getNullValue(CGF.ConvertType(Elem));
     188                2:     return ComplexPairTy(Null, Null);
     189                 :   }
     190                1:   ComplexPairTy VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) {
                        1: branch 3 taken
                        0: branch 4 not taken
     191                1:     assert(E->getType()->isAnyComplexType() && "Expected complex type!");
     192                1:     QualType Elem = E->getType()->getAs<ComplexType>()->getElementType();
     193                 :     llvm::Constant *Null =
     194                1:                        llvm::Constant::getNullValue(CGF.ConvertType(Elem));
     195                1:     return ComplexPairTy(Null, Null);
     196                 :   }
     197                 : 
     198               45:   struct BinOpInfo {
     199                 :     ComplexPairTy LHS;
     200                 :     ComplexPairTy RHS;
     201                 :     QualType Ty;  // Computation Type.
     202                 :   };
     203                 : 
     204                 :   BinOpInfo EmitBinOps(const BinaryOperator *E);
     205                 :   ComplexPairTy EmitCompoundAssign(const CompoundAssignOperator *E,
     206                 :                                    ComplexPairTy (ComplexExprEmitter::*Func)
     207                 :                                    (const BinOpInfo &));
     208                 : 
     209                 :   ComplexPairTy EmitBinAdd(const BinOpInfo &Op);
     210                 :   ComplexPairTy EmitBinSub(const BinOpInfo &Op);
     211                 :   ComplexPairTy EmitBinMul(const BinOpInfo &Op);
     212                 :   ComplexPairTy EmitBinDiv(const BinOpInfo &Op);
     213                 : 
     214                6:   ComplexPairTy VisitBinMul(const BinaryOperator *E) {
     215                6:     return EmitBinMul(EmitBinOps(E));
     216                 :   }
     217               31:   ComplexPairTy VisitBinAdd(const BinaryOperator *E) {
     218               31:     return EmitBinAdd(EmitBinOps(E));
     219                 :   }
     220                2:   ComplexPairTy VisitBinSub(const BinaryOperator *E) {
     221                2:     return EmitBinSub(EmitBinOps(E));
     222                 :   }
     223                0:   ComplexPairTy VisitBinDiv(const BinaryOperator *E) {
     224                0:     return EmitBinDiv(EmitBinOps(E));
     225                 :   }
     226                 : 
     227                 :   // Compound assignments.
     228                4:   ComplexPairTy VisitBinAddAssign(const CompoundAssignOperator *E) {
     229                4:     return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinAdd);
     230                 :   }
     231                0:   ComplexPairTy VisitBinSubAssign(const CompoundAssignOperator *E) {
     232                0:     return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinSub);
     233                 :   }
     234                0:   ComplexPairTy VisitBinMulAssign(const CompoundAssignOperator *E) {
     235                0:     return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinMul);
     236                 :   }
     237                2:   ComplexPairTy VisitBinDivAssign(const CompoundAssignOperator *E) {
     238                2:     return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinDiv);
     239                 :   }
     240                 : 
     241                 :   // GCC rejects rem/and/or/xor for integer complex.
     242                 :   // Logical and/or always return int, never complex.
     243                 : 
     244                 :   // No comparisons produce a complex result.
     245                 :   ComplexPairTy VisitBinAssign     (const BinaryOperator *E);
     246                 :   ComplexPairTy VisitBinComma      (const BinaryOperator *E);
     247                 : 
     248                 : 
     249                 :   ComplexPairTy VisitConditionalOperator(const ConditionalOperator *CO);
     250                 :   ComplexPairTy VisitChooseExpr(ChooseExpr *CE);
     251                 : 
     252                 :   ComplexPairTy VisitInitListExpr(InitListExpr *E);
     253                 : 
     254                 :   ComplexPairTy VisitVAArgExpr(VAArgExpr *E);
     255                 : };
     256                 : }  // end anonymous namespace.
     257                 : 
     258                 : //===----------------------------------------------------------------------===//
     259                 : //                                Utilities
     260                 : //===----------------------------------------------------------------------===//
     261                 : 
     262                 : /// EmitLoadOfComplex - Given an RValue reference for a complex, emit code to
     263                 : /// load the real and imaginary pieces, returning them as Real/Imag.
     264                 : ComplexPairTy ComplexExprEmitter::EmitLoadOfComplex(llvm::Value *SrcPtr,
     265              217:                                                     bool isVolatile) {
     266              217:   llvm::Value *Real=0, *Imag=0;
     267                 : 
                      156: branch 0 taken
                       61: branch 1 taken
     268              217:   if (!IgnoreReal) {
     269                 :     llvm::Value *RealP = Builder.CreateStructGEP(SrcPtr, 0,
     270              156:                                                  SrcPtr->getName() + ".realp");
     271              156:     Real = Builder.CreateLoad(RealP, isVolatile, SrcPtr->getName() + ".real");
     272                 :   }
     273                 : 
                      152: branch 0 taken
                       65: branch 1 taken
     274              217:   if (!IgnoreImag) {
     275                 :     llvm::Value *ImagP = Builder.CreateStructGEP(SrcPtr, 1,
     276              152:                                                  SrcPtr->getName() + ".imagp");
     277              152:     Imag = Builder.CreateLoad(ImagP, isVolatile, SrcPtr->getName() + ".imag");
     278                 :   }
     279              217:   return ComplexPairTy(Real, Imag);
     280                 : }
     281                 : 
     282                 : /// EmitStoreOfComplex - Store the specified real/imag parts into the
     283                 : /// specified value pointer.
     284                 : void ComplexExprEmitter::EmitStoreOfComplex(ComplexPairTy Val, llvm::Value *Ptr,
     285              111:                                             bool isVolatile) {
     286              111:   llvm::Value *RealPtr = Builder.CreateStructGEP(Ptr, 0, "real");
     287              111:   llvm::Value *ImagPtr = Builder.CreateStructGEP(Ptr, 1, "imag");
     288                 : 
     289              111:   Builder.CreateStore(Val.first, RealPtr, isVolatile);
     290              111:   Builder.CreateStore(Val.second, ImagPtr, isVolatile);
     291              111: }
     292                 : 
     293                 : 
     294                 : 
     295                 : //===----------------------------------------------------------------------===//
     296                 : //                            Visitor Methods
     297                 : //===----------------------------------------------------------------------===//
     298                 : 
     299                0: ComplexPairTy ComplexExprEmitter::VisitExpr(Expr *E) {
     300                0:   CGF.ErrorUnsupported(E, "complex expression");
     301                 :   const llvm::Type *EltTy =
     302                0:     CGF.ConvertType(E->getType()->getAs<ComplexType>()->getElementType());
     303                0:   llvm::Value *U = llvm::UndefValue::get(EltTy);
     304                0:   return ComplexPairTy(U, U);
     305                 : }
     306                 : 
     307                 : ComplexPairTy ComplexExprEmitter::
     308               19: VisitImaginaryLiteral(const ImaginaryLiteral *IL) {
     309               19:   llvm::Value *Imag = CGF.EmitScalarExpr(IL->getSubExpr());
     310                 :   return
     311               19:         ComplexPairTy(llvm::Constant::getNullValue(Imag->getType()), Imag);
     312                 : }
     313                 : 
     314                 : 
     315                7: ComplexPairTy ComplexExprEmitter::VisitCallExpr(const CallExpr *E) {
                        1: branch 3 taken
                        6: branch 4 taken
     316                7:   if (E->getCallReturnType()->isReferenceType())
     317                1:     return EmitLoadOfLValue(E);
     318                 : 
     319                6:   return CGF.EmitCallExpr(E).getComplexVal();
     320                 : }
     321                 : 
     322                0: ComplexPairTy ComplexExprEmitter::VisitStmtExpr(const StmtExpr *E) {
     323                0:   return CGF.EmitCompoundStmt(*E->getSubStmt(), true).getComplexVal();
     324                 : }
     325                 : 
     326                 : /// EmitComplexToComplexCast - Emit a cast from complex value Val to DestType.
     327                 : ComplexPairTy ComplexExprEmitter::EmitComplexToComplexCast(ComplexPairTy Val,
     328                 :                                                            QualType SrcType,
     329               60:                                                            QualType DestType) {
     330                 :   // Get the src/dest element type.
     331               60:   SrcType = SrcType->getAs<ComplexType>()->getElementType();
     332               60:   DestType = DestType->getAs<ComplexType>()->getElementType();
     333                 : 
     334                 :   // C99 6.3.1.6: When a value of complex type is converted to another
     335                 :   // complex type, both the real and imaginary parts follow the conversion
     336                 :   // rules for the corresponding real types.
     337               60:   Val.first = CGF.EmitScalarConversion(Val.first, SrcType, DestType);
     338               60:   Val.second = CGF.EmitScalarConversion(Val.second, SrcType, DestType);
     339               60:   return Val;
     340                 : }
     341                 : 
     342               76: ComplexPairTy ComplexExprEmitter::EmitCast(Expr *Op, QualType DestTy) {
     343                 :   // Two cases here: cast from (complex to complex) and (scalar to complex).
                       48: branch 3 taken
                       28: branch 4 taken
     344               76:   if (Op->getType()->isAnyComplexType())
     345               48:     return EmitComplexToComplexCast(Visit(Op), Op->getType(), DestTy);
     346                 : 
     347                 :   // C99 6.3.1.7: When a value of real type is converted to a complex type, the
     348                 :   // real part of the complex result value is determined by the rules of
     349                 :   // conversion to the corresponding real type and the imaginary part of the
     350                 :   // complex result value is a positive zero or an unsigned zero.
     351               28:   llvm::Value *Elt = CGF.EmitScalarExpr(Op);
     352                 : 
     353                 :   // Convert the input element to the element type of the complex.
     354               28:   DestTy = DestTy->getAs<ComplexType>()->getElementType();
     355               28:   Elt = CGF.EmitScalarConversion(Elt, Op->getType(), DestTy);
     356                 : 
     357                 :   // Return (realval, 0).
     358               28:   return ComplexPairTy(Elt, llvm::Constant::getNullValue(Elt->getType()));
     359                 : }
     360                 : 
     361                2: ComplexPairTy ComplexExprEmitter::VisitUnaryMinus(const UnaryOperator *E) {
     362                2:   TestAndClearIgnoreReal();
     363                2:   TestAndClearIgnoreImag();
     364                2:   TestAndClearIgnoreRealAssign();
     365                2:   TestAndClearIgnoreImagAssign();
     366                2:   ComplexPairTy Op = Visit(E->getSubExpr());
     367                 : 
     368                 :   llvm::Value *ResR, *ResI;
                        1: branch 2 taken
                        1: branch 3 taken
     369                2:   if (Op.first->getType()->isFloatingPoint()) {
     370                1:     ResR = Builder.CreateFNeg(Op.first,  "neg.r");
     371                1:     ResI = Builder.CreateFNeg(Op.second, "neg.i");
     372                 :   } else {
     373                1:     ResR = Builder.CreateNeg(Op.first,  "neg.r");
     374                1:     ResI = Builder.CreateNeg(Op.second, "neg.i");
     375                 :   }
     376                2:   return ComplexPairTy(ResR, ResI);
     377                 : }
     378                 : 
     379                2: ComplexPairTy ComplexExprEmitter::VisitUnaryNot(const UnaryOperator *E) {
     380                2:   TestAndClearIgnoreReal();
     381                2:   TestAndClearIgnoreImag();
     382                2:   TestAndClearIgnoreRealAssign();
     383                2:   TestAndClearIgnoreImagAssign();
     384                 :   // ~(a+ib) = a + i*-b
     385                2:   ComplexPairTy Op = Visit(E->getSubExpr());
     386                 :   llvm::Value *ResI;
                        1: branch 2 taken
                        1: branch 3 taken
     387                2:   if (Op.second->getType()->isFloatingPoint())
     388                1:     ResI = Builder.CreateFNeg(Op.second, "conj.i");
     389                 :   else
     390                1:     ResI = Builder.CreateNeg(Op.second, "conj.i");
     391                 : 
     392                2:   return ComplexPairTy(Op.first, ResI);
     393                 : }
     394                 : 
     395               35: ComplexPairTy ComplexExprEmitter::EmitBinAdd(const BinOpInfo &Op) {
     396                 :   llvm::Value *ResR, *ResI;
     397                 : 
                       24: branch 2 taken
                       11: branch 3 taken
     398               35:   if (Op.LHS.first->getType()->isFloatingPoint()) {
     399               24:     ResR = Builder.CreateFAdd(Op.LHS.first,  Op.RHS.first,  "add.r");
     400               24:     ResI = Builder.CreateFAdd(Op.LHS.second, Op.RHS.second, "add.i");
     401                 :   } else {
     402               11:     ResR = Builder.CreateAdd(Op.LHS.first,  Op.RHS.first,  "add.r");
     403               11:     ResI = Builder.CreateAdd(Op.LHS.second, Op.RHS.second, "add.i");
     404                 :   }
     405               35:   return ComplexPairTy(ResR, ResI);
     406                 : }
     407                 : 
     408                2: ComplexPairTy ComplexExprEmitter::EmitBinSub(const BinOpInfo &Op) {
     409                 :   llvm::Value *ResR, *ResI;
                        1: branch 2 taken
                        1: branch 3 taken
     410                2:   if (Op.LHS.first->getType()->isFloatingPoint()) {
     411                1:     ResR = Builder.CreateFSub(Op.LHS.first,  Op.RHS.first,  "sub.r");
     412                1:     ResI = Builder.CreateFSub(Op.LHS.second, Op.RHS.second, "sub.i");
     413                 :   } else {
     414                1:     ResR = Builder.CreateSub(Op.LHS.first,  Op.RHS.first,  "sub.r");
     415                1:     ResI = Builder.CreateSub(Op.LHS.second, Op.RHS.second, "sub.i");
     416                 :   }
     417                2:   return ComplexPairTy(ResR, ResI);
     418                 : }
     419                 : 
     420                 : 
     421                6: ComplexPairTy ComplexExprEmitter::EmitBinMul(const BinOpInfo &Op) {
     422                 :   using llvm::Value;
     423                 :   Value *ResR, *ResI;
     424                 : 
                        5: branch 2 taken
                        1: branch 3 taken
     425                6:   if (Op.LHS.first->getType()->isFloatingPoint()) {
     426                5:     Value *ResRl = Builder.CreateFMul(Op.LHS.first, Op.RHS.first, "mul.rl");
     427                5:     Value *ResRr = Builder.CreateFMul(Op.LHS.second, Op.RHS.second,"mul.rr");
     428                5:     ResR  = Builder.CreateFSub(ResRl, ResRr, "mul.r");
     429                 : 
     430                5:     Value *ResIl = Builder.CreateFMul(Op.LHS.second, Op.RHS.first, "mul.il");
     431                5:     Value *ResIr = Builder.CreateFMul(Op.LHS.first, Op.RHS.second, "mul.ir");
     432                5:     ResI  = Builder.CreateFAdd(ResIl, ResIr, "mul.i");
     433                 :   } else {
     434                1:     Value *ResRl = Builder.CreateMul(Op.LHS.first, Op.RHS.first, "mul.rl");
     435                1:     Value *ResRr = Builder.CreateMul(Op.LHS.second, Op.RHS.second,"mul.rr");
     436                1:     ResR  = Builder.CreateSub(ResRl, ResRr, "mul.r");
     437                 : 
     438                1:     Value *ResIl = Builder.CreateMul(Op.LHS.second, Op.RHS.first, "mul.il");
     439                1:     Value *ResIr = Builder.CreateMul(Op.LHS.first, Op.RHS.second, "mul.ir");
     440                1:     ResI  = Builder.CreateAdd(ResIl, ResIr, "mul.i");
     441                 :   }
     442                6:   return ComplexPairTy(ResR, ResI);
     443                 : }
     444                 : 
     445                2: ComplexPairTy ComplexExprEmitter::EmitBinDiv(const BinOpInfo &Op) {
     446                2:   llvm::Value *LHSr = Op.LHS.first, *LHSi = Op.LHS.second;
     447                2:   llvm::Value *RHSr = Op.RHS.first, *RHSi = Op.RHS.second;
     448                 : 
     449                 : 
     450                 :   llvm::Value *DSTr, *DSTi;
                        1: branch 2 taken
                        1: branch 3 taken
     451                2:   if (Op.LHS.first->getType()->isFloatingPoint()) {
     452                 :     // (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd))
     453                1:     llvm::Value *Tmp1 = Builder.CreateFMul(LHSr, RHSr, "tmp"); // a*c
     454                1:     llvm::Value *Tmp2 = Builder.CreateFMul(LHSi, RHSi, "tmp"); // b*d
     455                1:     llvm::Value *Tmp3 = Builder.CreateFAdd(Tmp1, Tmp2, "tmp"); // ac+bd
     456                 : 
     457                1:     llvm::Value *Tmp4 = Builder.CreateFMul(RHSr, RHSr, "tmp"); // c*c
     458                1:     llvm::Value *Tmp5 = Builder.CreateFMul(RHSi, RHSi, "tmp"); // d*d
     459                1:     llvm::Value *Tmp6 = Builder.CreateFAdd(Tmp4, Tmp5, "tmp"); // cc+dd
     460                 : 
     461                1:     llvm::Value *Tmp7 = Builder.CreateFMul(LHSi, RHSr, "tmp"); // b*c
     462                1:     llvm::Value *Tmp8 = Builder.CreateFMul(LHSr, RHSi, "tmp"); // a*d
     463                1:     llvm::Value *Tmp9 = Builder.CreateFSub(Tmp7, Tmp8, "tmp"); // bc-ad
     464                 : 
     465                1:     DSTr = Builder.CreateFDiv(Tmp3, Tmp6, "tmp");
     466                1:     DSTi = Builder.CreateFDiv(Tmp9, Tmp6, "tmp");
     467                 :   } else {
     468                 :     // (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd))
     469                1:     llvm::Value *Tmp1 = Builder.CreateMul(LHSr, RHSr, "tmp"); // a*c
     470                1:     llvm::Value *Tmp2 = Builder.CreateMul(LHSi, RHSi, "tmp"); // b*d
     471                1:     llvm::Value *Tmp3 = Builder.CreateAdd(Tmp1, Tmp2, "tmp"); // ac+bd
     472                 : 
     473                1:     llvm::Value *Tmp4 = Builder.CreateMul(RHSr, RHSr, "tmp"); // c*c
     474                1:     llvm::Value *Tmp5 = Builder.CreateMul(RHSi, RHSi, "tmp"); // d*d
     475                1:     llvm::Value *Tmp6 = Builder.CreateAdd(Tmp4, Tmp5, "tmp"); // cc+dd
     476                 : 
     477                1:     llvm::Value *Tmp7 = Builder.CreateMul(LHSi, RHSr, "tmp"); // b*c
     478                1:     llvm::Value *Tmp8 = Builder.CreateMul(LHSr, RHSi, "tmp"); // a*d
     479                1:     llvm::Value *Tmp9 = Builder.CreateSub(Tmp7, Tmp8, "tmp"); // bc-ad
     480                 : 
                        0: branch 5 not taken
                        1: branch 6 taken
     481                1:     if (Op.Ty->getAs<ComplexType>()->getElementType()->isUnsignedIntegerType()) {
     482                0:       DSTr = Builder.CreateUDiv(Tmp3, Tmp6, "tmp");
     483                0:       DSTi = Builder.CreateUDiv(Tmp9, Tmp6, "tmp");
     484                 :     } else {
     485                1:       DSTr = Builder.CreateSDiv(Tmp3, Tmp6, "tmp");
     486                1:       DSTi = Builder.CreateSDiv(Tmp9, Tmp6, "tmp");
     487                 :     }
     488                 :   }
     489                 : 
     490                2:   return ComplexPairTy(DSTr, DSTi);
     491                 : }
     492                 : 
     493                 : ComplexExprEmitter::BinOpInfo
     494               39: ComplexExprEmitter::EmitBinOps(const BinaryOperator *E) {
     495               39:   TestAndClearIgnoreReal();
     496               39:   TestAndClearIgnoreImag();
     497               39:   TestAndClearIgnoreRealAssign();
     498               39:   TestAndClearIgnoreImagAssign();
     499               39:   BinOpInfo Ops;
     500               39:   Ops.LHS = Visit(E->getLHS());
     501               39:   Ops.RHS = Visit(E->getRHS());
     502               39:   Ops.Ty = E->getType();
     503                 :   return Ops;
     504                 : }
     505                 : 
     506                 : 
     507                 : // Compound assignments.
     508                 : ComplexPairTy ComplexExprEmitter::
     509                 : EmitCompoundAssign(const CompoundAssignOperator *E,
     510                6:                    ComplexPairTy (ComplexExprEmitter::*Func)(const BinOpInfo&)){
     511                6:   TestAndClearIgnoreReal();
     512                6:   TestAndClearIgnoreImag();
     513                6:   bool ignreal = TestAndClearIgnoreRealAssign();
     514                6:   bool ignimag = TestAndClearIgnoreImagAssign();
     515                6:   QualType LHSTy = E->getLHS()->getType(), RHSTy = E->getRHS()->getType();
     516                 : 
     517                6:   BinOpInfo OpInfo;
     518                 : 
     519                 :   // Load the RHS and LHS operands.
     520                 :   // __block variables need to have the rhs evaluated first, plus this should
     521                 :   // improve codegen a little.  It is possible for the RHS to be complex or
     522                 :   // scalar.
     523                6:   OpInfo.Ty = E->getComputationResultType();
     524                6:   OpInfo.RHS = EmitCast(E->getRHS(), OpInfo.Ty);
     525                 : 
     526                6:   LValue LHSLV = CGF.EmitLValue(E->getLHS());
     527                 : 
     528                 : 
     529                 :   // We know the LHS is a complex lvalue.
     530                6:   OpInfo.LHS=EmitLoadOfComplex(LHSLV.getAddress(), LHSLV.isVolatileQualified());
     531                6:   OpInfo.LHS=EmitComplexToComplexCast(OpInfo.LHS, LHSTy, OpInfo.Ty);
     532                 : 
     533                 :   // Expand the binary operator.
                        0: branch 0 not taken
                        6: branch 1 taken
     534                6:   ComplexPairTy Result = (this->*Func)(OpInfo);
     535                 : 
     536                 :   // Truncate the result back to the LHS type.
     537                6:   Result = EmitComplexToComplexCast(Result, OpInfo.Ty, LHSTy);
     538                 : 
     539                 :   // Store the result value into the LHS lvalue.
     540                6:   EmitStoreOfComplex(Result, LHSLV.getAddress(), LHSLV.isVolatileQualified());
     541                 :   // And now return the LHS
     542                6:   IgnoreReal = ignreal;
     543                6:   IgnoreImag = ignimag;
     544                6:   IgnoreRealAssign = ignreal;
     545                6:   IgnoreImagAssign = ignimag;
     546                6:   return EmitLoadOfComplex(LHSLV.getAddress(), LHSLV.isVolatileQualified());
     547                 : }
     548                 : 
     549               37: ComplexPairTy ComplexExprEmitter::VisitBinAssign(const BinaryOperator *E) {
     550               37:   TestAndClearIgnoreReal();
     551               37:   TestAndClearIgnoreImag();
     552               37:   bool ignreal = TestAndClearIgnoreRealAssign();
     553               37:   bool ignimag = TestAndClearIgnoreImagAssign();
     554                 :   assert(CGF.getContext().getCanonicalType(E->getLHS()->getType()) ==
     555                 :          CGF.getContext().getCanonicalType(E->getRHS()->getType()) &&
                       37: branch 9 taken
                        0: branch 10 not taken
     556               37:          "Invalid assignment");
     557                 :   // Emit the RHS.
     558               37:   ComplexPairTy Val = Visit(E->getRHS());
     559                 : 
     560                 :   // Compute the address to store into.
     561               37:   LValue LHS = CGF.EmitLValue(E->getLHS());
     562                 : 
     563                 :   // Store into it, if simple.
                       33: branch 1 taken
                        4: branch 2 taken
     564               37:   if (LHS.isSimple()) {
     565               33:     EmitStoreOfComplex(Val, LHS.getAddress(), LHS.isVolatileQualified());
     566                 : 
     567                 :     // And now return the LHS
     568               33:     IgnoreReal = ignreal;
     569               33:     IgnoreImag = ignimag;
     570               33:     IgnoreRealAssign = ignreal;
     571               33:     IgnoreImagAssign = ignimag;
     572               33:     return EmitLoadOfComplex(LHS.getAddress(), LHS.isVolatileQualified());
     573                 :   }
     574                 : 
     575                 :   // Otherwise we must have a property setter (no complex vector/bitfields).
                        2: branch 1 taken
                        2: branch 2 taken
     576                4:   if (LHS.isPropertyRef())
     577                2:     CGF.EmitObjCPropertySet(LHS.getPropertyRefExpr(), RValue::getComplex(Val));
     578                 :   else
     579                2:     CGF.EmitObjCPropertySet(LHS.getKVCRefExpr(), RValue::getComplex(Val));
     580                 : 
     581                 :   // There is no reload after a store through a method, but we need to restore
     582                 :   // the Ignore* flags.
     583                4:   IgnoreReal = ignreal;
     584                4:   IgnoreImag = ignimag;
     585                4:   IgnoreRealAssign = ignreal;
     586                4:   IgnoreImagAssign = ignimag;
     587                4:   return Val;
     588                 : }
     589                 : 
     590                0: ComplexPairTy ComplexExprEmitter::VisitBinComma(const BinaryOperator *E) {
     591                0:   CGF.EmitStmt(E->getLHS());
     592                0:   CGF.EnsureInsertPoint();
     593                0:   return Visit(E->getRHS());
     594                 : }
     595                 : 
     596                 : ComplexPairTy ComplexExprEmitter::
     597                5: VisitConditionalOperator(const ConditionalOperator *E) {
                        0: branch 1 not taken
                        5: branch 2 taken
     598                5:   if (!E->getLHS()) {
     599                0:     CGF.ErrorUnsupported(E, "conditional operator with missing LHS");
     600                 :     const llvm::Type *EltTy =
     601                0:       CGF.ConvertType(E->getType()->getAs<ComplexType>()->getElementType());
     602                0:     llvm::Value *U = llvm::UndefValue::get(EltTy);
     603                0:     return ComplexPairTy(U, U);
     604                 :   }
     605                 : 
     606                5:   TestAndClearIgnoreReal();
     607                5:   TestAndClearIgnoreImag();
     608                5:   TestAndClearIgnoreRealAssign();
     609                5:   TestAndClearIgnoreImagAssign();
     610                5:   llvm::BasicBlock *LHSBlock = CGF.createBasicBlock("cond.true");
     611                5:   llvm::BasicBlock *RHSBlock = CGF.createBasicBlock("cond.false");
     612                5:   llvm::BasicBlock *ContBlock = CGF.createBasicBlock("cond.end");
     613                 : 
     614                5:   CGF.EmitBranchOnBoolExpr(E->getCond(), LHSBlock, RHSBlock);
     615                 : 
     616                5:   CGF.EmitBlock(LHSBlock);
     617                 : 
     618                 :   // Handle the GNU extension for missing LHS.
                        5: branch 1 taken
                        0: branch 2 not taken
     619                5:   assert(E->getLHS() && "Must have LHS for complex value");
     620                 : 
     621                5:   ComplexPairTy LHS = Visit(E->getLHS());
     622                5:   LHSBlock = Builder.GetInsertBlock();
     623                5:   CGF.EmitBranch(ContBlock);
     624                 : 
     625                5:   CGF.EmitBlock(RHSBlock);
     626                 : 
     627                5:   ComplexPairTy RHS = Visit(E->getRHS());
     628                5:   RHSBlock = Builder.GetInsertBlock();
     629                5:   CGF.EmitBranch(ContBlock);
     630                 : 
     631                5:   CGF.EmitBlock(ContBlock);
     632                 : 
     633                 :   // Create a PHI node for the real part.
     634                5:   llvm::PHINode *RealPN = Builder.CreatePHI(LHS.first->getType(), "cond.r");
     635                5:   RealPN->reserveOperandSpace(2);
     636                5:   RealPN->addIncoming(LHS.first, LHSBlock);
     637                5:   RealPN->addIncoming(RHS.first, RHSBlock);
     638                 : 
     639                 :   // Create a PHI node for the imaginary part.
     640                5:   llvm::PHINode *ImagPN = Builder.CreatePHI(LHS.first->getType(), "cond.i");
     641                5:   ImagPN->reserveOperandSpace(2);
     642                5:   ImagPN->addIncoming(LHS.second, LHSBlock);
     643                5:   ImagPN->addIncoming(RHS.second, RHSBlock);
     644                 : 
     645                5:   return ComplexPairTy(RealPN, ImagPN);
     646                 : }
     647                 : 
     648                0: ComplexPairTy ComplexExprEmitter::VisitChooseExpr(ChooseExpr *E) {
     649                0:   return Visit(E->getChosenSubExpr(CGF.getContext()));
     650                 : }
     651                 : 
     652                1: ComplexPairTy ComplexExprEmitter::VisitInitListExpr(InitListExpr *E) {
     653                1:     bool Ignore = TestAndClearIgnoreReal();
     654                 :     (void)Ignore;
                        0: branch 0 not taken
                        1: branch 1 taken
     655                1:     assert (Ignore == false && "init list ignored");
     656                1:     Ignore = TestAndClearIgnoreImag();
     657                 :     (void)Ignore;
                        0: branch 0 not taken
                        1: branch 1 taken
     658                1:     assert (Ignore == false && "init list ignored");
                        1: branch 1 taken
                        0: branch 2 not taken
     659                1:   if (E->getNumInits())
     660                1:     return Visit(E->getInit(0));
     661                 : 
     662                 :   // Empty init list intializes to null
     663                0:   QualType Ty = E->getType()->getAs<ComplexType>()->getElementType();
     664                0:   const llvm::Type* LTy = CGF.ConvertType(Ty);
     665                0:   llvm::Value* zeroConstant = llvm::Constant::getNullValue(LTy);
     666                0:   return ComplexPairTy(zeroConstant, zeroConstant);
     667                 : }
     668                 : 
     669                0: ComplexPairTy ComplexExprEmitter::VisitVAArgExpr(VAArgExpr *E) {
     670                0:   llvm::Value *ArgValue = CGF.EmitVAListRef(E->getSubExpr());
     671                0:   llvm::Value *ArgPtr = CGF.EmitVAArg(ArgValue, E->getType());
     672                 : 
                        0: branch 0 not taken
                        0: branch 1 not taken
     673                0:   if (!ArgPtr) {
     674                0:     CGF.ErrorUnsupported(E, "complex va_arg expression");
     675                 :     const llvm::Type *EltTy =
     676                0:       CGF.ConvertType(E->getType()->getAs<ComplexType>()->getElementType());
     677                0:     llvm::Value *U = llvm::UndefValue::get(EltTy);
     678                0:     return ComplexPairTy(U, U);
     679                 :   }
     680                 : 
     681                 :   // FIXME Volatility.
     682                0:   return EmitLoadOfComplex(ArgPtr, false);
     683                 : }
     684                 : 
     685                 : //===----------------------------------------------------------------------===//
     686                 : //                         Entry Point into this File
     687                 : //===----------------------------------------------------------------------===//
     688                 : 
     689                 : /// EmitComplexExpr - Emit the computation of the specified expression of
     690                 : /// complex type, ignoring the result.
     691                 : ComplexPairTy CodeGenFunction::EmitComplexExpr(const Expr *E, bool IgnoreReal,
     692              133:                                                bool IgnoreImag, bool IgnoreRealAssign, bool IgnoreImagAssign) {
     693                 :   assert(E && E->getType()->isAnyComplexType() &&
                      133: branch 0 taken
                        0: branch 1 not taken
                      133: branch 5 taken
                        0: branch 6 not taken
     694              133:          "Invalid complex expression to emit");
     695                 : 
     696                 :   return ComplexExprEmitter(*this, IgnoreReal, IgnoreImag, IgnoreRealAssign,
     697                 :                             IgnoreImagAssign)
     698              133:     .Visit(const_cast<Expr*>(E));
     699                 : }
     700                 : 
     701                 : /// EmitComplexExprIntoAddr - Emit the computation of the specified expression
     702                 : /// of complex type, storing into the specified Value*.
     703                 : void CodeGenFunction::EmitComplexExprIntoAddr(const Expr *E,
     704                 :                                               llvm::Value *DestAddr,
     705               36:                                               bool DestIsVolatile) {
     706                 :   assert(E && E->getType()->isAnyComplexType() &&
                       36: branch 0 taken
                        0: branch 1 not taken
                       36: branch 5 taken
                        0: branch 6 not taken
     707               36:          "Invalid complex expression to emit");
     708               36:   ComplexExprEmitter Emitter(*this);
     709               36:   ComplexPairTy Val = Emitter.Visit(const_cast<Expr*>(E));
     710               36:   Emitter.EmitStoreOfComplex(Val, DestAddr, DestIsVolatile);
     711               36: }
     712                 : 
     713                 : /// StoreComplexToAddr - Store a complex number into the specified address.
     714                 : void CodeGenFunction::StoreComplexToAddr(ComplexPairTy V,
     715                 :                                          llvm::Value *DestAddr,
     716               36:                                          bool DestIsVolatile) {
     717               36:   ComplexExprEmitter(*this).EmitStoreOfComplex(V, DestAddr, DestIsVolatile);
     718               36: }
     719                 : 
     720                 : /// LoadComplexFromAddr - Load a complex number from the specified address.
     721                 : ComplexPairTy CodeGenFunction::LoadComplexFromAddr(llvm::Value *SrcAddr,
     722               31:                                                    bool SrcIsVolatile) {
     723               31:   return ComplexExprEmitter(*this).EmitLoadOfComplex(SrcAddr, SrcIsVolatile);
     724                 : }

Generated: 2010-02-10 01:31 by zcov