2007-08-24 10:22:53 +08:00
|
|
|
//===--- CGExprComplex.cpp - Emit LLVM Code for Complex Exprs -------------===//
|
2007-08-21 13:54:00 +08:00
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
2007-12-30 03:59:25 +08:00
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
2007-08-21 13:54:00 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// This contains code to emit Expr nodes with complex types as LLVM code.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include "CodeGenFunction.h"
|
|
|
|
#include "CodeGenModule.h"
|
2008-08-11 13:00:27 +08:00
|
|
|
#include "clang/AST/ASTContext.h"
|
|
|
|
#include "clang/AST/StmtVisitor.h"
|
2014-10-20 03:13:49 +08:00
|
|
|
#include "llvm/ADT/STLExtras.h"
|
2012-12-04 17:13:33 +08:00
|
|
|
#include "llvm/ADT/SmallString.h"
|
2013-01-02 19:45:17 +08:00
|
|
|
#include "llvm/IR/Constants.h"
|
|
|
|
#include "llvm/IR/Function.h"
|
2014-10-20 03:13:49 +08:00
|
|
|
#include "llvm/IR/Instructions.h"
|
|
|
|
#include "llvm/IR/MDBuilder.h"
|
|
|
|
#include "llvm/IR/Metadata.h"
|
2013-07-17 13:57:42 +08:00
|
|
|
#include <algorithm>
|
2007-08-21 13:54:00 +08:00
|
|
|
using namespace clang;
|
|
|
|
using namespace CodeGen;
|
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
2007-08-21 13:54:53 +08:00
|
|
|
// Complex Expression Emitter
|
2007-08-21 13:54:00 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2007-08-22 00:57:55 +08:00
|
|
|
typedef CodeGenFunction::ComplexPairTy ComplexPairTy;
|
2007-08-21 13:54:00 +08:00
|
|
|
|
2013-03-08 05:37:08 +08:00
|
|
|
/// Return the complex type that we are meant to emit.
|
|
|
|
static const ComplexType *getComplexType(QualType type) {
|
|
|
|
type = type.getCanonicalType();
|
|
|
|
if (const ComplexType *comp = dyn_cast<ComplexType>(type)) {
|
|
|
|
return comp;
|
|
|
|
} else {
|
|
|
|
return cast<ComplexType>(cast<AtomicType>(type)->getValueType());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-08-21 13:54:00 +08:00
|
|
|
namespace {
|
2009-11-29 03:45:26 +08:00
|
|
|
class ComplexExprEmitter
|
2007-08-21 13:54:00 +08:00
|
|
|
: public StmtVisitor<ComplexExprEmitter, ComplexPairTy> {
|
|
|
|
CodeGenFunction &CGF;
|
2008-11-01 09:53:16 +08:00
|
|
|
CGBuilderTy &Builder;
|
2009-05-29 23:46:01 +08:00
|
|
|
bool IgnoreReal;
|
|
|
|
bool IgnoreImag;
|
2007-08-21 13:54:00 +08:00
|
|
|
public:
|
2010-11-16 18:08:07 +08:00
|
|
|
ComplexExprEmitter(CodeGenFunction &cgf, bool ir=false, bool ii=false)
|
|
|
|
: CGF(cgf), Builder(CGF.Builder), IgnoreReal(ir), IgnoreImag(ii) {
|
2007-08-21 13:54:00 +08:00
|
|
|
}
|
|
|
|
|
2009-09-09 21:00:44 +08:00
|
|
|
|
2007-08-21 13:54:00 +08:00
|
|
|
//===--------------------------------------------------------------------===//
|
|
|
|
// Utilities
|
|
|
|
//===--------------------------------------------------------------------===//
|
|
|
|
|
2009-05-29 23:46:01 +08:00
|
|
|
bool TestAndClearIgnoreReal() {
|
|
|
|
bool I = IgnoreReal;
|
|
|
|
IgnoreReal = false;
|
|
|
|
return I;
|
|
|
|
}
|
|
|
|
bool TestAndClearIgnoreImag() {
|
|
|
|
bool I = IgnoreImag;
|
|
|
|
IgnoreImag = false;
|
|
|
|
return I;
|
|
|
|
}
|
|
|
|
|
2007-08-21 13:54:00 +08:00
|
|
|
/// EmitLoadOfLValue - Given an expression with complex type that represents a
|
|
|
|
/// value l-value, this method emits the address of the l-value, then loads
|
|
|
|
/// and returns the result.
|
2007-08-22 01:28:34 +08:00
|
|
|
ComplexPairTy EmitLoadOfLValue(const Expr *E) {
|
2013-10-02 10:29:49 +08:00
|
|
|
return EmitLoadOfLValue(CGF.EmitLValue(E), E->getExprLoc());
|
2010-12-04 16:14:53 +08:00
|
|
|
}
|
|
|
|
|
2013-10-02 10:29:49 +08:00
|
|
|
ComplexPairTy EmitLoadOfLValue(LValue LV, SourceLocation Loc);
|
2010-12-04 16:14:53 +08:00
|
|
|
|
2007-08-22 01:28:34 +08:00
|
|
|
/// EmitStoreOfComplex - Store the specified real/imag parts into the
|
|
|
|
/// specified value pointer.
|
2015-01-14 15:38:27 +08:00
|
|
|
void EmitStoreOfComplex(ComplexPairTy Val, LValue LV, bool isInit);
|
2009-09-09 21:00:44 +08:00
|
|
|
|
2007-08-27 06:09:01 +08:00
|
|
|
/// EmitComplexToComplexCast - Emit a cast from complex value Val to DestType.
|
|
|
|
ComplexPairTy EmitComplexToComplexCast(ComplexPairTy Val, QualType SrcType,
|
|
|
|
QualType DestType);
|
2013-06-12 09:40:06 +08:00
|
|
|
/// EmitComplexToComplexCast - Emit a cast from scalar value Val to DestType.
|
|
|
|
ComplexPairTy EmitScalarToComplexCast(llvm::Value *Val, QualType SrcType,
|
|
|
|
QualType DestType);
|
2009-09-09 21:00:44 +08:00
|
|
|
|
2007-08-21 13:54:00 +08:00
|
|
|
//===--------------------------------------------------------------------===//
|
|
|
|
// Visitor Methods
|
|
|
|
//===--------------------------------------------------------------------===//
|
2007-08-22 02:51:13 +08:00
|
|
|
|
2010-09-21 07:50:22 +08:00
|
|
|
ComplexPairTy Visit(Expr *E) {
|
DebugInfo: Use the preferred location rather than the start location for expression line info
This causes things like assignment to refer to the '=' rather than the
LHS when attributing the store instruction, for example.
There were essentially 3 options for this:
* The beginning of an expression (this was the behavior prior to this
commit). This meant that stepping through subexpressions would bounce
around from subexpressions back to the start of the outer expression,
etc. (eg: x + y + z would go x, y, x, z, x (the repeated 'x's would be
where the actual addition occurred)).
* The end of an expression. This seems to be what GCC does /mostly/, and
certainly this for function calls. This has the advantage that
progress is always 'forwards' (never jumping backwards - except for
independent subexpressions if they're evaluated in interesting orders,
etc). "x + y + z" would go "x y z" with the additions occurring at y
and z after the respective loads.
The problem with this is that the user would still have to think
fairly hard about precedence to realize which subexpression is being
evaluated or which operator overload is being called in, say, an asan
backtrace.
* The preferred location or 'exprloc'. In this case you get sort of what
you'd expect, though it's a bit confusing in its own way due to going
'backwards'. In this case the locations would be: "x y + z +" in
lovely postfix arithmetic order. But this does mean that if the op+
were an operator overload, say, and in a backtrace, the backtrace will
point to the exact '+' that's being called, not to the end of one of
its operands.
(actually the operator overload case doesn't work yet for other reasons,
but that's being fixed - but this at least gets scalar/complex
assignments and other plain operators right)
llvm-svn: 227027
2015-01-25 09:19:10 +08:00
|
|
|
ApplyDebugLocation DL(CGF, E);
|
2011-02-18 03:02:56 +08:00
|
|
|
return StmtVisitor<ComplexExprEmitter, ComplexPairTy>::Visit(E);
|
2010-09-21 07:50:22 +08:00
|
|
|
}
|
2013-11-22 18:20:40 +08:00
|
|
|
|
2007-08-21 13:54:00 +08:00
|
|
|
ComplexPairTy VisitStmt(Stmt *S) {
|
2007-12-12 05:27:55 +08:00
|
|
|
S->dump(CGF.getContext().getSourceManager());
|
2011-09-23 13:06:16 +08:00
|
|
|
llvm_unreachable("Stmt can't have complex result type!");
|
2007-08-21 13:54:00 +08:00
|
|
|
}
|
2007-08-22 02:51:13 +08:00
|
|
|
ComplexPairTy VisitExpr(Expr *S);
|
2007-08-21 13:54:00 +08:00
|
|
|
ComplexPairTy VisitParenExpr(ParenExpr *PE) { return Visit(PE->getSubExpr());}
|
2011-04-15 08:35:48 +08:00
|
|
|
ComplexPairTy VisitGenericSelectionExpr(GenericSelectionExpr *GE) {
|
|
|
|
return Visit(GE->getResultExpr());
|
|
|
|
}
|
2007-08-26 13:57:57 +08:00
|
|
|
ComplexPairTy VisitImaginaryLiteral(const ImaginaryLiteral *IL);
|
2011-07-15 13:09:51 +08:00
|
|
|
ComplexPairTy
|
|
|
|
VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *PE) {
|
|
|
|
return Visit(PE->getReplacement());
|
|
|
|
}
|
2009-09-09 21:00:44 +08:00
|
|
|
|
2007-08-21 13:54:00 +08:00
|
|
|
// l-values.
|
2012-03-10 17:33:50 +08:00
|
|
|
ComplexPairTy VisitDeclRefExpr(DeclRefExpr *E) {
|
|
|
|
if (CodeGenFunction::ConstantEmission result = CGF.tryEmitAsConstant(E)) {
|
2012-03-10 11:05:10 +08:00
|
|
|
if (result.isReference())
|
2013-10-02 10:29:49 +08:00
|
|
|
return EmitLoadOfLValue(result.getReferenceLValue(CGF, E),
|
|
|
|
E->getExprLoc());
|
2012-03-10 11:05:10 +08:00
|
|
|
|
2013-07-17 04:19:04 +08:00
|
|
|
llvm::Constant *pair = result.getValue();
|
|
|
|
return ComplexPairTy(pair->getAggregateElement(0U),
|
|
|
|
pair->getAggregateElement(1U));
|
2012-03-10 11:05:10 +08:00
|
|
|
}
|
2012-03-10 17:33:50 +08:00
|
|
|
return EmitLoadOfLValue(E);
|
2012-03-10 11:05:10 +08:00
|
|
|
}
|
2009-09-09 21:00:44 +08:00
|
|
|
ComplexPairTy VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
|
2009-06-10 12:38:50 +08:00
|
|
|
return EmitLoadOfLValue(E);
|
|
|
|
}
|
|
|
|
ComplexPairTy VisitObjCMessageExpr(ObjCMessageExpr *E) {
|
|
|
|
return CGF.EmitObjCMessageExpr(E).getComplexVal();
|
|
|
|
}
|
2007-08-22 02:03:58 +08:00
|
|
|
ComplexPairTy VisitArraySubscriptExpr(Expr *E) { return EmitLoadOfLValue(E); }
|
2007-08-26 13:57:57 +08:00
|
|
|
ComplexPairTy VisitMemberExpr(const Expr *E) { return EmitLoadOfLValue(E); }
|
2011-02-16 16:02:54 +08:00
|
|
|
ComplexPairTy VisitOpaqueValueExpr(OpaqueValueExpr *E) {
|
2011-02-17 18:25:35 +08:00
|
|
|
if (E->isGLValue())
|
2013-10-02 10:29:49 +08:00
|
|
|
return EmitLoadOfLValue(CGF.getOpaqueLValueMapping(E), E->getExprLoc());
|
2011-02-17 18:25:35 +08:00
|
|
|
return CGF.getOpaqueRValueMapping(E).getComplexVal();
|
2011-02-16 16:02:54 +08:00
|
|
|
}
|
2007-08-21 13:54:00 +08:00
|
|
|
|
2011-11-06 17:01:30 +08:00
|
|
|
ComplexPairTy VisitPseudoObjectExpr(PseudoObjectExpr *E) {
|
|
|
|
return CGF.EmitPseudoObjectRValue(E).getComplexVal();
|
|
|
|
}
|
|
|
|
|
2007-08-22 06:33:41 +08:00
|
|
|
// FIXME: CompoundLiteralExpr
|
2009-09-09 21:00:44 +08:00
|
|
|
|
2014-10-31 14:57:10 +08:00
|
|
|
ComplexPairTy EmitCast(CastKind CK, Expr *Op, QualType DestTy);
|
2007-08-26 13:57:57 +08:00
|
|
|
ComplexPairTy VisitImplicitCastExpr(ImplicitCastExpr *E) {
|
|
|
|
// Unlike for scalars, we don't have to worry about function->ptr demotion
|
|
|
|
// here.
|
2010-07-15 05:35:45 +08:00
|
|
|
return EmitCast(E->getCastKind(), E->getSubExpr(), E->getType());
|
2007-08-26 13:57:57 +08:00
|
|
|
}
|
|
|
|
ComplexPairTy VisitCastExpr(CastExpr *E) {
|
2010-07-15 05:35:45 +08:00
|
|
|
return EmitCast(E->getCastKind(), E->getSubExpr(), E->getType());
|
2007-08-26 13:57:57 +08:00
|
|
|
}
|
2007-08-24 05:38:16 +08:00
|
|
|
ComplexPairTy VisitCallExpr(const CallExpr *E);
|
2007-09-01 06:51:38 +08:00
|
|
|
ComplexPairTy VisitStmtExpr(const StmtExpr *E);
|
|
|
|
|
2007-08-21 13:54:00 +08:00
|
|
|
// Operators.
|
2007-08-22 06:25:29 +08:00
|
|
|
ComplexPairTy VisitPrePostIncDec(const UnaryOperator *E,
|
2010-01-10 05:40:03 +08:00
|
|
|
bool isInc, bool isPre) {
|
|
|
|
LValue LV = CGF.EmitLValue(E->getSubExpr());
|
|
|
|
return CGF.EmitComplexPrePostIncDec(E, LV, isInc, isPre);
|
|
|
|
}
|
2007-08-22 06:25:29 +08:00
|
|
|
ComplexPairTy VisitUnaryPostDec(const UnaryOperator *E) {
|
|
|
|
return VisitPrePostIncDec(E, false, false);
|
|
|
|
}
|
|
|
|
ComplexPairTy VisitUnaryPostInc(const UnaryOperator *E) {
|
|
|
|
return VisitPrePostIncDec(E, true, false);
|
|
|
|
}
|
|
|
|
ComplexPairTy VisitUnaryPreDec(const UnaryOperator *E) {
|
|
|
|
return VisitPrePostIncDec(E, false, true);
|
|
|
|
}
|
|
|
|
ComplexPairTy VisitUnaryPreInc(const UnaryOperator *E) {
|
|
|
|
return VisitPrePostIncDec(E, true, true);
|
|
|
|
}
|
|
|
|
ComplexPairTy VisitUnaryDeref(const Expr *E) { return EmitLoadOfLValue(E); }
|
2007-08-22 04:08:23 +08:00
|
|
|
ComplexPairTy VisitUnaryPlus (const UnaryOperator *E) {
|
2009-05-29 23:46:01 +08:00
|
|
|
TestAndClearIgnoreReal();
|
|
|
|
TestAndClearIgnoreImag();
|
2007-08-22 04:08:23 +08:00
|
|
|
return Visit(E->getSubExpr());
|
|
|
|
}
|
|
|
|
ComplexPairTy VisitUnaryMinus (const UnaryOperator *E);
|
2007-08-22 04:41:44 +08:00
|
|
|
ComplexPairTy VisitUnaryNot (const UnaryOperator *E);
|
2008-11-12 01:56:53 +08:00
|
|
|
// LNot,Real,Imag never return complex.
|
2007-08-22 04:41:44 +08:00
|
|
|
ComplexPairTy VisitUnaryExtension(const UnaryOperator *E) {
|
|
|
|
return Visit(E->getSubExpr());
|
|
|
|
}
|
2008-04-08 12:40:51 +08:00
|
|
|
ComplexPairTy VisitCXXDefaultArgExpr(CXXDefaultArgExpr *DAE) {
|
|
|
|
return Visit(DAE->getExpr());
|
|
|
|
}
|
2013-04-21 06:23:05 +08:00
|
|
|
ComplexPairTy VisitCXXDefaultInitExpr(CXXDefaultInitExpr *DIE) {
|
|
|
|
CodeGenFunction::CXXDefaultInitExprScope Scope(CGF);
|
|
|
|
return Visit(DIE->getExpr());
|
|
|
|
}
|
2010-12-06 16:20:24 +08:00
|
|
|
ComplexPairTy VisitExprWithCleanups(ExprWithCleanups *E) {
|
2011-11-10 16:15:53 +08:00
|
|
|
CGF.enterFullExpression(E);
|
|
|
|
CodeGenFunction::RunCleanupsScope Scope(CGF);
|
|
|
|
return Visit(E->getSubExpr());
|
2009-05-31 08:12:05 +08:00
|
|
|
}
|
2010-07-08 14:14:04 +08:00
|
|
|
ComplexPairTy VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {
|
2008-08-24 03:35:47 +08:00
|
|
|
assert(E->getType()->isAnyComplexType() && "Expected complex type!");
|
2013-03-08 05:37:08 +08:00
|
|
|
QualType Elem = E->getType()->castAs<ComplexType>()->getElementType();
|
2009-09-09 21:00:44 +08:00
|
|
|
llvm::Constant *Null = llvm::Constant::getNullValue(CGF.ConvertType(Elem));
|
2008-08-24 03:35:47 +08:00
|
|
|
return ComplexPairTy(Null, Null);
|
|
|
|
}
|
2009-01-30 01:44:32 +08:00
|
|
|
ComplexPairTy VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) {
|
|
|
|
assert(E->getType()->isAnyComplexType() && "Expected complex type!");
|
2013-03-08 05:37:08 +08:00
|
|
|
QualType Elem = E->getType()->castAs<ComplexType>()->getElementType();
|
2009-09-09 21:00:44 +08:00
|
|
|
llvm::Constant *Null =
|
2009-08-01 04:28:54 +08:00
|
|
|
llvm::Constant::getNullValue(CGF.ConvertType(Elem));
|
2009-01-30 01:44:32 +08:00
|
|
|
return ComplexPairTy(Null, Null);
|
|
|
|
}
|
2009-09-09 21:00:44 +08:00
|
|
|
|
2007-08-27 06:09:01 +08:00
|
|
|
struct BinOpInfo {
|
|
|
|
ComplexPairTy LHS;
|
|
|
|
ComplexPairTy RHS;
|
|
|
|
QualType Ty; // Computation Type.
|
2009-09-09 21:00:44 +08:00
|
|
|
};
|
|
|
|
|
2007-08-27 06:09:01 +08:00
|
|
|
BinOpInfo EmitBinOps(const BinaryOperator *E);
|
2010-11-16 18:08:07 +08:00
|
|
|
LValue EmitCompoundAssignLValue(const CompoundAssignOperator *E,
|
|
|
|
ComplexPairTy (ComplexExprEmitter::*Func)
|
|
|
|
(const BinOpInfo &),
|
2013-06-12 09:40:06 +08:00
|
|
|
RValue &Val);
|
2007-08-27 06:09:01 +08:00
|
|
|
ComplexPairTy EmitCompoundAssign(const CompoundAssignOperator *E,
|
|
|
|
ComplexPairTy (ComplexExprEmitter::*Func)
|
|
|
|
(const BinOpInfo &));
|
|
|
|
|
|
|
|
ComplexPairTy EmitBinAdd(const BinOpInfo &Op);
|
|
|
|
ComplexPairTy EmitBinSub(const BinOpInfo &Op);
|
|
|
|
ComplexPairTy EmitBinMul(const BinOpInfo &Op);
|
|
|
|
ComplexPairTy EmitBinDiv(const BinOpInfo &Op);
|
2009-09-09 21:00:44 +08:00
|
|
|
|
2014-10-11 08:57:18 +08:00
|
|
|
ComplexPairTy EmitComplexBinOpLibCall(StringRef LibCallName,
|
|
|
|
const BinOpInfo &Op);
|
|
|
|
|
2007-08-27 06:09:01 +08:00
|
|
|
ComplexPairTy VisitBinAdd(const BinaryOperator *E) {
|
|
|
|
return EmitBinAdd(EmitBinOps(E));
|
|
|
|
}
|
|
|
|
ComplexPairTy VisitBinSub(const BinaryOperator *E) {
|
|
|
|
return EmitBinSub(EmitBinOps(E));
|
|
|
|
}
|
2010-11-16 18:08:07 +08:00
|
|
|
ComplexPairTy VisitBinMul(const BinaryOperator *E) {
|
|
|
|
return EmitBinMul(EmitBinOps(E));
|
|
|
|
}
|
2007-08-27 06:09:01 +08:00
|
|
|
ComplexPairTy VisitBinDiv(const BinaryOperator *E) {
|
|
|
|
return EmitBinDiv(EmitBinOps(E));
|
|
|
|
}
|
2009-09-09 21:00:44 +08:00
|
|
|
|
2007-08-27 06:09:01 +08:00
|
|
|
// Compound assignments.
|
|
|
|
ComplexPairTy VisitBinAddAssign(const CompoundAssignOperator *E) {
|
|
|
|
return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinAdd);
|
|
|
|
}
|
|
|
|
ComplexPairTy VisitBinSubAssign(const CompoundAssignOperator *E) {
|
|
|
|
return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinSub);
|
|
|
|
}
|
|
|
|
ComplexPairTy VisitBinMulAssign(const CompoundAssignOperator *E) {
|
|
|
|
return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinMul);
|
|
|
|
}
|
|
|
|
ComplexPairTy VisitBinDivAssign(const CompoundAssignOperator *E) {
|
|
|
|
return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinDiv);
|
|
|
|
}
|
2009-09-09 21:00:44 +08:00
|
|
|
|
2007-08-27 05:27:07 +08:00
|
|
|
// GCC rejects rem/and/or/xor for integer complex.
|
2007-08-22 01:12:50 +08:00
|
|
|
// Logical and/or always return int, never complex.
|
2007-08-22 00:57:55 +08:00
|
|
|
|
|
|
|
// No comparisons produce a complex result.
|
2010-11-16 18:08:07 +08:00
|
|
|
|
|
|
|
LValue EmitBinAssignLValue(const BinaryOperator *E,
|
|
|
|
ComplexPairTy &Val);
|
2007-08-21 13:54:00 +08:00
|
|
|
ComplexPairTy VisitBinAssign (const BinaryOperator *E);
|
2007-08-22 01:15:50 +08:00
|
|
|
ComplexPairTy VisitBinComma (const BinaryOperator *E);
|
|
|
|
|
2009-09-09 21:00:44 +08:00
|
|
|
|
2011-02-17 18:25:35 +08:00
|
|
|
ComplexPairTy
|
|
|
|
VisitAbstractConditionalOperator(const AbstractConditionalOperator *CO);
|
2007-08-24 10:18:47 +08:00
|
|
|
ComplexPairTy VisitChooseExpr(ChooseExpr *CE);
|
2008-05-14 07:11:35 +08:00
|
|
|
|
|
|
|
ComplexPairTy VisitInitListExpr(InitListExpr *E);
|
2009-02-10 11:03:30 +08:00
|
|
|
|
2012-02-28 04:26:13 +08:00
|
|
|
ComplexPairTy VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
|
|
|
|
return EmitLoadOfLValue(E);
|
|
|
|
}
|
|
|
|
|
2009-02-10 11:03:30 +08:00
|
|
|
ComplexPairTy VisitVAArgExpr(VAArgExpr *E);
|
2011-10-11 10:20:01 +08:00
|
|
|
|
|
|
|
ComplexPairTy VisitAtomicExpr(AtomicExpr *E) {
|
|
|
|
return CGF.EmitAtomicExpr(E).getComplexVal();
|
|
|
|
}
|
2007-08-21 13:54:00 +08:00
|
|
|
};
|
|
|
|
} // end anonymous namespace.
|
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Utilities
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2013-03-08 05:37:08 +08:00
|
|
|
/// EmitLoadOfLValue - Given an RValue reference for a complex, emit code to
|
2007-08-22 01:28:34 +08:00
|
|
|
/// load the real and imaginary pieces, returning them as Real/Imag.
|
2013-10-02 10:29:49 +08:00
|
|
|
ComplexPairTy ComplexExprEmitter::EmitLoadOfLValue(LValue lvalue,
|
|
|
|
SourceLocation loc) {
|
2013-03-08 05:37:08 +08:00
|
|
|
assert(lvalue.isSimple() && "non-simple complex l-value?");
|
2013-03-08 05:37:17 +08:00
|
|
|
if (lvalue.getType()->isAtomicType())
|
2013-10-02 10:29:49 +08:00
|
|
|
return CGF.EmitAtomicLoad(lvalue, loc).getComplexVal();
|
2013-03-08 05:37:17 +08:00
|
|
|
|
2013-03-08 05:37:08 +08:00
|
|
|
llvm::Value *SrcPtr = lvalue.getAddress();
|
|
|
|
bool isVolatile = lvalue.isVolatileQualified();
|
2013-07-17 13:57:42 +08:00
|
|
|
unsigned AlignR = lvalue.getAlignment().getQuantity();
|
|
|
|
ASTContext &C = CGF.getContext();
|
|
|
|
QualType ComplexTy = lvalue.getType();
|
|
|
|
unsigned ComplexAlign = C.getTypeAlignInChars(ComplexTy).getQuantity();
|
|
|
|
unsigned AlignI = std::min(AlignR, ComplexAlign);
|
2013-03-08 05:37:08 +08:00
|
|
|
|
2014-05-21 13:09:00 +08:00
|
|
|
llvm::Value *Real=nullptr, *Imag=nullptr;
|
2007-08-27 06:47:40 +08:00
|
|
|
|
2010-11-14 17:40:28 +08:00
|
|
|
if (!IgnoreReal || isVolatile) {
|
2009-11-30 03:51:45 +08:00
|
|
|
llvm::Value *RealP = Builder.CreateStructGEP(SrcPtr, 0,
|
|
|
|
SrcPtr->getName() + ".realp");
|
2013-07-17 13:57:42 +08:00
|
|
|
Real = Builder.CreateAlignedLoad(RealP, AlignR, isVolatile,
|
|
|
|
SrcPtr->getName() + ".real");
|
2009-05-29 23:46:01 +08:00
|
|
|
}
|
2009-09-09 21:00:44 +08:00
|
|
|
|
2010-11-14 17:40:28 +08:00
|
|
|
if (!IgnoreImag || isVolatile) {
|
2009-11-30 03:51:45 +08:00
|
|
|
llvm::Value *ImagP = Builder.CreateStructGEP(SrcPtr, 1,
|
|
|
|
SrcPtr->getName() + ".imagp");
|
2013-07-17 13:57:42 +08:00
|
|
|
Imag = Builder.CreateAlignedLoad(ImagP, AlignI, isVolatile,
|
|
|
|
SrcPtr->getName() + ".imag");
|
2009-05-29 23:46:01 +08:00
|
|
|
}
|
2007-08-21 13:54:00 +08:00
|
|
|
return ComplexPairTy(Real, Imag);
|
|
|
|
}
|
|
|
|
|
2007-08-22 01:28:34 +08:00
|
|
|
/// EmitStoreOfComplex - Store the specified real/imag parts into the
|
|
|
|
/// specified value pointer.
|
2014-12-10 04:52:24 +08:00
|
|
|
void ComplexExprEmitter::EmitStoreOfComplex(ComplexPairTy Val, LValue lvalue,
|
2015-01-14 15:38:27 +08:00
|
|
|
bool isInit) {
|
2015-02-14 00:27:00 +08:00
|
|
|
if (lvalue.getType()->isAtomicType())
|
2013-03-08 05:37:17 +08:00
|
|
|
return CGF.EmitAtomicStore(RValue::getComplex(Val), lvalue, isInit);
|
|
|
|
|
2013-03-08 05:37:08 +08:00
|
|
|
llvm::Value *Ptr = lvalue.getAddress();
|
2008-03-19 13:19:41 +08:00
|
|
|
llvm::Value *RealPtr = Builder.CreateStructGEP(Ptr, 0, "real");
|
|
|
|
llvm::Value *ImagPtr = Builder.CreateStructGEP(Ptr, 1, "imag");
|
2013-07-17 13:57:42 +08:00
|
|
|
unsigned AlignR = lvalue.getAlignment().getQuantity();
|
|
|
|
ASTContext &C = CGF.getContext();
|
|
|
|
QualType ComplexTy = lvalue.getType();
|
|
|
|
unsigned ComplexAlign = C.getTypeAlignInChars(ComplexTy).getQuantity();
|
|
|
|
unsigned AlignI = std::min(AlignR, ComplexAlign);
|
|
|
|
|
|
|
|
Builder.CreateAlignedStore(Val.first, RealPtr, AlignR,
|
|
|
|
lvalue.isVolatileQualified());
|
|
|
|
Builder.CreateAlignedStore(Val.second, ImagPtr, AlignI,
|
|
|
|
lvalue.isVolatileQualified());
|
2007-08-22 01:28:34 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2007-08-21 13:54:00 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Visitor Methods
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2007-08-22 02:51:13 +08:00
|
|
|
ComplexPairTy ComplexExprEmitter::VisitExpr(Expr *E) {
|
2011-09-03 04:03:16 +08:00
|
|
|
CGF.ErrorUnsupported(E, "complex expression");
|
|
|
|
llvm::Type *EltTy =
|
2013-03-08 05:37:08 +08:00
|
|
|
CGF.ConvertType(getComplexType(E->getType())->getElementType());
|
2011-09-03 04:03:16 +08:00
|
|
|
llvm::Value *U = llvm::UndefValue::get(EltTy);
|
|
|
|
return ComplexPairTy(U, U);
|
2007-08-21 13:54:00 +08:00
|
|
|
}
|
|
|
|
|
2007-08-26 13:57:57 +08:00
|
|
|
ComplexPairTy ComplexExprEmitter::
|
|
|
|
VisitImaginaryLiteral(const ImaginaryLiteral *IL) {
|
2007-08-26 11:51:12 +08:00
|
|
|
llvm::Value *Imag = CGF.EmitScalarExpr(IL->getSubExpr());
|
2011-01-13 10:03:06 +08:00
|
|
|
return ComplexPairTy(llvm::Constant::getNullValue(Imag->getType()), Imag);
|
2007-08-26 11:51:12 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-08-24 05:38:16 +08:00
|
|
|
ComplexPairTy ComplexExprEmitter::VisitCallExpr(const CallExpr *E) {
|
2009-05-27 11:37:57 +08:00
|
|
|
if (E->getCallReturnType()->isReferenceType())
|
|
|
|
return EmitLoadOfLValue(E);
|
|
|
|
|
2007-09-01 06:49:20 +08:00
|
|
|
return CGF.EmitCallExpr(E).getComplexVal();
|
2008-01-31 04:50:20 +08:00
|
|
|
}
|
|
|
|
|
2007-09-01 06:51:38 +08:00
|
|
|
ComplexPairTy ComplexExprEmitter::VisitStmtExpr(const StmtExpr *E) {
|
2011-01-26 12:00:11 +08:00
|
|
|
CodeGenFunction::StmtExprEvaluation eval(CGF);
|
2013-06-11 06:04:49 +08:00
|
|
|
llvm::Value *RetAlloca = CGF.EmitCompoundStmt(*E->getSubStmt(), true);
|
|
|
|
assert(RetAlloca && "Expected complex return value");
|
2013-10-02 10:29:49 +08:00
|
|
|
return EmitLoadOfLValue(CGF.MakeAddrLValue(RetAlloca, E->getType()),
|
|
|
|
E->getExprLoc());
|
2007-09-01 06:51:38 +08:00
|
|
|
}
|
|
|
|
|
2007-08-27 06:09:01 +08:00
|
|
|
/// EmitComplexToComplexCast - Emit a cast from complex value Val to DestType.
|
|
|
|
ComplexPairTy ComplexExprEmitter::EmitComplexToComplexCast(ComplexPairTy Val,
|
|
|
|
QualType SrcType,
|
|
|
|
QualType DestType) {
|
|
|
|
// Get the src/dest element type.
|
2013-03-08 05:37:08 +08:00
|
|
|
SrcType = SrcType->castAs<ComplexType>()->getElementType();
|
|
|
|
DestType = DestType->castAs<ComplexType>()->getElementType();
|
2007-08-27 06:09:01 +08:00
|
|
|
|
2009-01-29 14:44:03 +08:00
|
|
|
// C99 6.3.1.6: When a value of complex type is converted to another
|
2009-01-27 02:02:34 +08:00
|
|
|
// complex type, both the real and imaginary parts follow the conversion
|
2007-08-27 06:09:01 +08:00
|
|
|
// rules for the corresponding real types.
|
|
|
|
Val.first = CGF.EmitScalarConversion(Val.first, SrcType, DestType);
|
|
|
|
Val.second = CGF.EmitScalarConversion(Val.second, SrcType, DestType);
|
|
|
|
return Val;
|
|
|
|
}
|
2007-08-26 13:57:57 +08:00
|
|
|
|
2013-06-12 09:40:06 +08:00
|
|
|
ComplexPairTy ComplexExprEmitter::EmitScalarToComplexCast(llvm::Value *Val,
|
|
|
|
QualType SrcType,
|
|
|
|
QualType DestType) {
|
|
|
|
// Convert the input element to the element type of the complex.
|
|
|
|
DestType = DestType->castAs<ComplexType>()->getElementType();
|
|
|
|
Val = CGF.EmitScalarConversion(Val, SrcType, DestType);
|
|
|
|
|
|
|
|
// Return (realval, 0).
|
|
|
|
return ComplexPairTy(Val, llvm::Constant::getNullValue(Val->getType()));
|
|
|
|
}
|
|
|
|
|
2014-10-31 14:57:10 +08:00
|
|
|
ComplexPairTy ComplexExprEmitter::EmitCast(CastKind CK, Expr *Op,
|
2010-07-15 05:35:45 +08:00
|
|
|
QualType DestTy) {
|
2010-12-04 11:47:34 +08:00
|
|
|
switch (CK) {
|
2011-06-25 10:58:47 +08:00
|
|
|
case CK_Dependent: llvm_unreachable("dependent cast kind in IR gen!");
|
2010-12-04 11:47:34 +08:00
|
|
|
|
2012-01-17 01:27:18 +08:00
|
|
|
// Atomic to non-atomic casts may be more than a no-op for some platforms and
|
|
|
|
// for some types.
|
|
|
|
case CK_AtomicToNonAtomic:
|
|
|
|
case CK_NonAtomicToAtomic:
|
2010-12-04 11:47:34 +08:00
|
|
|
case CK_NoOp:
|
|
|
|
case CK_LValueToRValue:
|
2011-06-25 10:58:47 +08:00
|
|
|
case CK_UserDefinedConversion:
|
2010-12-04 11:47:34 +08:00
|
|
|
return Visit(Op);
|
|
|
|
|
2011-06-25 10:58:47 +08:00
|
|
|
case CK_LValueBitCast: {
|
2013-03-08 05:37:08 +08:00
|
|
|
LValue origLV = CGF.EmitLValue(Op);
|
|
|
|
llvm::Value *V = origLV.getAddress();
|
2013-11-22 18:20:40 +08:00
|
|
|
V = Builder.CreateBitCast(V,
|
2011-06-25 10:58:47 +08:00
|
|
|
CGF.ConvertType(CGF.getContext().getPointerType(DestTy)));
|
2013-03-08 05:37:08 +08:00
|
|
|
return EmitLoadOfLValue(CGF.MakeAddrLValue(V, DestTy,
|
2013-10-02 10:29:49 +08:00
|
|
|
origLV.getAlignment()),
|
|
|
|
Op->getExprLoc());
|
2010-07-15 05:35:45 +08:00
|
|
|
}
|
2007-08-26 13:57:57 +08:00
|
|
|
|
2011-06-25 10:58:47 +08:00
|
|
|
case CK_BitCast:
|
|
|
|
case CK_BaseToDerived:
|
|
|
|
case CK_DerivedToBase:
|
|
|
|
case CK_UncheckedDerivedToBase:
|
|
|
|
case CK_Dynamic:
|
|
|
|
case CK_ToUnion:
|
|
|
|
case CK_ArrayToPointerDecay:
|
|
|
|
case CK_FunctionToPointerDecay:
|
|
|
|
case CK_NullToPointer:
|
|
|
|
case CK_NullToMemberPointer:
|
|
|
|
case CK_BaseToDerivedMemberPointer:
|
|
|
|
case CK_DerivedToBaseMemberPointer:
|
|
|
|
case CK_MemberPointerToBoolean:
|
2012-02-15 09:22:51 +08:00
|
|
|
case CK_ReinterpretMemberPointer:
|
2011-06-25 10:58:47 +08:00
|
|
|
case CK_ConstructorConversion:
|
|
|
|
case CK_IntegralToPointer:
|
|
|
|
case CK_PointerToIntegral:
|
|
|
|
case CK_PointerToBoolean:
|
|
|
|
case CK_ToVoid:
|
|
|
|
case CK_VectorSplat:
|
|
|
|
case CK_IntegralCast:
|
|
|
|
case CK_IntegralToBoolean:
|
|
|
|
case CK_IntegralToFloating:
|
|
|
|
case CK_FloatingToIntegral:
|
|
|
|
case CK_FloatingToBoolean:
|
|
|
|
case CK_FloatingCast:
|
2011-09-09 13:25:32 +08:00
|
|
|
case CK_CPointerToObjCPointerCast:
|
|
|
|
case CK_BlockPointerToObjCPointerCast:
|
2011-06-25 10:58:47 +08:00
|
|
|
case CK_AnyPointerToBlockPointerCast:
|
|
|
|
case CK_ObjCObjectLValueCast:
|
|
|
|
case CK_FloatingComplexToReal:
|
|
|
|
case CK_FloatingComplexToBoolean:
|
|
|
|
case CK_IntegralComplexToReal:
|
|
|
|
case CK_IntegralComplexToBoolean:
|
2011-09-10 14:18:15 +08:00
|
|
|
case CK_ARCProduceObject:
|
|
|
|
case CK_ARCConsumeObject:
|
|
|
|
case CK_ARCReclaimReturnedObject:
|
|
|
|
case CK_ARCExtendBlockObject:
|
2012-02-22 13:02:47 +08:00
|
|
|
case CK_CopyAndAutoreleaseBlockObject:
|
2012-08-31 08:14:07 +08:00
|
|
|
case CK_BuiltinFnToFnPtr:
|
2013-01-20 20:31:11 +08:00
|
|
|
case CK_ZeroToOCLEvent:
|
2013-12-11 21:39:46 +08:00
|
|
|
case CK_AddressSpaceConversion:
|
2011-06-25 10:58:47 +08:00
|
|
|
llvm_unreachable("invalid cast kind for complex value");
|
|
|
|
|
|
|
|
case CK_FloatingRealToComplex:
|
2013-06-12 09:40:06 +08:00
|
|
|
case CK_IntegralRealToComplex:
|
|
|
|
return EmitScalarToComplexCast(CGF.EmitScalarExpr(Op),
|
|
|
|
Op->getType(), DestTy);
|
2011-06-25 10:58:47 +08:00
|
|
|
|
|
|
|
case CK_FloatingComplexCast:
|
|
|
|
case CK_FloatingComplexToIntegralComplex:
|
|
|
|
case CK_IntegralComplexCast:
|
|
|
|
case CK_IntegralComplexToFloatingComplex:
|
|
|
|
return EmitComplexToComplexCast(Visit(Op), Op->getType(), DestTy);
|
|
|
|
}
|
2009-09-09 21:00:44 +08:00
|
|
|
|
2011-06-25 10:58:47 +08:00
|
|
|
llvm_unreachable("unknown cast resulting in complex value");
|
2007-08-26 13:57:57 +08:00
|
|
|
}
|
|
|
|
|
2007-08-22 04:08:23 +08:00
|
|
|
ComplexPairTy ComplexExprEmitter::VisitUnaryMinus(const UnaryOperator *E) {
|
2009-05-29 23:46:01 +08:00
|
|
|
TestAndClearIgnoreReal();
|
|
|
|
TestAndClearIgnoreImag();
|
2007-08-22 04:08:23 +08:00
|
|
|
ComplexPairTy Op = Visit(E->getSubExpr());
|
2009-09-09 21:00:44 +08:00
|
|
|
|
2009-06-17 14:36:24 +08:00
|
|
|
llvm::Value *ResR, *ResI;
|
2010-02-16 00:14:01 +08:00
|
|
|
if (Op.first->getType()->isFloatingPointTy()) {
|
2009-06-17 14:36:24 +08:00
|
|
|
ResR = Builder.CreateFNeg(Op.first, "neg.r");
|
|
|
|
ResI = Builder.CreateFNeg(Op.second, "neg.i");
|
|
|
|
} else {
|
|
|
|
ResR = Builder.CreateNeg(Op.first, "neg.r");
|
|
|
|
ResI = Builder.CreateNeg(Op.second, "neg.i");
|
|
|
|
}
|
2007-08-22 04:08:23 +08:00
|
|
|
return ComplexPairTy(ResR, ResI);
|
|
|
|
}
|
|
|
|
|
2007-08-22 04:41:44 +08:00
|
|
|
ComplexPairTy ComplexExprEmitter::VisitUnaryNot(const UnaryOperator *E) {
|
2009-05-29 23:46:01 +08:00
|
|
|
TestAndClearIgnoreReal();
|
|
|
|
TestAndClearIgnoreImag();
|
2007-08-22 04:41:44 +08:00
|
|
|
// ~(a+ib) = a + i*-b
|
|
|
|
ComplexPairTy Op = Visit(E->getSubExpr());
|
2009-06-17 14:36:24 +08:00
|
|
|
llvm::Value *ResI;
|
2010-02-16 00:14:01 +08:00
|
|
|
if (Op.second->getType()->isFloatingPointTy())
|
2009-06-17 14:36:24 +08:00
|
|
|
ResI = Builder.CreateFNeg(Op.second, "conj.i");
|
|
|
|
else
|
|
|
|
ResI = Builder.CreateNeg(Op.second, "conj.i");
|
2009-09-09 21:00:44 +08:00
|
|
|
|
2007-08-22 04:41:44 +08:00
|
|
|
return ComplexPairTy(Op.first, ResI);
|
|
|
|
}
|
2007-08-22 04:08:23 +08:00
|
|
|
|
2007-08-27 06:09:01 +08:00
|
|
|
ComplexPairTy ComplexExprEmitter::EmitBinAdd(const BinOpInfo &Op) {
|
2009-06-17 14:36:24 +08:00
|
|
|
llvm::Value *ResR, *ResI;
|
2009-09-09 21:00:44 +08:00
|
|
|
|
2010-02-16 00:14:01 +08:00
|
|
|
if (Op.LHS.first->getType()->isFloatingPointTy()) {
|
2009-06-17 14:36:24 +08:00
|
|
|
ResR = Builder.CreateFAdd(Op.LHS.first, Op.RHS.first, "add.r");
|
2014-10-11 08:57:18 +08:00
|
|
|
if (Op.LHS.second && Op.RHS.second)
|
|
|
|
ResI = Builder.CreateFAdd(Op.LHS.second, Op.RHS.second, "add.i");
|
|
|
|
else
|
|
|
|
ResI = Op.LHS.second ? Op.LHS.second : Op.RHS.second;
|
|
|
|
assert(ResI && "Only one operand may be real!");
|
2009-06-17 14:36:24 +08:00
|
|
|
} else {
|
|
|
|
ResR = Builder.CreateAdd(Op.LHS.first, Op.RHS.first, "add.r");
|
2014-10-11 08:57:18 +08:00
|
|
|
assert(Op.LHS.second && Op.RHS.second &&
|
|
|
|
"Both operands of integer complex operators must be complex!");
|
2009-06-17 14:36:24 +08:00
|
|
|
ResI = Builder.CreateAdd(Op.LHS.second, Op.RHS.second, "add.i");
|
|
|
|
}
|
2007-08-21 13:54:00 +08:00
|
|
|
return ComplexPairTy(ResR, ResI);
|
|
|
|
}
|
|
|
|
|
2007-08-27 06:09:01 +08:00
|
|
|
ComplexPairTy ComplexExprEmitter::EmitBinSub(const BinOpInfo &Op) {
|
2009-06-17 14:36:24 +08:00
|
|
|
llvm::Value *ResR, *ResI;
|
2010-02-16 00:14:01 +08:00
|
|
|
if (Op.LHS.first->getType()->isFloatingPointTy()) {
|
2014-10-11 08:57:18 +08:00
|
|
|
ResR = Builder.CreateFSub(Op.LHS.first, Op.RHS.first, "sub.r");
|
|
|
|
if (Op.LHS.second && Op.RHS.second)
|
|
|
|
ResI = Builder.CreateFSub(Op.LHS.second, Op.RHS.second, "sub.i");
|
|
|
|
else
|
|
|
|
ResI = Op.LHS.second ? Op.LHS.second
|
|
|
|
: Builder.CreateFNeg(Op.RHS.second, "sub.i");
|
|
|
|
assert(ResI && "Only one operand may be real!");
|
2009-06-17 14:36:24 +08:00
|
|
|
} else {
|
2014-10-11 08:57:18 +08:00
|
|
|
ResR = Builder.CreateSub(Op.LHS.first, Op.RHS.first, "sub.r");
|
|
|
|
assert(Op.LHS.second && Op.RHS.second &&
|
|
|
|
"Both operands of integer complex operators must be complex!");
|
2009-06-17 14:36:24 +08:00
|
|
|
ResI = Builder.CreateSub(Op.LHS.second, Op.RHS.second, "sub.i");
|
|
|
|
}
|
2007-08-24 07:46:33 +08:00
|
|
|
return ComplexPairTy(ResR, ResI);
|
|
|
|
}
|
|
|
|
|
2014-10-11 08:57:18 +08:00
|
|
|
/// \brief Emit a libcall for a binary operation on complex types.
|
|
|
|
ComplexPairTy ComplexExprEmitter::EmitComplexBinOpLibCall(StringRef LibCallName,
|
|
|
|
const BinOpInfo &Op) {
|
|
|
|
CallArgList Args;
|
|
|
|
Args.add(RValue::get(Op.LHS.first),
|
|
|
|
Op.Ty->castAs<ComplexType>()->getElementType());
|
|
|
|
Args.add(RValue::get(Op.LHS.second),
|
|
|
|
Op.Ty->castAs<ComplexType>()->getElementType());
|
|
|
|
Args.add(RValue::get(Op.RHS.first),
|
|
|
|
Op.Ty->castAs<ComplexType>()->getElementType());
|
|
|
|
Args.add(RValue::get(Op.RHS.second),
|
|
|
|
Op.Ty->castAs<ComplexType>()->getElementType());
|
|
|
|
|
|
|
|
// We *must* use the full CG function call building logic here because the
|
2014-12-03 00:04:58 +08:00
|
|
|
// complex type has special ABI handling. We also should not forget about
|
|
|
|
// special calling convention which may be used for compiler builtins.
|
|
|
|
const CGFunctionInfo &FuncInfo =
|
|
|
|
CGF.CGM.getTypes().arrangeFreeFunctionCall(
|
|
|
|
Op.Ty, Args, FunctionType::ExtInfo(/* No CC here - will be added later */),
|
|
|
|
RequiredArgs::All);
|
2014-10-11 08:57:18 +08:00
|
|
|
llvm::FunctionType *FTy = CGF.CGM.getTypes().GetFunctionType(FuncInfo);
|
2014-12-03 00:04:58 +08:00
|
|
|
llvm::Constant *Func = CGF.CGM.CreateBuiltinFunction(FTy, LibCallName);
|
|
|
|
llvm::Instruction *Call;
|
2014-10-11 08:57:18 +08:00
|
|
|
|
2014-12-03 00:04:58 +08:00
|
|
|
RValue Res = CGF.EmitCall(FuncInfo, Func, ReturnValueSlot(), Args,
|
|
|
|
nullptr, &Call);
|
|
|
|
cast<llvm::CallInst>(Call)->setCallingConv(CGF.CGM.getBuiltinCC());
|
|
|
|
cast<llvm::CallInst>(Call)->setDoesNotThrow();
|
|
|
|
|
|
|
|
return Res.getComplexVal();
|
2014-10-11 08:57:18 +08:00
|
|
|
}
|
|
|
|
|
2014-10-20 03:13:49 +08:00
|
|
|
/// \brief Lookup the libcall name for a given floating point type complex
|
|
|
|
/// multiply.
|
|
|
|
static StringRef getComplexMultiplyLibCallName(llvm::Type *Ty) {
|
|
|
|
switch (Ty->getTypeID()) {
|
|
|
|
default:
|
|
|
|
llvm_unreachable("Unsupported floating point type!");
|
|
|
|
case llvm::Type::HalfTyID:
|
|
|
|
return "__mulhc3";
|
|
|
|
case llvm::Type::FloatTyID:
|
|
|
|
return "__mulsc3";
|
|
|
|
case llvm::Type::DoubleTyID:
|
|
|
|
return "__muldc3";
|
|
|
|
case llvm::Type::PPC_FP128TyID:
|
|
|
|
return "__multc3";
|
|
|
|
case llvm::Type::X86_FP80TyID:
|
|
|
|
return "__mulxc3";
|
2014-10-21 09:34:34 +08:00
|
|
|
case llvm::Type::FP128TyID:
|
|
|
|
return "__multc3";
|
2014-10-20 03:13:49 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-10-11 08:57:18 +08:00
|
|
|
// See C11 Annex G.5.1 for the semantics of multiplicative operators on complex
|
|
|
|
// typed values.
|
2007-08-27 06:09:01 +08:00
|
|
|
ComplexPairTy ComplexExprEmitter::EmitBinMul(const BinOpInfo &Op) {
|
2009-06-17 14:36:24 +08:00
|
|
|
using llvm::Value;
|
|
|
|
Value *ResR, *ResI;
|
2014-10-20 03:13:49 +08:00
|
|
|
llvm::MDBuilder MDHelper(CGF.getLLVMContext());
|
2009-09-09 21:00:44 +08:00
|
|
|
|
2010-02-16 00:14:01 +08:00
|
|
|
if (Op.LHS.first->getType()->isFloatingPointTy()) {
|
2014-10-11 08:57:18 +08:00
|
|
|
// The general formulation is:
|
|
|
|
// (a + ib) * (c + id) = (a * c - b * d) + i(a * d + b * c)
|
|
|
|
//
|
|
|
|
// But we can fold away components which would be zero due to a real
|
|
|
|
// operand according to C11 Annex G.5.1p2.
|
|
|
|
// FIXME: C11 also provides for imaginary types which would allow folding
|
|
|
|
// still more of this within the type system.
|
|
|
|
|
|
|
|
if (Op.LHS.second && Op.RHS.second) {
|
2014-10-20 03:13:49 +08:00
|
|
|
// If both operands are complex, emit the core math directly, and then
|
|
|
|
// test for NaNs. If we find NaNs in the result, we delegate to a libcall
|
|
|
|
// to carefully re-compute the correct infinity representation if
|
|
|
|
// possible. The expectation is that the presence of NaNs here is
|
|
|
|
// *extremely* rare, and so the cost of the libcall is almost irrelevant.
|
|
|
|
// This is good, because the libcall re-computes the core multiplication
|
|
|
|
// exactly the same as we do here and re-tests for NaNs in order to be
|
|
|
|
// a generic complex*complex libcall.
|
|
|
|
|
|
|
|
// First compute the four products.
|
|
|
|
Value *AC = Builder.CreateFMul(Op.LHS.first, Op.RHS.first, "mul_ac");
|
|
|
|
Value *BD = Builder.CreateFMul(Op.LHS.second, Op.RHS.second, "mul_bd");
|
|
|
|
Value *AD = Builder.CreateFMul(Op.LHS.first, Op.RHS.second, "mul_ad");
|
|
|
|
Value *BC = Builder.CreateFMul(Op.LHS.second, Op.RHS.first, "mul_bc");
|
|
|
|
|
|
|
|
// The real part is the difference of the first two, the imaginary part is
|
|
|
|
// the sum of the second.
|
|
|
|
ResR = Builder.CreateFSub(AC, BD, "mul_r");
|
|
|
|
ResI = Builder.CreateFAdd(AD, BC, "mul_i");
|
|
|
|
|
|
|
|
// Emit the test for the real part becoming NaN and create a branch to
|
|
|
|
// handle it. We test for NaN by comparing the number to itself.
|
|
|
|
Value *IsRNaN = Builder.CreateFCmpUNO(ResR, ResR, "isnan_cmp");
|
|
|
|
llvm::BasicBlock *ContBB = CGF.createBasicBlock("complex_mul_cont");
|
|
|
|
llvm::BasicBlock *INaNBB = CGF.createBasicBlock("complex_mul_imag_nan");
|
|
|
|
llvm::Instruction *Branch = Builder.CreateCondBr(IsRNaN, INaNBB, ContBB);
|
|
|
|
llvm::BasicBlock *OrigBB = Branch->getParent();
|
|
|
|
|
|
|
|
// Give hint that we very much don't expect to see NaNs.
|
|
|
|
// Value chosen to match UR_NONTAKEN_WEIGHT, see BranchProbabilityInfo.cpp
|
|
|
|
llvm::MDNode *BrWeight = MDHelper.createBranchWeights(1, (1U << 20) - 1);
|
|
|
|
Branch->setMetadata(llvm::LLVMContext::MD_prof, BrWeight);
|
|
|
|
|
|
|
|
// Now test the imaginary part and create its branch.
|
|
|
|
CGF.EmitBlock(INaNBB);
|
|
|
|
Value *IsINaN = Builder.CreateFCmpUNO(ResI, ResI, "isnan_cmp");
|
|
|
|
llvm::BasicBlock *LibCallBB = CGF.createBasicBlock("complex_mul_libcall");
|
|
|
|
Branch = Builder.CreateCondBr(IsINaN, LibCallBB, ContBB);
|
|
|
|
Branch->setMetadata(llvm::LLVMContext::MD_prof, BrWeight);
|
|
|
|
|
|
|
|
// Now emit the libcall on this slowest of the slow paths.
|
|
|
|
CGF.EmitBlock(LibCallBB);
|
|
|
|
Value *LibCallR, *LibCallI;
|
|
|
|
std::tie(LibCallR, LibCallI) = EmitComplexBinOpLibCall(
|
|
|
|
getComplexMultiplyLibCallName(Op.LHS.first->getType()), Op);
|
|
|
|
Builder.CreateBr(ContBB);
|
|
|
|
|
|
|
|
// Finally continue execution by phi-ing together the different
|
|
|
|
// computation paths.
|
|
|
|
CGF.EmitBlock(ContBB);
|
|
|
|
llvm::PHINode *RealPHI = Builder.CreatePHI(ResR->getType(), 3, "real_mul_phi");
|
|
|
|
RealPHI->addIncoming(ResR, OrigBB);
|
|
|
|
RealPHI->addIncoming(ResR, INaNBB);
|
|
|
|
RealPHI->addIncoming(LibCallR, LibCallBB);
|
|
|
|
llvm::PHINode *ImagPHI = Builder.CreatePHI(ResI->getType(), 3, "imag_mul_phi");
|
|
|
|
ImagPHI->addIncoming(ResI, OrigBB);
|
|
|
|
ImagPHI->addIncoming(ResI, INaNBB);
|
|
|
|
ImagPHI->addIncoming(LibCallI, LibCallBB);
|
|
|
|
return ComplexPairTy(RealPHI, ImagPHI);
|
2014-10-11 08:57:18 +08:00
|
|
|
}
|
|
|
|
assert((Op.LHS.second || Op.RHS.second) &&
|
|
|
|
"At least one operand must be complex!");
|
|
|
|
|
|
|
|
// If either of the operands is a real rather than a complex, the
|
|
|
|
// imaginary component is ignored when computing the real component of the
|
|
|
|
// result.
|
|
|
|
ResR = Builder.CreateFMul(Op.LHS.first, Op.RHS.first, "mul.rl");
|
2009-09-09 21:00:44 +08:00
|
|
|
|
2014-10-11 08:57:18 +08:00
|
|
|
ResI = Op.LHS.second
|
|
|
|
? Builder.CreateFMul(Op.LHS.second, Op.RHS.first, "mul.il")
|
|
|
|
: Builder.CreateFMul(Op.LHS.first, Op.RHS.second, "mul.ir");
|
2009-06-17 14:36:24 +08:00
|
|
|
} else {
|
2014-10-11 08:57:18 +08:00
|
|
|
assert(Op.LHS.second && Op.RHS.second &&
|
|
|
|
"Both operands of integer complex operators must be complex!");
|
2009-06-17 14:36:24 +08:00
|
|
|
Value *ResRl = Builder.CreateMul(Op.LHS.first, Op.RHS.first, "mul.rl");
|
2014-10-11 08:57:18 +08:00
|
|
|
Value *ResRr = Builder.CreateMul(Op.LHS.second, Op.RHS.second, "mul.rr");
|
|
|
|
ResR = Builder.CreateSub(ResRl, ResRr, "mul.r");
|
2009-09-09 21:00:44 +08:00
|
|
|
|
2009-06-17 14:36:24 +08:00
|
|
|
Value *ResIl = Builder.CreateMul(Op.LHS.second, Op.RHS.first, "mul.il");
|
|
|
|
Value *ResIr = Builder.CreateMul(Op.LHS.first, Op.RHS.second, "mul.ir");
|
2014-10-11 08:57:18 +08:00
|
|
|
ResI = Builder.CreateAdd(ResIl, ResIr, "mul.i");
|
2009-06-17 14:36:24 +08:00
|
|
|
}
|
2007-08-22 00:34:16 +08:00
|
|
|
return ComplexPairTy(ResR, ResI);
|
|
|
|
}
|
|
|
|
|
2014-10-11 08:57:18 +08:00
|
|
|
// See C11 Annex G.5.1 for the semantics of multiplicative operators on complex
|
|
|
|
// typed values.
|
2007-08-27 06:09:01 +08:00
|
|
|
ComplexPairTy ComplexExprEmitter::EmitBinDiv(const BinOpInfo &Op) {
|
|
|
|
llvm::Value *LHSr = Op.LHS.first, *LHSi = Op.LHS.second;
|
|
|
|
llvm::Value *RHSr = Op.RHS.first, *RHSi = Op.RHS.second;
|
2009-09-09 21:00:44 +08:00
|
|
|
|
2007-08-27 05:24:19 +08:00
|
|
|
|
|
|
|
llvm::Value *DSTr, *DSTi;
|
2014-10-11 08:57:18 +08:00
|
|
|
if (LHSr->getType()->isFloatingPointTy()) {
|
|
|
|
// If we have a complex operand on the RHS, we delegate to a libcall to
|
|
|
|
// handle all of the complexities and minimize underflow/overflow cases.
|
|
|
|
//
|
|
|
|
// FIXME: We would be able to avoid the libcall in many places if we
|
|
|
|
// supported imaginary types in addition to complex types.
|
|
|
|
if (RHSi) {
|
|
|
|
BinOpInfo LibCallOp = Op;
|
|
|
|
// If LHS was a real, supply a null imaginary part.
|
|
|
|
if (!LHSi)
|
|
|
|
LibCallOp.LHS.second = llvm::Constant::getNullValue(LHSr->getType());
|
|
|
|
|
|
|
|
StringRef LibCallName;
|
|
|
|
switch (LHSr->getType()->getTypeID()) {
|
|
|
|
default:
|
|
|
|
llvm_unreachable("Unsupported floating point type!");
|
|
|
|
case llvm::Type::HalfTyID:
|
|
|
|
return EmitComplexBinOpLibCall("__divhc3", LibCallOp);
|
|
|
|
case llvm::Type::FloatTyID:
|
|
|
|
return EmitComplexBinOpLibCall("__divsc3", LibCallOp);
|
|
|
|
case llvm::Type::DoubleTyID:
|
|
|
|
return EmitComplexBinOpLibCall("__divdc3", LibCallOp);
|
2014-10-17 19:51:19 +08:00
|
|
|
case llvm::Type::PPC_FP128TyID:
|
|
|
|
return EmitComplexBinOpLibCall("__divtc3", LibCallOp);
|
2014-10-11 08:57:18 +08:00
|
|
|
case llvm::Type::X86_FP80TyID:
|
|
|
|
return EmitComplexBinOpLibCall("__divxc3", LibCallOp);
|
2014-10-21 09:34:34 +08:00
|
|
|
case llvm::Type::FP128TyID:
|
|
|
|
return EmitComplexBinOpLibCall("__divtc3", LibCallOp);
|
2014-10-11 08:57:18 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
assert(LHSi && "Can have at most one non-complex operand!");
|
2009-09-09 21:00:44 +08:00
|
|
|
|
2014-10-11 08:57:18 +08:00
|
|
|
DSTr = Builder.CreateFDiv(LHSr, RHSr);
|
|
|
|
DSTi = Builder.CreateFDiv(LHSi, RHSr);
|
2007-08-27 05:24:19 +08:00
|
|
|
} else {
|
2014-10-11 08:57:18 +08:00
|
|
|
assert(Op.LHS.second && Op.RHS.second &&
|
|
|
|
"Both operands of integer complex operators must be complex!");
|
2009-06-17 14:36:24 +08:00
|
|
|
// (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd))
|
2011-09-28 05:06:10 +08:00
|
|
|
llvm::Value *Tmp1 = Builder.CreateMul(LHSr, RHSr); // a*c
|
|
|
|
llvm::Value *Tmp2 = Builder.CreateMul(LHSi, RHSi); // b*d
|
|
|
|
llvm::Value *Tmp3 = Builder.CreateAdd(Tmp1, Tmp2); // ac+bd
|
2009-09-09 21:00:44 +08:00
|
|
|
|
2011-09-28 05:06:10 +08:00
|
|
|
llvm::Value *Tmp4 = Builder.CreateMul(RHSr, RHSr); // c*c
|
|
|
|
llvm::Value *Tmp5 = Builder.CreateMul(RHSi, RHSi); // d*d
|
|
|
|
llvm::Value *Tmp6 = Builder.CreateAdd(Tmp4, Tmp5); // cc+dd
|
2009-09-09 21:00:44 +08:00
|
|
|
|
2011-09-28 05:06:10 +08:00
|
|
|
llvm::Value *Tmp7 = Builder.CreateMul(LHSi, RHSr); // b*c
|
|
|
|
llvm::Value *Tmp8 = Builder.CreateMul(LHSr, RHSi); // a*d
|
|
|
|
llvm::Value *Tmp9 = Builder.CreateSub(Tmp7, Tmp8); // bc-ad
|
2009-09-09 21:00:44 +08:00
|
|
|
|
2013-03-08 05:37:08 +08:00
|
|
|
if (Op.Ty->castAs<ComplexType>()->getElementType()->isUnsignedIntegerType()) {
|
2011-09-28 05:06:10 +08:00
|
|
|
DSTr = Builder.CreateUDiv(Tmp3, Tmp6);
|
|
|
|
DSTi = Builder.CreateUDiv(Tmp9, Tmp6);
|
2007-08-27 05:24:19 +08:00
|
|
|
} else {
|
2011-09-28 05:06:10 +08:00
|
|
|
DSTr = Builder.CreateSDiv(Tmp3, Tmp6);
|
|
|
|
DSTi = Builder.CreateSDiv(Tmp9, Tmp6);
|
2007-08-27 05:24:19 +08:00
|
|
|
}
|
|
|
|
}
|
2009-09-09 21:00:44 +08:00
|
|
|
|
2007-08-27 05:24:19 +08:00
|
|
|
return ComplexPairTy(DSTr, DSTi);
|
|
|
|
}
|
|
|
|
|
2009-09-09 21:00:44 +08:00
|
|
|
ComplexExprEmitter::BinOpInfo
|
2007-08-27 06:09:01 +08:00
|
|
|
ComplexExprEmitter::EmitBinOps(const BinaryOperator *E) {
|
2009-05-29 23:46:01 +08:00
|
|
|
TestAndClearIgnoreReal();
|
|
|
|
TestAndClearIgnoreImag();
|
2007-08-27 06:09:01 +08:00
|
|
|
BinOpInfo Ops;
|
2014-10-11 08:57:18 +08:00
|
|
|
if (E->getLHS()->getType()->isRealFloatingType())
|
|
|
|
Ops.LHS = ComplexPairTy(CGF.EmitScalarExpr(E->getLHS()), nullptr);
|
|
|
|
else
|
|
|
|
Ops.LHS = Visit(E->getLHS());
|
|
|
|
if (E->getRHS()->getType()->isRealFloatingType())
|
|
|
|
Ops.RHS = ComplexPairTy(CGF.EmitScalarExpr(E->getRHS()), nullptr);
|
|
|
|
else
|
|
|
|
Ops.RHS = Visit(E->getRHS());
|
|
|
|
|
2007-08-27 06:09:01 +08:00
|
|
|
Ops.Ty = E->getType();
|
|
|
|
return Ops;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-11-16 18:08:07 +08:00
|
|
|
LValue ComplexExprEmitter::
|
|
|
|
EmitCompoundAssignLValue(const CompoundAssignOperator *E,
|
|
|
|
ComplexPairTy (ComplexExprEmitter::*Func)(const BinOpInfo&),
|
2013-06-12 09:40:06 +08:00
|
|
|
RValue &Val) {
|
2009-05-29 23:46:01 +08:00
|
|
|
TestAndClearIgnoreReal();
|
|
|
|
TestAndClearIgnoreImag();
|
2011-01-18 10:00:16 +08:00
|
|
|
QualType LHSTy = E->getLHS()->getType();
|
2007-08-27 06:09:01 +08:00
|
|
|
|
|
|
|
BinOpInfo OpInfo;
|
2009-09-09 21:00:44 +08:00
|
|
|
|
2009-05-29 23:46:01 +08:00
|
|
|
// Load the RHS and LHS operands.
|
|
|
|
// __block variables need to have the rhs evaluated first, plus this should
|
2010-11-16 13:45:35 +08:00
|
|
|
// improve codegen a little.
|
2009-03-28 09:22:36 +08:00
|
|
|
OpInfo.Ty = E->getComputationResultType();
|
2014-10-11 08:57:18 +08:00
|
|
|
QualType ComplexElementTy = cast<ComplexType>(OpInfo.Ty)->getElementType();
|
2010-11-16 13:45:35 +08:00
|
|
|
|
|
|
|
// The RHS should have been converted to the computation type.
|
2014-10-11 08:57:18 +08:00
|
|
|
if (E->getRHS()->getType()->isRealFloatingType()) {
|
|
|
|
assert(
|
|
|
|
CGF.getContext()
|
|
|
|
.hasSameUnqualifiedType(ComplexElementTy, E->getRHS()->getType()));
|
|
|
|
OpInfo.RHS = ComplexPairTy(CGF.EmitScalarExpr(E->getRHS()), nullptr);
|
|
|
|
} else {
|
|
|
|
assert(CGF.getContext()
|
|
|
|
.hasSameUnqualifiedType(OpInfo.Ty, E->getRHS()->getType()));
|
|
|
|
OpInfo.RHS = Visit(E->getRHS());
|
|
|
|
}
|
2013-11-22 18:20:40 +08:00
|
|
|
|
2010-06-30 06:44:21 +08:00
|
|
|
LValue LHS = CGF.EmitLValue(E->getLHS());
|
2010-12-04 16:14:53 +08:00
|
|
|
|
2013-06-12 09:40:06 +08:00
|
|
|
// Load from the l-value and convert it.
|
|
|
|
if (LHSTy->isAnyComplexType()) {
|
2013-10-02 10:29:49 +08:00
|
|
|
ComplexPairTy LHSVal = EmitLoadOfLValue(LHS, E->getExprLoc());
|
2013-06-12 09:40:06 +08:00
|
|
|
OpInfo.LHS = EmitComplexToComplexCast(LHSVal, LHSTy, OpInfo.Ty);
|
|
|
|
} else {
|
2013-10-02 10:29:49 +08:00
|
|
|
llvm::Value *LHSVal = CGF.EmitLoadOfScalar(LHS, E->getExprLoc());
|
2014-10-11 08:57:18 +08:00
|
|
|
// For floating point real operands we can directly pass the scalar form
|
|
|
|
// to the binary operator emission and potentially get more efficient code.
|
|
|
|
if (LHSTy->isRealFloatingType()) {
|
|
|
|
if (!CGF.getContext().hasSameUnqualifiedType(ComplexElementTy, LHSTy))
|
|
|
|
LHSVal = CGF.EmitScalarConversion(LHSVal, LHSTy, ComplexElementTy);
|
|
|
|
OpInfo.LHS = ComplexPairTy(LHSVal, nullptr);
|
|
|
|
} else {
|
|
|
|
OpInfo.LHS = EmitScalarToComplexCast(LHSVal, LHSTy, OpInfo.Ty);
|
|
|
|
}
|
2013-06-12 09:40:06 +08:00
|
|
|
}
|
2009-09-09 21:00:44 +08:00
|
|
|
|
2007-08-27 06:09:01 +08:00
|
|
|
// Expand the binary operator.
|
|
|
|
ComplexPairTy Result = (this->*Func)(OpInfo);
|
2009-09-09 21:00:44 +08:00
|
|
|
|
2013-06-12 09:40:06 +08:00
|
|
|
// Truncate the result and store it into the LHS lvalue.
|
|
|
|
if (LHSTy->isAnyComplexType()) {
|
|
|
|
ComplexPairTy ResVal = EmitComplexToComplexCast(Result, OpInfo.Ty, LHSTy);
|
2015-01-14 15:38:27 +08:00
|
|
|
EmitStoreOfComplex(ResVal, LHS, /*isInit*/ false);
|
2013-06-12 09:40:06 +08:00
|
|
|
Val = RValue::getComplex(ResVal);
|
|
|
|
} else {
|
|
|
|
llvm::Value *ResVal =
|
|
|
|
CGF.EmitComplexToScalarConversion(Result, OpInfo.Ty, LHSTy);
|
|
|
|
CGF.EmitStoreOfScalar(ResVal, LHS, /*isInit*/ false);
|
|
|
|
Val = RValue::get(ResVal);
|
|
|
|
}
|
2010-06-30 06:44:21 +08:00
|
|
|
|
2010-11-16 18:08:07 +08:00
|
|
|
return LHS;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Compound assignments.
|
|
|
|
ComplexPairTy ComplexExprEmitter::
|
|
|
|
EmitCompoundAssign(const CompoundAssignOperator *E,
|
|
|
|
ComplexPairTy (ComplexExprEmitter::*Func)(const BinOpInfo&)){
|
2013-06-12 09:40:06 +08:00
|
|
|
RValue Val;
|
2010-11-16 18:08:07 +08:00
|
|
|
LValue LV = EmitCompoundAssignLValue(E, Func, Val);
|
|
|
|
|
|
|
|
// The result of an assignment in C is the assigned r-value.
|
2012-11-02 06:30:59 +08:00
|
|
|
if (!CGF.getLangOpts().CPlusPlus)
|
2013-06-12 09:40:06 +08:00
|
|
|
return Val.getComplexVal();
|
2010-11-16 18:08:07 +08:00
|
|
|
|
|
|
|
// If the lvalue is non-volatile, return the computed value of the assignment.
|
|
|
|
if (!LV.isVolatileQualified())
|
2013-06-12 09:40:06 +08:00
|
|
|
return Val.getComplexVal();
|
2010-11-16 18:08:07 +08:00
|
|
|
|
2013-10-02 10:29:49 +08:00
|
|
|
return EmitLoadOfLValue(LV, E->getExprLoc());
|
2007-08-27 06:09:01 +08:00
|
|
|
}
|
2007-08-27 05:24:19 +08:00
|
|
|
|
2010-11-16 18:08:07 +08:00
|
|
|
LValue ComplexExprEmitter::EmitBinAssignLValue(const BinaryOperator *E,
|
|
|
|
ComplexPairTy &Val) {
|
2013-11-22 18:20:40 +08:00
|
|
|
assert(CGF.getContext().hasSameUnqualifiedType(E->getLHS()->getType(),
|
2010-07-14 02:40:04 +08:00
|
|
|
E->getRHS()->getType()) &&
|
2008-07-27 06:37:01 +08:00
|
|
|
"Invalid assignment");
|
2010-11-16 18:08:07 +08:00
|
|
|
TestAndClearIgnoreReal();
|
|
|
|
TestAndClearIgnoreImag();
|
|
|
|
|
2010-12-06 14:10:02 +08:00
|
|
|
// Emit the RHS. __block variables need the RHS evaluated first.
|
2010-11-16 18:08:07 +08:00
|
|
|
Val = Visit(E->getRHS());
|
2007-08-21 13:54:00 +08:00
|
|
|
|
|
|
|
// Compute the address to store into.
|
|
|
|
LValue LHS = CGF.EmitLValue(E->getLHS());
|
2009-09-09 21:00:44 +08:00
|
|
|
|
2010-06-30 06:44:21 +08:00
|
|
|
// Store the result value into the LHS lvalue.
|
2015-01-14 15:38:27 +08:00
|
|
|
EmitStoreOfComplex(Val, LHS, /*isInit*/ false);
|
2009-06-10 12:38:50 +08:00
|
|
|
|
2010-11-16 18:08:07 +08:00
|
|
|
return LHS;
|
|
|
|
}
|
2010-06-30 06:44:21 +08:00
|
|
|
|
2010-11-16 18:08:07 +08:00
|
|
|
ComplexPairTy ComplexExprEmitter::VisitBinAssign(const BinaryOperator *E) {
|
|
|
|
ComplexPairTy Val;
|
|
|
|
LValue LV = EmitBinAssignLValue(E, Val);
|
|
|
|
|
|
|
|
// The result of an assignment in C is the assigned r-value.
|
2012-11-02 06:30:59 +08:00
|
|
|
if (!CGF.getLangOpts().CPlusPlus)
|
2010-11-16 18:08:07 +08:00
|
|
|
return Val;
|
|
|
|
|
|
|
|
// If the lvalue is non-volatile, return the computed value of the assignment.
|
|
|
|
if (!LV.isVolatileQualified())
|
|
|
|
return Val;
|
|
|
|
|
2013-10-02 10:29:49 +08:00
|
|
|
return EmitLoadOfLValue(LV, E->getExprLoc());
|
2007-08-21 13:54:00 +08:00
|
|
|
}
|
|
|
|
|
2007-08-22 01:15:50 +08:00
|
|
|
ComplexPairTy ComplexExprEmitter::VisitBinComma(const BinaryOperator *E) {
|
2010-12-05 10:00:02 +08:00
|
|
|
CGF.EmitIgnoredExpr(E->getLHS());
|
2007-08-22 01:15:50 +08:00
|
|
|
return Visit(E->getRHS());
|
|
|
|
}
|
2007-08-21 13:54:00 +08:00
|
|
|
|
|
|
|
ComplexPairTy ComplexExprEmitter::
|
2011-02-17 18:25:35 +08:00
|
|
|
VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) {
|
2009-05-29 23:46:01 +08:00
|
|
|
TestAndClearIgnoreReal();
|
|
|
|
TestAndClearIgnoreImag();
|
2008-11-13 09:38:36 +08:00
|
|
|
llvm::BasicBlock *LHSBlock = CGF.createBasicBlock("cond.true");
|
|
|
|
llvm::BasicBlock *RHSBlock = CGF.createBasicBlock("cond.false");
|
|
|
|
llvm::BasicBlock *ContBlock = CGF.createBasicBlock("cond.end");
|
2009-09-09 21:00:44 +08:00
|
|
|
|
2011-02-17 18:25:35 +08:00
|
|
|
// Bind the common expression if necessary.
|
2012-01-07 04:42:20 +08:00
|
|
|
CodeGenFunction::OpaqueValueMapping binding(CGF, E);
|
2011-01-26 12:00:11 +08:00
|
|
|
|
2014-01-07 06:27:43 +08:00
|
|
|
RegionCounter Cnt = CGF.getPGORegionCounter(E);
|
2011-02-17 18:25:35 +08:00
|
|
|
CodeGenFunction::ConditionalEvaluation eval(CGF);
|
2014-01-07 06:27:43 +08:00
|
|
|
CGF.EmitBranchOnBoolExpr(E->getCond(), LHSBlock, RHSBlock, Cnt.getCount());
|
2009-09-09 21:00:44 +08:00
|
|
|
|
2011-01-26 12:00:11 +08:00
|
|
|
eval.begin(CGF);
|
2007-08-21 13:54:00 +08:00
|
|
|
CGF.EmitBlock(LHSBlock);
|
2014-01-07 06:27:43 +08:00
|
|
|
Cnt.beginRegion(Builder);
|
2010-09-21 07:50:22 +08:00
|
|
|
ComplexPairTy LHS = Visit(E->getTrueExpr());
|
2007-08-22 01:39:38 +08:00
|
|
|
LHSBlock = Builder.GetInsertBlock();
|
2008-11-11 17:41:28 +08:00
|
|
|
CGF.EmitBranch(ContBlock);
|
2011-01-26 12:00:11 +08:00
|
|
|
eval.end(CGF);
|
2009-09-09 21:00:44 +08:00
|
|
|
|
2011-01-26 12:00:11 +08:00
|
|
|
eval.begin(CGF);
|
2007-08-21 13:54:00 +08:00
|
|
|
CGF.EmitBlock(RHSBlock);
|
2011-02-17 18:25:35 +08:00
|
|
|
ComplexPairTy RHS = Visit(E->getFalseExpr());
|
2007-08-22 01:39:38 +08:00
|
|
|
RHSBlock = Builder.GetInsertBlock();
|
2007-08-21 13:54:00 +08:00
|
|
|
CGF.EmitBlock(ContBlock);
|
2011-01-26 12:00:11 +08:00
|
|
|
eval.end(CGF);
|
2009-09-09 21:00:44 +08:00
|
|
|
|
2007-08-21 13:54:00 +08:00
|
|
|
// Create a PHI node for the real part.
|
2011-03-30 19:28:58 +08:00
|
|
|
llvm::PHINode *RealPN = Builder.CreatePHI(LHS.first->getType(), 2, "cond.r");
|
2007-08-21 13:54:00 +08:00
|
|
|
RealPN->addIncoming(LHS.first, LHSBlock);
|
|
|
|
RealPN->addIncoming(RHS.first, RHSBlock);
|
|
|
|
|
|
|
|
// Create a PHI node for the imaginary part.
|
2011-03-30 19:28:58 +08:00
|
|
|
llvm::PHINode *ImagPN = Builder.CreatePHI(LHS.first->getType(), 2, "cond.i");
|
2007-08-21 13:54:00 +08:00
|
|
|
ImagPN->addIncoming(LHS.second, LHSBlock);
|
|
|
|
ImagPN->addIncoming(RHS.second, RHSBlock);
|
2009-09-09 21:00:44 +08:00
|
|
|
|
2007-08-21 13:54:00 +08:00
|
|
|
return ComplexPairTy(RealPN, ImagPN);
|
|
|
|
}
|
|
|
|
|
2007-08-24 10:18:47 +08:00
|
|
|
ComplexPairTy ComplexExprEmitter::VisitChooseExpr(ChooseExpr *E) {
|
2013-07-20 08:40:58 +08:00
|
|
|
return Visit(E->getChosenSubExpr());
|
2007-08-24 10:18:47 +08:00
|
|
|
}
|
|
|
|
|
2008-05-14 07:11:35 +08:00
|
|
|
ComplexPairTy ComplexExprEmitter::VisitInitListExpr(InitListExpr *E) {
|
2009-05-29 23:46:01 +08:00
|
|
|
bool Ignore = TestAndClearIgnoreReal();
|
|
|
|
(void)Ignore;
|
|
|
|
assert (Ignore == false && "init list ignored");
|
|
|
|
Ignore = TestAndClearIgnoreImag();
|
|
|
|
(void)Ignore;
|
|
|
|
assert (Ignore == false && "init list ignored");
|
2011-09-20 07:17:44 +08:00
|
|
|
|
|
|
|
if (E->getNumInits() == 2) {
|
|
|
|
llvm::Value *Real = CGF.EmitScalarExpr(E->getInit(0));
|
|
|
|
llvm::Value *Imag = CGF.EmitScalarExpr(E->getInit(1));
|
|
|
|
return ComplexPairTy(Real, Imag);
|
|
|
|
} else if (E->getNumInits() == 1) {
|
2008-05-14 07:11:35 +08:00
|
|
|
return Visit(E->getInit(0));
|
2011-09-20 07:17:44 +08:00
|
|
|
}
|
2008-05-14 07:11:35 +08:00
|
|
|
|
|
|
|
// Empty init list intializes to null
|
2011-09-20 07:17:44 +08:00
|
|
|
assert(E->getNumInits() == 0 && "Unexpected number of inits");
|
2013-03-08 05:37:08 +08:00
|
|
|
QualType Ty = E->getType()->castAs<ComplexType>()->getElementType();
|
2011-07-18 12:24:23 +08:00
|
|
|
llvm::Type* LTy = CGF.ConvertType(Ty);
|
2009-08-01 04:28:54 +08:00
|
|
|
llvm::Value* zeroConstant = llvm::Constant::getNullValue(LTy);
|
2008-05-14 07:11:35 +08:00
|
|
|
return ComplexPairTy(zeroConstant, zeroConstant);
|
|
|
|
}
|
|
|
|
|
2009-02-10 11:03:30 +08:00
|
|
|
ComplexPairTy ComplexExprEmitter::VisitVAArgExpr(VAArgExpr *E) {
|
2009-02-12 06:25:55 +08:00
|
|
|
llvm::Value *ArgValue = CGF.EmitVAListRef(E->getSubExpr());
|
2009-02-10 11:03:30 +08:00
|
|
|
llvm::Value *ArgPtr = CGF.EmitVAArg(ArgValue, E->getType());
|
|
|
|
|
|
|
|
if (!ArgPtr) {
|
|
|
|
CGF.ErrorUnsupported(E, "complex va_arg expression");
|
2011-07-18 12:24:23 +08:00
|
|
|
llvm::Type *EltTy =
|
2013-03-08 05:37:08 +08:00
|
|
|
CGF.ConvertType(E->getType()->castAs<ComplexType>()->getElementType());
|
2009-02-10 11:03:30 +08:00
|
|
|
llvm::Value *U = llvm::UndefValue::get(EltTy);
|
|
|
|
return ComplexPairTy(U, U);
|
|
|
|
}
|
|
|
|
|
2013-10-02 10:29:49 +08:00
|
|
|
return EmitLoadOfLValue(CGF.MakeNaturalAlignAddrLValue(ArgPtr, E->getType()),
|
|
|
|
E->getExprLoc());
|
2009-02-10 11:03:30 +08:00
|
|
|
}
|
|
|
|
|
2007-08-21 13:54:00 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Entry Point into this File
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
/// EmitComplexExpr - Emit the computation of the specified expression of
|
|
|
|
/// complex type, ignoring the result.
|
2009-05-29 23:46:01 +08:00
|
|
|
ComplexPairTy CodeGenFunction::EmitComplexExpr(const Expr *E, bool IgnoreReal,
|
2010-11-16 18:08:07 +08:00
|
|
|
bool IgnoreImag) {
|
2013-03-08 05:37:08 +08:00
|
|
|
assert(E && getComplexType(E->getType()) &&
|
2007-08-21 13:54:00 +08:00
|
|
|
"Invalid complex expression to emit");
|
2009-09-09 21:00:44 +08:00
|
|
|
|
2015-02-10 03:13:51 +08:00
|
|
|
return ComplexExprEmitter(*this, IgnoreReal, IgnoreImag)
|
|
|
|
.Visit(const_cast<Expr *>(E));
|
2007-08-21 13:54:00 +08:00
|
|
|
}
|
|
|
|
|
2013-03-08 05:37:08 +08:00
|
|
|
void CodeGenFunction::EmitComplexExprIntoLValue(const Expr *E, LValue dest,
|
2015-01-14 15:38:27 +08:00
|
|
|
bool isInit) {
|
2013-03-08 05:37:08 +08:00
|
|
|
assert(E && getComplexType(E->getType()) &&
|
2007-08-24 07:43:33 +08:00
|
|
|
"Invalid complex expression to emit");
|
|
|
|
ComplexExprEmitter Emitter(*this);
|
|
|
|
ComplexPairTy Val = Emitter.Visit(const_cast<Expr*>(E));
|
2015-01-14 15:38:27 +08:00
|
|
|
Emitter.EmitStoreOfComplex(Val, dest, isInit);
|
2007-08-24 07:43:33 +08:00
|
|
|
}
|
2007-09-01 06:49:20 +08:00
|
|
|
|
2013-03-08 05:37:08 +08:00
|
|
|
/// EmitStoreOfComplex - Store a complex number into the specified l-value.
|
|
|
|
void CodeGenFunction::EmitStoreOfComplex(ComplexPairTy V, LValue dest,
|
2015-01-14 15:38:27 +08:00
|
|
|
bool isInit) {
|
|
|
|
ComplexExprEmitter(*this).EmitStoreOfComplex(V, dest, isInit);
|
2008-08-30 13:35:15 +08:00
|
|
|
}
|
|
|
|
|
2013-03-08 05:37:08 +08:00
|
|
|
/// EmitLoadOfComplex - Load a complex number from the specified address.
|
2013-10-02 10:29:49 +08:00
|
|
|
ComplexPairTy CodeGenFunction::EmitLoadOfComplex(LValue src,
|
|
|
|
SourceLocation loc) {
|
|
|
|
return ComplexExprEmitter(*this).EmitLoadOfLValue(src, loc);
|
2007-09-01 06:49:20 +08:00
|
|
|
}
|
2010-11-17 07:07:28 +08:00
|
|
|
|
|
|
|
LValue CodeGenFunction::EmitComplexAssignmentLValue(const BinaryOperator *E) {
|
2010-12-05 10:00:02 +08:00
|
|
|
assert(E->getOpcode() == BO_Assign);
|
2010-11-17 07:07:28 +08:00
|
|
|
ComplexPairTy Val; // ignored
|
2010-12-05 10:00:02 +08:00
|
|
|
return ComplexExprEmitter(*this).EmitBinAssignLValue(E, Val);
|
|
|
|
}
|
2010-11-17 07:07:28 +08:00
|
|
|
|
2013-06-12 09:40:06 +08:00
|
|
|
typedef ComplexPairTy (ComplexExprEmitter::*CompoundFunc)(
|
|
|
|
const ComplexExprEmitter::BinOpInfo &);
|
2010-11-17 07:07:28 +08:00
|
|
|
|
2013-06-12 09:40:06 +08:00
|
|
|
static CompoundFunc getComplexOp(BinaryOperatorKind Op) {
|
|
|
|
switch (Op) {
|
|
|
|
case BO_MulAssign: return &ComplexExprEmitter::EmitBinMul;
|
|
|
|
case BO_DivAssign: return &ComplexExprEmitter::EmitBinDiv;
|
|
|
|
case BO_SubAssign: return &ComplexExprEmitter::EmitBinSub;
|
|
|
|
case BO_AddAssign: return &ComplexExprEmitter::EmitBinAdd;
|
2010-11-17 07:07:28 +08:00
|
|
|
default:
|
|
|
|
llvm_unreachable("unexpected complex compound assignment");
|
|
|
|
}
|
2013-06-12 09:40:06 +08:00
|
|
|
}
|
2010-11-17 07:07:28 +08:00
|
|
|
|
2013-06-12 09:40:06 +08:00
|
|
|
LValue CodeGenFunction::
|
|
|
|
EmitComplexCompoundAssignmentLValue(const CompoundAssignOperator *E) {
|
|
|
|
CompoundFunc Op = getComplexOp(E->getOpcode());
|
|
|
|
RValue Val;
|
2010-12-05 10:00:02 +08:00
|
|
|
return ComplexExprEmitter(*this).EmitCompoundAssignLValue(E, Op, Val);
|
2010-11-17 07:07:28 +08:00
|
|
|
}
|
2013-06-12 09:40:06 +08:00
|
|
|
|
|
|
|
LValue CodeGenFunction::
|
2015-02-13 05:23:20 +08:00
|
|
|
EmitScalarCompoundAssignWithComplex(const CompoundAssignOperator *E,
|
|
|
|
llvm::Value *&Result) {
|
2013-06-12 09:40:06 +08:00
|
|
|
CompoundFunc Op = getComplexOp(E->getOpcode());
|
|
|
|
RValue Val;
|
|
|
|
LValue Ret = ComplexExprEmitter(*this).EmitCompoundAssignLValue(E, Op, Val);
|
|
|
|
Result = Val.getScalarVal();
|
|
|
|
return Ret;
|
|
|
|
}
|