2007-08-24 13:35:26 +08:00
|
|
|
//===--- CGExprScalar.cpp - Emit LLVM Code for Scalar Exprs ---------------===//
|
|
|
|
//
|
|
|
|
// 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-24 13:35:26 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// This contains code to emit Expr nodes with scalar LLVM types as LLVM code.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include "CodeGenFunction.h"
|
|
|
|
#include "CodeGenModule.h"
|
|
|
|
#include "clang/AST/AST.h"
|
2008-04-20 08:50:39 +08:00
|
|
|
#include "clang/Basic/TargetInfo.h"
|
2007-08-24 13:35:26 +08:00
|
|
|
#include "llvm/Constants.h"
|
|
|
|
#include "llvm/Function.h"
|
2007-10-29 13:01:08 +08:00
|
|
|
#include "llvm/GlobalVariable.h"
|
2007-10-16 04:28:48 +08:00
|
|
|
#include "llvm/Intrinsics.h"
|
2007-08-24 13:35:26 +08:00
|
|
|
#include "llvm/Support/Compiler.h"
|
2008-01-03 15:05:49 +08:00
|
|
|
#include <cstdarg>
|
2007-12-11 07:44:32 +08:00
|
|
|
|
2007-08-24 13:35:26 +08:00
|
|
|
using namespace clang;
|
|
|
|
using namespace CodeGen;
|
|
|
|
using llvm::Value;
|
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Scalar Expression Emitter
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
struct BinOpInfo {
|
|
|
|
Value *LHS;
|
|
|
|
Value *RHS;
|
2007-08-25 05:00:35 +08:00
|
|
|
QualType Ty; // Computation Type.
|
2007-08-24 13:35:26 +08:00
|
|
|
const BinaryOperator *E;
|
|
|
|
};
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
class VISIBILITY_HIDDEN ScalarExprEmitter
|
|
|
|
: public StmtVisitor<ScalarExprEmitter, Value*> {
|
|
|
|
CodeGenFunction &CGF;
|
2008-04-13 15:32:11 +08:00
|
|
|
llvm::IRBuilder &Builder;
|
2008-03-01 16:45:05 +08:00
|
|
|
CGObjCRuntime *Runtime;
|
|
|
|
|
2007-08-24 13:35:26 +08:00
|
|
|
public:
|
|
|
|
|
2008-03-01 16:45:05 +08:00
|
|
|
ScalarExprEmitter(CodeGenFunction &cgf) : CGF(cgf),
|
|
|
|
Builder(CGF.Builder),
|
|
|
|
Runtime(CGF.CGM.getObjCRuntime()) {
|
2007-08-24 13:35:26 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
//===--------------------------------------------------------------------===//
|
|
|
|
// Utilities
|
|
|
|
//===--------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
const llvm::Type *ConvertType(QualType T) { return CGF.ConvertType(T); }
|
|
|
|
LValue EmitLValue(const Expr *E) { return CGF.EmitLValue(E); }
|
|
|
|
|
|
|
|
Value *EmitLoadOfLValue(LValue LV, QualType T) {
|
2007-09-01 06:49:20 +08:00
|
|
|
return CGF.EmitLoadOfLValue(LV, T).getScalarVal();
|
2007-08-24 13:35:26 +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.
|
|
|
|
Value *EmitLoadOfLValue(const Expr *E) {
|
|
|
|
// FIXME: Volatile
|
|
|
|
return EmitLoadOfLValue(EmitLValue(E), E->getType());
|
|
|
|
}
|
|
|
|
|
2007-08-27 00:42:57 +08:00
|
|
|
/// EmitConversionToBool - Convert the specified expression value to a
|
2007-08-27 01:25:57 +08:00
|
|
|
/// boolean (i1) truth value. This is equivalent to "Val != 0".
|
2007-08-27 00:42:57 +08:00
|
|
|
Value *EmitConversionToBool(Value *Src, QualType DstTy);
|
|
|
|
|
2007-08-26 14:48:56 +08:00
|
|
|
/// EmitScalarConversion - Emit a conversion from the specified type to the
|
|
|
|
/// specified destination type, both of which are LLVM scalar types.
|
2007-08-27 00:34:22 +08:00
|
|
|
Value *EmitScalarConversion(Value *Src, QualType SrcTy, QualType DstTy);
|
|
|
|
|
|
|
|
/// EmitComplexToScalarConversion - Emit a conversion from the specified
|
|
|
|
/// complex type to the specified destination type, where the destination
|
|
|
|
/// type is an LLVM scalar type.
|
|
|
|
Value *EmitComplexToScalarConversion(CodeGenFunction::ComplexPairTy Src,
|
|
|
|
QualType SrcTy, QualType DstTy);
|
2007-08-26 14:48:56 +08:00
|
|
|
|
2007-08-24 13:35:26 +08:00
|
|
|
//===--------------------------------------------------------------------===//
|
|
|
|
// Visitor Methods
|
|
|
|
//===--------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
Value *VisitStmt(Stmt *S) {
|
2007-12-12 05:27:55 +08:00
|
|
|
S->dump(CGF.getContext().getSourceManager());
|
2007-08-24 13:35:26 +08:00
|
|
|
assert(0 && "Stmt can't have complex result type!");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
Value *VisitExpr(Expr *S);
|
|
|
|
Value *VisitParenExpr(ParenExpr *PE) { return Visit(PE->getSubExpr()); }
|
|
|
|
|
|
|
|
// Leaves.
|
|
|
|
Value *VisitIntegerLiteral(const IntegerLiteral *E) {
|
|
|
|
return llvm::ConstantInt::get(E->getValue());
|
|
|
|
}
|
|
|
|
Value *VisitFloatingLiteral(const FloatingLiteral *E) {
|
2008-04-20 08:45:53 +08:00
|
|
|
return llvm::ConstantFP::get(E->getValue());
|
2007-08-24 13:35:26 +08:00
|
|
|
}
|
|
|
|
Value *VisitCharacterLiteral(const CharacterLiteral *E) {
|
|
|
|
return llvm::ConstantInt::get(ConvertType(E->getType()), E->getValue());
|
2007-11-15 13:40:03 +08:00
|
|
|
}
|
|
|
|
Value *VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *E) {
|
|
|
|
return llvm::ConstantInt::get(ConvertType(E->getType()), E->getValue());
|
2007-08-24 13:35:26 +08:00
|
|
|
}
|
|
|
|
Value *VisitTypesCompatibleExpr(const TypesCompatibleExpr *E) {
|
|
|
|
return llvm::ConstantInt::get(ConvertType(E->getType()),
|
2007-10-16 04:41:53 +08:00
|
|
|
CGF.getContext().typesAreCompatible(
|
|
|
|
E->getArgType1(), E->getArgType2()));
|
2007-08-24 13:35:26 +08:00
|
|
|
}
|
|
|
|
Value *VisitSizeOfAlignOfTypeExpr(const SizeOfAlignOfTypeExpr *E) {
|
|
|
|
return EmitSizeAlignOf(E->getArgumentType(), E->getType(), E->isSizeOf());
|
|
|
|
}
|
|
|
|
|
|
|
|
// l-values.
|
|
|
|
Value *VisitDeclRefExpr(DeclRefExpr *E) {
|
|
|
|
if (const EnumConstantDecl *EC = dyn_cast<EnumConstantDecl>(E->getDecl()))
|
|
|
|
return llvm::ConstantInt::get(EC->getInitVal());
|
|
|
|
return EmitLoadOfLValue(E);
|
|
|
|
}
|
2008-03-01 16:45:05 +08:00
|
|
|
Value *VisitObjCMessageExpr(ObjCMessageExpr *E);
|
2008-03-31 07:25:33 +08:00
|
|
|
Value *VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) { return EmitLoadOfLValue(E);}
|
2007-08-24 13:35:26 +08:00
|
|
|
Value *VisitArraySubscriptExpr(ArraySubscriptExpr *E);
|
2008-05-15 03:38:39 +08:00
|
|
|
Value *VisitShuffleVectorExpr(ShuffleVectorExpr *E);
|
2007-08-24 13:35:26 +08:00
|
|
|
Value *VisitMemberExpr(Expr *E) { return EmitLoadOfLValue(E); }
|
2008-04-19 07:10:10 +08:00
|
|
|
Value *VisitExtVectorElementExpr(Expr *E) { return EmitLoadOfLValue(E); }
|
2008-05-14 07:18:27 +08:00
|
|
|
Value *VisitCompoundLiteralExpr(CompoundLiteralExpr *E) { return EmitLoadOfLValue(E); }
|
2007-08-24 13:35:26 +08:00
|
|
|
Value *VisitStringLiteral(Expr *E) { return EmitLValue(E).getAddress(); }
|
|
|
|
Value *VisitPreDefinedExpr(Expr *E) { return EmitLValue(E).getAddress(); }
|
2007-10-25 01:18:43 +08:00
|
|
|
|
|
|
|
Value *VisitInitListExpr(InitListExpr *E) {
|
2007-12-05 15:36:10 +08:00
|
|
|
unsigned NumInitElements = E->getNumInits();
|
|
|
|
|
|
|
|
const llvm::VectorType *VType =
|
2008-01-29 09:15:48 +08:00
|
|
|
dyn_cast<llvm::VectorType>(ConvertType(E->getType()));
|
|
|
|
|
|
|
|
// We have a scalar in braces. Just use the first element.
|
|
|
|
if (!VType)
|
|
|
|
return Visit(E->getInit(0));
|
2007-12-05 15:36:10 +08:00
|
|
|
|
|
|
|
unsigned NumVectorElements = VType->getNumElements();
|
|
|
|
const llvm::Type *ElementType = VType->getElementType();
|
|
|
|
|
|
|
|
// Emit individual vector element stores.
|
|
|
|
llvm::Value *V = llvm::UndefValue::get(VType);
|
|
|
|
|
2007-12-18 10:45:33 +08:00
|
|
|
// Emit initializers
|
|
|
|
unsigned i;
|
|
|
|
for (i = 0; i < NumInitElements; ++i) {
|
2007-10-25 02:05:48 +08:00
|
|
|
Value *NewV = Visit(E->getInit(i));
|
|
|
|
Value *Idx = llvm::ConstantInt::get(llvm::Type::Int32Ty, i);
|
|
|
|
V = Builder.CreateInsertElement(V, NewV, Idx);
|
2007-10-25 01:18:43 +08:00
|
|
|
}
|
2007-12-05 15:36:10 +08:00
|
|
|
|
|
|
|
// Emit remaining default initializers
|
|
|
|
for (/* Do not initialize i*/; i < NumVectorElements; ++i) {
|
|
|
|
Value *Idx = llvm::ConstantInt::get(llvm::Type::Int32Ty, i);
|
|
|
|
llvm::Value *NewV = llvm::Constant::getNullValue(ElementType);
|
|
|
|
V = Builder.CreateInsertElement(V, NewV, Idx);
|
|
|
|
}
|
|
|
|
|
2007-10-25 02:05:48 +08:00
|
|
|
return V;
|
2007-10-25 01:18:43 +08:00
|
|
|
}
|
2008-04-08 12:40:51 +08:00
|
|
|
|
2007-08-24 13:35:26 +08:00
|
|
|
Value *VisitImplicitCastExpr(const ImplicitCastExpr *E);
|
|
|
|
Value *VisitCastExpr(const CastExpr *E) {
|
|
|
|
return EmitCastExpr(E->getSubExpr(), E->getType());
|
|
|
|
}
|
|
|
|
Value *EmitCastExpr(const Expr *E, QualType T);
|
|
|
|
|
|
|
|
Value *VisitCallExpr(const CallExpr *E) {
|
2007-09-01 06:49:20 +08:00
|
|
|
return CGF.EmitCallExpr(E).getScalarVal();
|
2007-08-24 13:35:26 +08:00
|
|
|
}
|
|
|
|
|
2007-09-01 06:09:40 +08:00
|
|
|
Value *VisitStmtExpr(const StmtExpr *E);
|
|
|
|
|
2007-08-24 13:35:26 +08:00
|
|
|
// Unary Operators.
|
|
|
|
Value *VisitPrePostIncDec(const UnaryOperator *E, bool isInc, bool isPre);
|
|
|
|
Value *VisitUnaryPostDec(const UnaryOperator *E) {
|
|
|
|
return VisitPrePostIncDec(E, false, false);
|
|
|
|
}
|
|
|
|
Value *VisitUnaryPostInc(const UnaryOperator *E) {
|
|
|
|
return VisitPrePostIncDec(E, true, false);
|
|
|
|
}
|
|
|
|
Value *VisitUnaryPreDec(const UnaryOperator *E) {
|
|
|
|
return VisitPrePostIncDec(E, false, true);
|
|
|
|
}
|
|
|
|
Value *VisitUnaryPreInc(const UnaryOperator *E) {
|
|
|
|
return VisitPrePostIncDec(E, true, true);
|
|
|
|
}
|
|
|
|
Value *VisitUnaryAddrOf(const UnaryOperator *E) {
|
|
|
|
return EmitLValue(E->getSubExpr()).getAddress();
|
|
|
|
}
|
|
|
|
Value *VisitUnaryDeref(const Expr *E) { return EmitLoadOfLValue(E); }
|
|
|
|
Value *VisitUnaryPlus(const UnaryOperator *E) {
|
|
|
|
return Visit(E->getSubExpr());
|
|
|
|
}
|
|
|
|
Value *VisitUnaryMinus (const UnaryOperator *E);
|
|
|
|
Value *VisitUnaryNot (const UnaryOperator *E);
|
|
|
|
Value *VisitUnaryLNot (const UnaryOperator *E);
|
|
|
|
Value *VisitUnarySizeOf (const UnaryOperator *E) {
|
|
|
|
return EmitSizeAlignOf(E->getSubExpr()->getType(), E->getType(), true);
|
|
|
|
}
|
|
|
|
Value *VisitUnaryAlignOf (const UnaryOperator *E) {
|
|
|
|
return EmitSizeAlignOf(E->getSubExpr()->getType(), E->getType(), false);
|
|
|
|
}
|
|
|
|
Value *EmitSizeAlignOf(QualType TypeToSize, QualType RetType,
|
2008-04-03 01:35:06 +08:00
|
|
|
bool isSizeOf);
|
2007-08-25 05:20:17 +08:00
|
|
|
Value *VisitUnaryReal (const UnaryOperator *E);
|
|
|
|
Value *VisitUnaryImag (const UnaryOperator *E);
|
2007-08-24 13:35:26 +08:00
|
|
|
Value *VisitUnaryExtension(const UnaryOperator *E) {
|
|
|
|
return Visit(E->getSubExpr());
|
|
|
|
}
|
2008-01-29 23:56:48 +08:00
|
|
|
Value *VisitUnaryOffsetOf(const UnaryOperator *E);
|
2008-04-08 12:40:51 +08:00
|
|
|
Value *VisitCXXDefaultArgExpr(CXXDefaultArgExpr *DAE) {
|
|
|
|
return Visit(DAE->getExpr());
|
|
|
|
}
|
2008-01-29 23:56:48 +08:00
|
|
|
|
2007-08-24 13:35:26 +08:00
|
|
|
// Binary Operators.
|
|
|
|
Value *EmitMul(const BinOpInfo &Ops) {
|
|
|
|
return Builder.CreateMul(Ops.LHS, Ops.RHS, "mul");
|
|
|
|
}
|
|
|
|
Value *EmitDiv(const BinOpInfo &Ops);
|
|
|
|
Value *EmitRem(const BinOpInfo &Ops);
|
|
|
|
Value *EmitAdd(const BinOpInfo &Ops);
|
|
|
|
Value *EmitSub(const BinOpInfo &Ops);
|
|
|
|
Value *EmitShl(const BinOpInfo &Ops);
|
|
|
|
Value *EmitShr(const BinOpInfo &Ops);
|
|
|
|
Value *EmitAnd(const BinOpInfo &Ops) {
|
|
|
|
return Builder.CreateAnd(Ops.LHS, Ops.RHS, "and");
|
|
|
|
}
|
|
|
|
Value *EmitXor(const BinOpInfo &Ops) {
|
|
|
|
return Builder.CreateXor(Ops.LHS, Ops.RHS, "xor");
|
|
|
|
}
|
|
|
|
Value *EmitOr (const BinOpInfo &Ops) {
|
|
|
|
return Builder.CreateOr(Ops.LHS, Ops.RHS, "or");
|
|
|
|
}
|
|
|
|
|
2007-08-25 05:00:35 +08:00
|
|
|
BinOpInfo EmitBinOps(const BinaryOperator *E);
|
2007-08-27 05:41:21 +08:00
|
|
|
Value *EmitCompoundAssign(const CompoundAssignOperator *E,
|
2007-08-25 05:00:35 +08:00
|
|
|
Value *(ScalarExprEmitter::*F)(const BinOpInfo &));
|
|
|
|
|
|
|
|
// Binary operators and binary compound assignment operators.
|
|
|
|
#define HANDLEBINOP(OP) \
|
2007-08-27 05:41:21 +08:00
|
|
|
Value *VisitBin ## OP(const BinaryOperator *E) { \
|
|
|
|
return Emit ## OP(EmitBinOps(E)); \
|
|
|
|
} \
|
|
|
|
Value *VisitBin ## OP ## Assign(const CompoundAssignOperator *E) { \
|
|
|
|
return EmitCompoundAssign(E, &ScalarExprEmitter::Emit ## OP); \
|
2007-08-25 05:00:35 +08:00
|
|
|
}
|
|
|
|
HANDLEBINOP(Mul);
|
|
|
|
HANDLEBINOP(Div);
|
|
|
|
HANDLEBINOP(Rem);
|
|
|
|
HANDLEBINOP(Add);
|
|
|
|
// (Sub) - Sub is handled specially below for ptr-ptr subtract.
|
|
|
|
HANDLEBINOP(Shl);
|
|
|
|
HANDLEBINOP(Shr);
|
|
|
|
HANDLEBINOP(And);
|
|
|
|
HANDLEBINOP(Xor);
|
|
|
|
HANDLEBINOP(Or);
|
|
|
|
#undef HANDLEBINOP
|
|
|
|
Value *VisitBinSub(const BinaryOperator *E);
|
2007-08-27 05:41:21 +08:00
|
|
|
Value *VisitBinSubAssign(const CompoundAssignOperator *E) {
|
2007-08-25 05:00:35 +08:00
|
|
|
return EmitCompoundAssign(E, &ScalarExprEmitter::EmitSub);
|
|
|
|
}
|
|
|
|
|
2007-08-24 13:35:26 +08:00
|
|
|
// Comparisons.
|
|
|
|
Value *EmitCompare(const BinaryOperator *E, unsigned UICmpOpc,
|
|
|
|
unsigned SICmpOpc, unsigned FCmpOpc);
|
|
|
|
#define VISITCOMP(CODE, UI, SI, FP) \
|
|
|
|
Value *VisitBin##CODE(const BinaryOperator *E) { \
|
|
|
|
return EmitCompare(E, llvm::ICmpInst::UI, llvm::ICmpInst::SI, \
|
|
|
|
llvm::FCmpInst::FP); }
|
|
|
|
VISITCOMP(LT, ICMP_ULT, ICMP_SLT, FCMP_OLT);
|
|
|
|
VISITCOMP(GT, ICMP_UGT, ICMP_SGT, FCMP_OGT);
|
|
|
|
VISITCOMP(LE, ICMP_ULE, ICMP_SLE, FCMP_OLE);
|
|
|
|
VISITCOMP(GE, ICMP_UGE, ICMP_SGE, FCMP_OGE);
|
|
|
|
VISITCOMP(EQ, ICMP_EQ , ICMP_EQ , FCMP_OEQ);
|
|
|
|
VISITCOMP(NE, ICMP_NE , ICMP_NE , FCMP_UNE);
|
|
|
|
#undef VISITCOMP
|
|
|
|
|
|
|
|
Value *VisitBinAssign (const BinaryOperator *E);
|
|
|
|
|
|
|
|
Value *VisitBinLAnd (const BinaryOperator *E);
|
|
|
|
Value *VisitBinLOr (const BinaryOperator *E);
|
|
|
|
Value *VisitBinComma (const BinaryOperator *E);
|
|
|
|
|
|
|
|
// Other Operators.
|
|
|
|
Value *VisitConditionalOperator(const ConditionalOperator *CO);
|
|
|
|
Value *VisitChooseExpr(ChooseExpr *CE);
|
2008-01-18 01:46:27 +08:00
|
|
|
Value *VisitOverloadExpr(OverloadExpr *OE);
|
2007-10-16 04:28:48 +08:00
|
|
|
Value *VisitVAArgExpr(VAArgExpr *VE);
|
2007-08-24 13:35:26 +08:00
|
|
|
Value *VisitObjCStringLiteral(const ObjCStringLiteral *E) {
|
|
|
|
return CGF.EmitObjCStringLiteral(E);
|
|
|
|
}
|
2007-10-29 13:01:08 +08:00
|
|
|
Value *VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
|
2007-08-24 13:35:26 +08:00
|
|
|
};
|
|
|
|
} // end anonymous namespace.
|
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Utilities
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2007-08-27 00:42:57 +08:00
|
|
|
/// EmitConversionToBool - Convert the specified expression value to a
|
2007-08-27 01:25:57 +08:00
|
|
|
/// boolean (i1) truth value. This is equivalent to "Val != 0".
|
2007-08-27 00:42:57 +08:00
|
|
|
Value *ScalarExprEmitter::EmitConversionToBool(Value *Src, QualType SrcType) {
|
|
|
|
assert(SrcType->isCanonical() && "EmitScalarConversion strips typedefs");
|
|
|
|
|
|
|
|
if (SrcType->isRealFloatingType()) {
|
|
|
|
// Compare against 0.0 for fp scalars.
|
|
|
|
llvm::Value *Zero = llvm::Constant::getNullValue(Src->getType());
|
|
|
|
return Builder.CreateFCmpUNE(Src, Zero, "tobool");
|
|
|
|
}
|
|
|
|
|
|
|
|
assert((SrcType->isIntegerType() || SrcType->isPointerType()) &&
|
|
|
|
"Unknown scalar type to convert");
|
|
|
|
|
|
|
|
// Because of the type rules of C, we often end up computing a logical value,
|
|
|
|
// then zero extending it to int, then wanting it as a logical value again.
|
|
|
|
// Optimize this common case.
|
|
|
|
if (llvm::ZExtInst *ZI = dyn_cast<llvm::ZExtInst>(Src)) {
|
|
|
|
if (ZI->getOperand(0)->getType() == llvm::Type::Int1Ty) {
|
|
|
|
Value *Result = ZI->getOperand(0);
|
2008-01-30 02:13:51 +08:00
|
|
|
// If there aren't any more uses, zap the instruction to save space.
|
|
|
|
// Note that there can be more uses, for example if this
|
|
|
|
// is the result of an assignment.
|
|
|
|
if (ZI->use_empty())
|
|
|
|
ZI->eraseFromParent();
|
2007-08-27 00:42:57 +08:00
|
|
|
return Result;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Compare against an integer or pointer null.
|
|
|
|
llvm::Value *Zero = llvm::Constant::getNullValue(Src->getType());
|
|
|
|
return Builder.CreateICmpNE(Src, Zero, "tobool");
|
|
|
|
}
|
|
|
|
|
2007-08-26 14:48:56 +08:00
|
|
|
/// EmitScalarConversion - Emit a conversion from the specified type to the
|
|
|
|
/// specified destination type, both of which are LLVM scalar types.
|
2007-08-27 00:34:22 +08:00
|
|
|
Value *ScalarExprEmitter::EmitScalarConversion(Value *Src, QualType SrcType,
|
|
|
|
QualType DstType) {
|
2007-08-26 14:48:56 +08:00
|
|
|
SrcType = SrcType.getCanonicalType();
|
|
|
|
DstType = DstType.getCanonicalType();
|
|
|
|
if (SrcType == DstType) return Src;
|
2007-08-26 15:21:11 +08:00
|
|
|
|
|
|
|
if (DstType->isVoidType()) return 0;
|
2007-08-26 14:48:56 +08:00
|
|
|
|
|
|
|
// Handle conversions to bool first, they are special: comparisons against 0.
|
2007-08-27 00:52:28 +08:00
|
|
|
if (DstType->isBooleanType())
|
|
|
|
return EmitConversionToBool(Src, SrcType);
|
2007-08-26 14:48:56 +08:00
|
|
|
|
|
|
|
const llvm::Type *DstTy = ConvertType(DstType);
|
|
|
|
|
|
|
|
// Ignore conversions like int -> uint.
|
|
|
|
if (Src->getType() == DstTy)
|
|
|
|
return Src;
|
|
|
|
|
|
|
|
// Handle pointer conversions next: pointers can only be converted to/from
|
|
|
|
// other pointers and integers.
|
|
|
|
if (isa<PointerType>(DstType)) {
|
|
|
|
// The source value may be an integer, or a pointer.
|
|
|
|
if (isa<llvm::PointerType>(Src->getType()))
|
|
|
|
return Builder.CreateBitCast(Src, DstTy, "conv");
|
|
|
|
assert(SrcType->isIntegerType() && "Not ptr->ptr or int->ptr conversion?");
|
|
|
|
return Builder.CreateIntToPtr(Src, DstTy, "conv");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (isa<PointerType>(SrcType)) {
|
|
|
|
// Must be an ptr to int cast.
|
|
|
|
assert(isa<llvm::IntegerType>(DstTy) && "not ptr->int?");
|
2007-11-01 07:18:02 +08:00
|
|
|
return Builder.CreatePtrToInt(Src, DstTy, "conv");
|
2007-08-26 14:48:56 +08:00
|
|
|
}
|
|
|
|
|
2008-04-19 07:10:10 +08:00
|
|
|
// A scalar can be splatted to an extended vector of the same element type
|
|
|
|
if (DstType->isExtVectorType() && !isa<VectorType>(SrcType) &&
|
2008-02-02 12:51:41 +08:00
|
|
|
cast<llvm::VectorType>(DstTy)->getElementType() == Src->getType())
|
2007-12-30 10:59:45 +08:00
|
|
|
return CGF.EmitVector(&Src, DstType->getAsVectorType()->getNumElements(),
|
|
|
|
true);
|
|
|
|
|
2008-02-02 12:51:41 +08:00
|
|
|
// Allow bitcast from vector to integer/fp of the same size.
|
2007-12-05 15:36:10 +08:00
|
|
|
if (isa<llvm::VectorType>(Src->getType()) ||
|
2008-02-02 12:51:41 +08:00
|
|
|
isa<llvm::VectorType>(DstTy))
|
2007-12-05 15:36:10 +08:00
|
|
|
return Builder.CreateBitCast(Src, DstTy, "conv");
|
|
|
|
|
2007-08-26 14:48:56 +08:00
|
|
|
// Finally, we have the arithmetic types: real int/float.
|
|
|
|
if (isa<llvm::IntegerType>(Src->getType())) {
|
|
|
|
bool InputSigned = SrcType->isSignedIntegerType();
|
2007-12-27 02:20:19 +08:00
|
|
|
if (isa<llvm::IntegerType>(DstTy))
|
|
|
|
return Builder.CreateIntCast(Src, DstTy, InputSigned, "conv");
|
|
|
|
else if (InputSigned)
|
|
|
|
return Builder.CreateSIToFP(Src, DstTy, "conv");
|
|
|
|
else
|
|
|
|
return Builder.CreateUIToFP(Src, DstTy, "conv");
|
2007-08-26 14:48:56 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
assert(Src->getType()->isFloatingPoint() && "Unknown real conversion");
|
|
|
|
if (isa<llvm::IntegerType>(DstTy)) {
|
2007-12-27 02:20:19 +08:00
|
|
|
if (DstType->isSignedIntegerType())
|
|
|
|
return Builder.CreateFPToSI(Src, DstTy, "conv");
|
|
|
|
else
|
|
|
|
return Builder.CreateFPToUI(Src, DstTy, "conv");
|
2007-08-26 14:48:56 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
assert(DstTy->isFloatingPoint() && "Unknown real conversion");
|
2007-12-27 02:20:19 +08:00
|
|
|
if (DstTy->getTypeID() < Src->getType()->getTypeID())
|
|
|
|
return Builder.CreateFPTrunc(Src, DstTy, "conv");
|
|
|
|
else
|
|
|
|
return Builder.CreateFPExt(Src, DstTy, "conv");
|
2007-08-26 14:48:56 +08:00
|
|
|
}
|
|
|
|
|
2007-08-27 00:34:22 +08:00
|
|
|
/// EmitComplexToScalarConversion - Emit a conversion from the specified
|
|
|
|
/// complex type to the specified destination type, where the destination
|
|
|
|
/// type is an LLVM scalar type.
|
|
|
|
Value *ScalarExprEmitter::
|
|
|
|
EmitComplexToScalarConversion(CodeGenFunction::ComplexPairTy Src,
|
|
|
|
QualType SrcTy, QualType DstTy) {
|
2007-08-27 00:52:28 +08:00
|
|
|
// Get the source element type.
|
|
|
|
SrcTy = cast<ComplexType>(SrcTy.getCanonicalType())->getElementType();
|
|
|
|
|
|
|
|
// Handle conversions to bool first, they are special: comparisons against 0.
|
|
|
|
if (DstTy->isBooleanType()) {
|
|
|
|
// Complex != 0 -> (Real != 0) | (Imag != 0)
|
|
|
|
Src.first = EmitScalarConversion(Src.first, SrcTy, DstTy);
|
|
|
|
Src.second = EmitScalarConversion(Src.second, SrcTy, DstTy);
|
|
|
|
return Builder.CreateOr(Src.first, Src.second, "tobool");
|
|
|
|
}
|
|
|
|
|
2007-08-27 00:34:22 +08:00
|
|
|
// C99 6.3.1.7p2: "When a value of complex type is converted to a real type,
|
|
|
|
// the imaginary part of the complex value is discarded and the value of the
|
|
|
|
// real part is converted according to the conversion rules for the
|
|
|
|
// corresponding real type.
|
|
|
|
return EmitScalarConversion(Src.first, SrcTy, DstTy);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-08-24 13:35:26 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Visitor Methods
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
Value *ScalarExprEmitter::VisitExpr(Expr *E) {
|
2007-12-02 09:49:16 +08:00
|
|
|
CGF.WarnUnsupported(E, "scalar expression");
|
2007-08-24 13:35:26 +08:00
|
|
|
if (E->getType()->isVoidType())
|
|
|
|
return 0;
|
|
|
|
return llvm::UndefValue::get(CGF.ConvertType(E->getType()));
|
|
|
|
}
|
|
|
|
|
2008-05-15 03:38:39 +08:00
|
|
|
Value *ScalarExprEmitter::VisitShuffleVectorExpr(ShuffleVectorExpr *E) {
|
|
|
|
llvm::SmallVector<llvm::Constant*, 32> indices;
|
|
|
|
for (unsigned i = 2; i < E->getNumSubExprs(); i++) {
|
|
|
|
indices.push_back(cast<llvm::Constant>(CGF.EmitScalarExpr(E->getExpr(i))));
|
|
|
|
}
|
|
|
|
Value* V1 = CGF.EmitScalarExpr(E->getExpr(0));
|
|
|
|
Value* V2 = CGF.EmitScalarExpr(E->getExpr(1));
|
|
|
|
Value* SV = llvm::ConstantVector::get(indices.begin(), indices.size());
|
|
|
|
return Builder.CreateShuffleVector(V1, V2, SV, "shuffle");
|
|
|
|
}
|
|
|
|
|
2008-03-01 16:45:05 +08:00
|
|
|
Value *ScalarExprEmitter::VisitObjCMessageExpr(ObjCMessageExpr *E) {
|
|
|
|
// Only the lookup mechanism and first two arguments of the method
|
|
|
|
// implementation vary between runtimes. We can get the receiver and
|
|
|
|
// arguments in generic code.
|
|
|
|
|
|
|
|
// Find the receiver
|
2008-03-31 07:25:33 +08:00
|
|
|
llvm::Value *Receiver = CGF.EmitScalarExpr(E->getReceiver());
|
2008-03-01 16:45:05 +08:00
|
|
|
|
|
|
|
// Process the arguments
|
2008-03-31 07:25:33 +08:00
|
|
|
unsigned ArgC = E->getNumArgs();
|
2008-03-01 16:45:05 +08:00
|
|
|
llvm::SmallVector<llvm::Value*, 16> Args;
|
2008-03-31 07:25:33 +08:00
|
|
|
for (unsigned i = 0; i != ArgC; ++i) {
|
2008-03-01 16:45:05 +08:00
|
|
|
Expr *ArgExpr = E->getArg(i);
|
|
|
|
QualType ArgTy = ArgExpr->getType();
|
|
|
|
if (!CGF.hasAggregateLLVMType(ArgTy)) {
|
|
|
|
// Scalar argument is passed by-value.
|
|
|
|
Args.push_back(CGF.EmitScalarExpr(ArgExpr));
|
2008-04-05 00:54:41 +08:00
|
|
|
} else if (ArgTy->isAnyComplexType()) {
|
2008-03-01 16:45:05 +08:00
|
|
|
// Make a temporary alloca to pass the argument.
|
|
|
|
llvm::Value *DestMem = CGF.CreateTempAlloca(ConvertType(ArgTy));
|
|
|
|
CGF.EmitComplexExprIntoAddr(ArgExpr, DestMem, false);
|
|
|
|
Args.push_back(DestMem);
|
|
|
|
} else {
|
|
|
|
llvm::Value *DestMem = CGF.CreateTempAlloca(ConvertType(ArgTy));
|
|
|
|
CGF.EmitAggExpr(ArgExpr, DestMem, false);
|
|
|
|
Args.push_back(DestMem);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-06-01 22:13:53 +08:00
|
|
|
return Runtime->GenerateMessageSend(Builder, ConvertType(E->getType()),
|
2008-04-04 12:07:35 +08:00
|
|
|
CGF.LoadObjCSelf(),
|
2008-06-26 12:42:20 +08:00
|
|
|
Receiver, E->getSelector(),
|
2008-03-31 07:25:33 +08:00
|
|
|
&Args[0], Args.size());
|
2008-03-01 16:45:05 +08:00
|
|
|
}
|
|
|
|
|
2007-08-24 13:35:26 +08:00
|
|
|
Value *ScalarExprEmitter::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
|
|
|
|
// Emit subscript expressions in rvalue context's. For most cases, this just
|
|
|
|
// loads the lvalue formed by the subscript expr. However, we have to be
|
|
|
|
// careful, because the base of a vector subscript is occasionally an rvalue,
|
|
|
|
// so we can't get it as an lvalue.
|
|
|
|
if (!E->getBase()->getType()->isVectorType())
|
|
|
|
return EmitLoadOfLValue(E);
|
|
|
|
|
|
|
|
// Handle the vector case. The base must be a vector, the index must be an
|
|
|
|
// integer value.
|
|
|
|
Value *Base = Visit(E->getBase());
|
|
|
|
Value *Idx = Visit(E->getIdx());
|
|
|
|
|
|
|
|
// FIXME: Convert Idx to i32 type.
|
|
|
|
return Builder.CreateExtractElement(Base, Idx, "vecext");
|
|
|
|
}
|
|
|
|
|
|
|
|
/// VisitImplicitCastExpr - Implicit casts are the same as normal casts, but
|
|
|
|
/// also handle things like function to pointer-to-function decay, and array to
|
|
|
|
/// pointer decay.
|
|
|
|
Value *ScalarExprEmitter::VisitImplicitCastExpr(const ImplicitCastExpr *E) {
|
|
|
|
const Expr *Op = E->getSubExpr();
|
|
|
|
|
|
|
|
// If this is due to array->pointer conversion, emit the array expression as
|
|
|
|
// an l-value.
|
|
|
|
if (Op->getType()->isArrayType()) {
|
|
|
|
// FIXME: For now we assume that all source arrays map to LLVM arrays. This
|
|
|
|
// will not true when we add support for VLAs.
|
2007-08-27 00:34:22 +08:00
|
|
|
Value *V = EmitLValue(Op).getAddress(); // Bitfields can't be arrays.
|
2007-08-24 13:35:26 +08:00
|
|
|
|
|
|
|
assert(isa<llvm::PointerType>(V->getType()) &&
|
|
|
|
isa<llvm::ArrayType>(cast<llvm::PointerType>(V->getType())
|
|
|
|
->getElementType()) &&
|
|
|
|
"Doesn't support VLAs yet!");
|
2008-03-19 13:19:41 +08:00
|
|
|
V = Builder.CreateStructGEP(V, 0, "arraydecay");
|
2007-12-12 12:13:20 +08:00
|
|
|
|
|
|
|
// The resultant pointer type can be implicitly casted to other pointer
|
|
|
|
// types as well, for example void*.
|
|
|
|
const llvm::Type *DestPTy = ConvertType(E->getType());
|
|
|
|
assert(isa<llvm::PointerType>(DestPTy) &&
|
|
|
|
"Only expect implicit cast to pointer");
|
|
|
|
if (V->getType() != DestPTy)
|
|
|
|
V = Builder.CreateBitCast(V, DestPTy, "ptrconv");
|
|
|
|
return V;
|
|
|
|
|
2007-10-13 07:56:29 +08:00
|
|
|
} else if (E->getType()->isReferenceType()) {
|
2007-10-13 13:52:34 +08:00
|
|
|
assert(cast<ReferenceType>(E->getType().getCanonicalType())->
|
2008-04-03 01:35:06 +08:00
|
|
|
getPointeeType() ==
|
2007-10-13 13:52:34 +08:00
|
|
|
Op->getType().getCanonicalType() && "Incompatible types!");
|
2007-10-13 07:56:29 +08:00
|
|
|
|
|
|
|
return EmitLValue(Op).getAddress();
|
2007-08-24 13:35:26 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return EmitCastExpr(Op, E->getType());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// VisitCastExpr - Emit code for an explicit or implicit cast. Implicit casts
|
|
|
|
// have to handle a more broad range of conversions than explicit casts, as they
|
|
|
|
// handle things like function to ptr-to-function decay etc.
|
|
|
|
Value *ScalarExprEmitter::EmitCastExpr(const Expr *E, QualType DestTy) {
|
2007-08-26 15:26:12 +08:00
|
|
|
// Handle cases where the source is an non-complex type.
|
2008-02-17 07:55:16 +08:00
|
|
|
|
|
|
|
if (!CGF.hasAggregateLLVMType(E->getType())) {
|
2007-08-26 14:48:56 +08:00
|
|
|
Value *Src = Visit(const_cast<Expr*>(E));
|
|
|
|
|
|
|
|
// Use EmitScalarConversion to perform the conversion.
|
|
|
|
return EmitScalarConversion(Src, E->getType(), DestTy);
|
|
|
|
}
|
2008-02-17 07:55:16 +08:00
|
|
|
|
2008-04-05 00:54:41 +08:00
|
|
|
if (E->getType()->isAnyComplexType()) {
|
2008-02-17 07:55:16 +08:00
|
|
|
// Handle cases where the source is a complex type.
|
|
|
|
return EmitComplexToScalarConversion(CGF.EmitComplexExpr(E), E->getType(),
|
|
|
|
DestTy);
|
|
|
|
}
|
2007-08-26 15:16:41 +08:00
|
|
|
|
2008-02-17 07:55:16 +08:00
|
|
|
// Okay, this is a cast from an aggregate. It must be a cast to void. Just
|
|
|
|
// evaluate the result and return.
|
|
|
|
CGF.EmitAggExpr(E, 0, false);
|
|
|
|
return 0;
|
2007-08-24 13:35:26 +08:00
|
|
|
}
|
|
|
|
|
2007-09-01 06:09:40 +08:00
|
|
|
Value *ScalarExprEmitter::VisitStmtExpr(const StmtExpr *E) {
|
2007-09-01 06:49:20 +08:00
|
|
|
return CGF.EmitCompoundStmt(*E->getSubStmt(), true).getScalarVal();
|
2007-09-01 06:09:40 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-08-24 13:35:26 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Unary Operators
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
Value *ScalarExprEmitter::VisitPrePostIncDec(const UnaryOperator *E,
|
2007-08-25 00:24:49 +08:00
|
|
|
bool isInc, bool isPre) {
|
2007-08-24 13:35:26 +08:00
|
|
|
LValue LV = EmitLValue(E->getSubExpr());
|
|
|
|
// FIXME: Handle volatile!
|
2007-08-26 13:10:16 +08:00
|
|
|
Value *InVal = CGF.EmitLoadOfLValue(LV, // false
|
2007-09-01 06:49:20 +08:00
|
|
|
E->getSubExpr()->getType()).getScalarVal();
|
2007-08-24 13:35:26 +08:00
|
|
|
|
|
|
|
int AmountVal = isInc ? 1 : -1;
|
|
|
|
|
|
|
|
Value *NextVal;
|
2007-08-26 13:10:16 +08:00
|
|
|
if (isa<llvm::PointerType>(InVal->getType())) {
|
|
|
|
// FIXME: This isn't right for VLAs.
|
|
|
|
NextVal = llvm::ConstantInt::get(llvm::Type::Int32Ty, AmountVal);
|
2008-03-19 13:19:41 +08:00
|
|
|
NextVal = Builder.CreateGEP(InVal, NextVal, "ptrincdec");
|
2007-08-26 13:10:16 +08:00
|
|
|
} else {
|
|
|
|
// Add the inc/dec to the real part.
|
|
|
|
if (isa<llvm::IntegerType>(InVal->getType()))
|
|
|
|
NextVal = llvm::ConstantInt::get(InVal->getType(), AmountVal);
|
2007-09-13 14:19:18 +08:00
|
|
|
else if (InVal->getType() == llvm::Type::FloatTy)
|
2007-10-31 04:59:40 +08:00
|
|
|
NextVal =
|
2008-04-20 08:45:53 +08:00
|
|
|
llvm::ConstantFP::get(llvm::APFloat(static_cast<float>(AmountVal)));
|
2008-04-20 08:50:39 +08:00
|
|
|
else if (InVal->getType() == llvm::Type::DoubleTy)
|
2007-10-31 04:59:40 +08:00
|
|
|
NextVal =
|
2008-04-20 08:45:53 +08:00
|
|
|
llvm::ConstantFP::get(llvm::APFloat(static_cast<double>(AmountVal)));
|
2008-04-20 08:50:39 +08:00
|
|
|
else {
|
|
|
|
llvm::APFloat F(static_cast<float>(AmountVal));
|
2008-07-01 02:32:54 +08:00
|
|
|
F.convert(CGF.Target.getLongDoubleFormat(), llvm::APFloat::rmTowardZero);
|
2008-04-20 08:50:39 +08:00
|
|
|
NextVal = llvm::ConstantFP::get(F);
|
2007-09-13 14:19:18 +08:00
|
|
|
}
|
2007-08-26 13:10:16 +08:00
|
|
|
NextVal = Builder.CreateAdd(InVal, NextVal, isInc ? "inc" : "dec");
|
|
|
|
}
|
2007-08-24 13:35:26 +08:00
|
|
|
|
|
|
|
// Store the updated result through the lvalue.
|
|
|
|
CGF.EmitStoreThroughLValue(RValue::get(NextVal), LV,
|
|
|
|
E->getSubExpr()->getType());
|
|
|
|
|
|
|
|
// If this is a postinc, return the value read from memory, otherwise use the
|
|
|
|
// updated value.
|
|
|
|
return isPre ? NextVal : InVal;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Value *ScalarExprEmitter::VisitUnaryMinus(const UnaryOperator *E) {
|
|
|
|
Value *Op = Visit(E->getSubExpr());
|
|
|
|
return Builder.CreateNeg(Op, "neg");
|
|
|
|
}
|
|
|
|
|
|
|
|
Value *ScalarExprEmitter::VisitUnaryNot(const UnaryOperator *E) {
|
|
|
|
Value *Op = Visit(E->getSubExpr());
|
|
|
|
return Builder.CreateNot(Op, "neg");
|
|
|
|
}
|
|
|
|
|
|
|
|
Value *ScalarExprEmitter::VisitUnaryLNot(const UnaryOperator *E) {
|
|
|
|
// Compare operand to zero.
|
|
|
|
Value *BoolVal = CGF.EvaluateExprAsBool(E->getSubExpr());
|
|
|
|
|
|
|
|
// Invert value.
|
|
|
|
// TODO: Could dynamically modify easy computations here. For example, if
|
|
|
|
// the operand is an icmp ne, turn into icmp eq.
|
|
|
|
BoolVal = Builder.CreateNot(BoolVal, "lnot");
|
|
|
|
|
|
|
|
// ZExt result to int.
|
|
|
|
return Builder.CreateZExt(BoolVal, CGF.LLVMIntTy, "lnot.ext");
|
|
|
|
}
|
|
|
|
|
|
|
|
/// EmitSizeAlignOf - Return the size or alignment of the 'TypeToSize' type as
|
|
|
|
/// an integer (RetType).
|
|
|
|
Value *ScalarExprEmitter::EmitSizeAlignOf(QualType TypeToSize,
|
2007-08-25 05:20:17 +08:00
|
|
|
QualType RetType,bool isSizeOf){
|
2008-02-21 13:45:29 +08:00
|
|
|
assert(RetType->isIntegerType() && "Result type must be an integer!");
|
|
|
|
uint32_t ResultWidth =
|
2008-03-06 02:54:05 +08:00
|
|
|
static_cast<uint32_t>(CGF.getContext().getTypeSize(RetType));
|
2008-02-21 13:45:29 +08:00
|
|
|
|
2008-07-22 09:35:47 +08:00
|
|
|
// sizeof(void) and __alignof__(void) = 1 as a gcc extension. Also
|
|
|
|
// for function types.
|
2008-07-23 03:44:18 +08:00
|
|
|
// FIXME: what is alignof a function type in gcc?
|
2008-07-22 09:35:47 +08:00
|
|
|
if (TypeToSize->isVoidType() || TypeToSize->isFunctionType())
|
2008-02-21 13:45:29 +08:00
|
|
|
return llvm::ConstantInt::get(llvm::APInt(ResultWidth, 1));
|
|
|
|
|
2007-08-24 13:35:26 +08:00
|
|
|
/// FIXME: This doesn't handle VLAs yet!
|
2008-03-06 02:54:05 +08:00
|
|
|
std::pair<uint64_t, unsigned> Info = CGF.getContext().getTypeInfo(TypeToSize);
|
2007-08-24 13:35:26 +08:00
|
|
|
|
|
|
|
uint64_t Val = isSizeOf ? Info.first : Info.second;
|
|
|
|
Val /= 8; // Return size in bytes, not bits.
|
|
|
|
|
|
|
|
return llvm::ConstantInt::get(llvm::APInt(ResultWidth, Val));
|
|
|
|
}
|
|
|
|
|
2007-08-25 05:20:17 +08:00
|
|
|
Value *ScalarExprEmitter::VisitUnaryReal(const UnaryOperator *E) {
|
|
|
|
Expr *Op = E->getSubExpr();
|
2008-04-05 00:54:41 +08:00
|
|
|
if (Op->getType()->isAnyComplexType())
|
2007-08-25 05:20:17 +08:00
|
|
|
return CGF.EmitComplexExpr(Op).first;
|
|
|
|
return Visit(Op);
|
|
|
|
}
|
|
|
|
Value *ScalarExprEmitter::VisitUnaryImag(const UnaryOperator *E) {
|
|
|
|
Expr *Op = E->getSubExpr();
|
2008-04-05 00:54:41 +08:00
|
|
|
if (Op->getType()->isAnyComplexType())
|
2007-08-25 05:20:17 +08:00
|
|
|
return CGF.EmitComplexExpr(Op).second;
|
2007-08-26 13:29:21 +08:00
|
|
|
|
|
|
|
// __imag on a scalar returns zero. Emit it the subexpr to ensure side
|
|
|
|
// effects are evaluated.
|
|
|
|
CGF.EmitScalarExpr(Op);
|
|
|
|
return llvm::Constant::getNullValue(ConvertType(E->getType()));
|
2007-08-25 05:20:17 +08:00
|
|
|
}
|
|
|
|
|
2008-01-29 23:56:48 +08:00
|
|
|
Value *ScalarExprEmitter::VisitUnaryOffsetOf(const UnaryOperator *E)
|
|
|
|
{
|
|
|
|
int64_t Val = E->evaluateOffsetOf(CGF.getContext());
|
|
|
|
|
|
|
|
assert(E->getType()->isIntegerType() && "Result type must be an integer!");
|
|
|
|
|
2008-03-06 02:54:05 +08:00
|
|
|
uint32_t ResultWidth =
|
|
|
|
static_cast<uint32_t>(CGF.getContext().getTypeSize(E->getType()));
|
2008-01-29 23:56:48 +08:00
|
|
|
return llvm::ConstantInt::get(llvm::APInt(ResultWidth, Val));
|
|
|
|
}
|
2007-08-25 05:20:17 +08:00
|
|
|
|
2007-08-24 13:35:26 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Binary Operators
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
BinOpInfo ScalarExprEmitter::EmitBinOps(const BinaryOperator *E) {
|
|
|
|
BinOpInfo Result;
|
|
|
|
Result.LHS = Visit(E->getLHS());
|
|
|
|
Result.RHS = Visit(E->getRHS());
|
2007-08-25 05:00:35 +08:00
|
|
|
Result.Ty = E->getType();
|
2007-08-24 13:35:26 +08:00
|
|
|
Result.E = E;
|
|
|
|
return Result;
|
|
|
|
}
|
|
|
|
|
2007-08-27 05:41:21 +08:00
|
|
|
Value *ScalarExprEmitter::EmitCompoundAssign(const CompoundAssignOperator *E,
|
2007-08-25 05:00:35 +08:00
|
|
|
Value *(ScalarExprEmitter::*Func)(const BinOpInfo &)) {
|
|
|
|
QualType LHSTy = E->getLHS()->getType(), RHSTy = E->getRHS()->getType();
|
|
|
|
|
|
|
|
BinOpInfo OpInfo;
|
|
|
|
|
|
|
|
// Load the LHS and RHS operands.
|
|
|
|
LValue LHSLV = EmitLValue(E->getLHS());
|
|
|
|
OpInfo.LHS = EmitLoadOfLValue(LHSLV, LHSTy);
|
2007-08-27 06:37:40 +08:00
|
|
|
|
|
|
|
// Determine the computation type. If the RHS is complex, then this is one of
|
|
|
|
// the add/sub/mul/div operators. All of these operators can be computed in
|
|
|
|
// with just their real component even though the computation domain really is
|
|
|
|
// complex.
|
|
|
|
QualType ComputeType = E->getComputationType();
|
2007-08-25 05:00:35 +08:00
|
|
|
|
2007-08-27 06:37:40 +08:00
|
|
|
// If the computation type is complex, then the RHS is complex. Emit the RHS.
|
|
|
|
if (const ComplexType *CT = ComputeType->getAsComplexType()) {
|
|
|
|
ComputeType = CT->getElementType();
|
|
|
|
|
|
|
|
// Emit the RHS, only keeping the real component.
|
|
|
|
OpInfo.RHS = CGF.EmitComplexExpr(E->getRHS()).first;
|
|
|
|
RHSTy = RHSTy->getAsComplexType()->getElementType();
|
|
|
|
} else {
|
|
|
|
// Otherwise the RHS is a simple scalar value.
|
|
|
|
OpInfo.RHS = Visit(E->getRHS());
|
|
|
|
}
|
2007-08-25 05:00:35 +08:00
|
|
|
|
|
|
|
// Convert the LHS/RHS values to the computation type.
|
2007-08-26 15:08:39 +08:00
|
|
|
OpInfo.LHS = EmitScalarConversion(OpInfo.LHS, LHSTy, ComputeType);
|
2007-08-25 05:00:35 +08:00
|
|
|
|
2007-10-26 06:19:13 +08:00
|
|
|
// Do not merge types for -= or += where the LHS is a pointer.
|
|
|
|
if (!(E->getOpcode() == BinaryOperator::SubAssign ||
|
2007-10-31 02:31:12 +08:00
|
|
|
E->getOpcode() == BinaryOperator::AddAssign) ||
|
2007-08-26 05:56:20 +08:00
|
|
|
!E->getLHS()->getType()->isPointerType()) {
|
2007-08-26 15:08:39 +08:00
|
|
|
OpInfo.RHS = EmitScalarConversion(OpInfo.RHS, RHSTy, ComputeType);
|
2007-08-25 05:00:35 +08:00
|
|
|
}
|
|
|
|
OpInfo.Ty = ComputeType;
|
|
|
|
OpInfo.E = E;
|
|
|
|
|
|
|
|
// Expand the binary operator.
|
|
|
|
Value *Result = (this->*Func)(OpInfo);
|
|
|
|
|
|
|
|
// Truncate the result back to the LHS type.
|
2007-08-26 15:08:39 +08:00
|
|
|
Result = EmitScalarConversion(Result, ComputeType, LHSTy);
|
2007-08-25 05:00:35 +08:00
|
|
|
|
|
|
|
// Store the result value into the LHS lvalue.
|
|
|
|
CGF.EmitStoreThroughLValue(RValue::get(Result), LHSLV, E->getType());
|
|
|
|
|
2008-05-25 22:13:57 +08:00
|
|
|
// For bitfields, we need the value in the bitfield
|
|
|
|
// FIXME: This adds an extra bitfield load
|
|
|
|
if (LHSLV.isBitfield())
|
|
|
|
Result = EmitLoadOfLValue(LHSLV, LHSTy);
|
|
|
|
|
2007-08-25 05:00:35 +08:00
|
|
|
return Result;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-08-24 13:35:26 +08:00
|
|
|
Value *ScalarExprEmitter::EmitDiv(const BinOpInfo &Ops) {
|
2007-12-30 09:28:16 +08:00
|
|
|
if (Ops.LHS->getType()->isFPOrFPVector())
|
2007-08-24 13:35:26 +08:00
|
|
|
return Builder.CreateFDiv(Ops.LHS, Ops.RHS, "div");
|
2007-08-25 05:00:35 +08:00
|
|
|
else if (Ops.Ty->isUnsignedIntegerType())
|
2007-08-24 13:35:26 +08:00
|
|
|
return Builder.CreateUDiv(Ops.LHS, Ops.RHS, "div");
|
|
|
|
else
|
|
|
|
return Builder.CreateSDiv(Ops.LHS, Ops.RHS, "div");
|
|
|
|
}
|
|
|
|
|
|
|
|
Value *ScalarExprEmitter::EmitRem(const BinOpInfo &Ops) {
|
|
|
|
// Rem in C can't be a floating point type: C99 6.5.5p2.
|
2007-08-25 05:00:35 +08:00
|
|
|
if (Ops.Ty->isUnsignedIntegerType())
|
2007-08-24 13:35:26 +08:00
|
|
|
return Builder.CreateURem(Ops.LHS, Ops.RHS, "rem");
|
|
|
|
else
|
|
|
|
return Builder.CreateSRem(Ops.LHS, Ops.RHS, "rem");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Value *ScalarExprEmitter::EmitAdd(const BinOpInfo &Ops) {
|
2007-08-25 05:00:35 +08:00
|
|
|
if (!Ops.Ty->isPointerType())
|
2007-08-24 13:35:26 +08:00
|
|
|
return Builder.CreateAdd(Ops.LHS, Ops.RHS, "add");
|
2007-08-25 05:00:35 +08:00
|
|
|
|
|
|
|
// FIXME: What about a pointer to a VLA?
|
2008-01-03 14:36:51 +08:00
|
|
|
Value *Ptr, *Idx;
|
|
|
|
Expr *IdxExp;
|
|
|
|
if (isa<llvm::PointerType>(Ops.LHS->getType())) { // pointer + int
|
|
|
|
Ptr = Ops.LHS;
|
|
|
|
Idx = Ops.RHS;
|
|
|
|
IdxExp = Ops.E->getRHS();
|
|
|
|
} else { // int + pointer
|
|
|
|
Ptr = Ops.RHS;
|
|
|
|
Idx = Ops.LHS;
|
|
|
|
IdxExp = Ops.E->getLHS();
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned Width = cast<llvm::IntegerType>(Idx->getType())->getBitWidth();
|
|
|
|
if (Width < CGF.LLVMPointerWidth) {
|
|
|
|
// Zero or sign extend the pointer value based on whether the index is
|
|
|
|
// signed or not.
|
|
|
|
const llvm::Type *IdxType = llvm::IntegerType::get(CGF.LLVMPointerWidth);
|
|
|
|
if (IdxExp->getType().getCanonicalType()->isSignedIntegerType())
|
|
|
|
Idx = Builder.CreateSExt(Idx, IdxType, "idx.ext");
|
|
|
|
else
|
|
|
|
Idx = Builder.CreateZExt(Idx, IdxType, "idx.ext");
|
|
|
|
}
|
|
|
|
|
|
|
|
return Builder.CreateGEP(Ptr, Idx, "add.ptr");
|
2007-08-24 13:35:26 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
Value *ScalarExprEmitter::EmitSub(const BinOpInfo &Ops) {
|
|
|
|
if (!isa<llvm::PointerType>(Ops.LHS->getType()))
|
|
|
|
return Builder.CreateSub(Ops.LHS, Ops.RHS, "sub");
|
|
|
|
|
2007-08-25 05:00:35 +08:00
|
|
|
// pointer - int
|
|
|
|
assert(!isa<llvm::PointerType>(Ops.RHS->getType()) &&
|
|
|
|
"ptr-ptr shouldn't get here");
|
|
|
|
// FIXME: The pointer could point to a VLA.
|
2008-01-31 12:12:50 +08:00
|
|
|
Value *Idx = Builder.CreateNeg(Ops.RHS, "sub.ptr.neg");
|
|
|
|
|
|
|
|
unsigned Width = cast<llvm::IntegerType>(Idx->getType())->getBitWidth();
|
|
|
|
if (Width < CGF.LLVMPointerWidth) {
|
|
|
|
// Zero or sign extend the pointer value based on whether the index is
|
|
|
|
// signed or not.
|
|
|
|
const llvm::Type *IdxType = llvm::IntegerType::get(CGF.LLVMPointerWidth);
|
|
|
|
if (Ops.E->getRHS()->getType().getCanonicalType()->isSignedIntegerType())
|
|
|
|
Idx = Builder.CreateSExt(Idx, IdxType, "idx.ext");
|
|
|
|
else
|
|
|
|
Idx = Builder.CreateZExt(Idx, IdxType, "idx.ext");
|
|
|
|
}
|
|
|
|
|
|
|
|
return Builder.CreateGEP(Ops.LHS, Idx, "sub.ptr");
|
2007-08-25 05:00:35 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
Value *ScalarExprEmitter::VisitBinSub(const BinaryOperator *E) {
|
|
|
|
// "X - Y" is different from "X -= Y" in one case: when Y is a pointer. In
|
|
|
|
// the compound assignment case it is invalid, so just handle it here.
|
|
|
|
if (!E->getRHS()->getType()->isPointerType())
|
|
|
|
return EmitSub(EmitBinOps(E));
|
2007-08-24 13:35:26 +08:00
|
|
|
|
|
|
|
// pointer - pointer
|
2007-08-25 05:00:35 +08:00
|
|
|
Value *LHS = Visit(E->getLHS());
|
|
|
|
Value *RHS = Visit(E->getRHS());
|
|
|
|
|
2007-12-03 14:23:43 +08:00
|
|
|
const QualType LHSType = E->getLHS()->getType().getCanonicalType();
|
2007-12-26 13:21:37 +08:00
|
|
|
const QualType LHSElementType = cast<PointerType>(LHSType)->getPointeeType();
|
2008-03-06 02:54:05 +08:00
|
|
|
uint64_t ElementSize = CGF.getContext().getTypeSize(LHSElementType) / 8;
|
2007-08-25 05:00:35 +08:00
|
|
|
|
|
|
|
const llvm::Type *ResultType = ConvertType(E->getType());
|
|
|
|
LHS = Builder.CreatePtrToInt(LHS, ResultType, "sub.ptr.lhs.cast");
|
|
|
|
RHS = Builder.CreatePtrToInt(RHS, ResultType, "sub.ptr.rhs.cast");
|
|
|
|
Value *BytesBetween = Builder.CreateSub(LHS, RHS, "sub.ptr.sub");
|
2007-08-24 13:35:26 +08:00
|
|
|
|
|
|
|
// HACK: LLVM doesn't have an divide instruction that 'knows' there is no
|
|
|
|
// remainder. As such, we handle common power-of-two cases here to generate
|
|
|
|
// better code.
|
|
|
|
if (llvm::isPowerOf2_64(ElementSize)) {
|
|
|
|
Value *ShAmt =
|
|
|
|
llvm::ConstantInt::get(ResultType, llvm::Log2_64(ElementSize));
|
|
|
|
return Builder.CreateAShr(BytesBetween, ShAmt, "sub.ptr.shr");
|
|
|
|
}
|
2007-08-25 05:00:35 +08:00
|
|
|
|
2007-08-24 13:35:26 +08:00
|
|
|
// Otherwise, do a full sdiv.
|
|
|
|
Value *BytesPerElt = llvm::ConstantInt::get(ResultType, ElementSize);
|
|
|
|
return Builder.CreateSDiv(BytesBetween, BytesPerElt, "sub.ptr.div");
|
|
|
|
}
|
|
|
|
|
2007-08-25 05:00:35 +08:00
|
|
|
|
2007-08-24 13:35:26 +08:00
|
|
|
Value *ScalarExprEmitter::EmitShl(const BinOpInfo &Ops) {
|
|
|
|
// LLVM requires the LHS and RHS to be the same type: promote or truncate the
|
|
|
|
// RHS to the same size as the LHS.
|
|
|
|
Value *RHS = Ops.RHS;
|
|
|
|
if (Ops.LHS->getType() != RHS->getType())
|
|
|
|
RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(), false, "sh_prom");
|
|
|
|
|
|
|
|
return Builder.CreateShl(Ops.LHS, RHS, "shl");
|
|
|
|
}
|
|
|
|
|
|
|
|
Value *ScalarExprEmitter::EmitShr(const BinOpInfo &Ops) {
|
|
|
|
// LLVM requires the LHS and RHS to be the same type: promote or truncate the
|
|
|
|
// RHS to the same size as the LHS.
|
|
|
|
Value *RHS = Ops.RHS;
|
|
|
|
if (Ops.LHS->getType() != RHS->getType())
|
|
|
|
RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(), false, "sh_prom");
|
|
|
|
|
2007-08-25 05:00:35 +08:00
|
|
|
if (Ops.Ty->isUnsignedIntegerType())
|
2007-08-24 13:35:26 +08:00
|
|
|
return Builder.CreateLShr(Ops.LHS, RHS, "shr");
|
|
|
|
return Builder.CreateAShr(Ops.LHS, RHS, "shr");
|
|
|
|
}
|
|
|
|
|
|
|
|
Value *ScalarExprEmitter::EmitCompare(const BinaryOperator *E,unsigned UICmpOpc,
|
|
|
|
unsigned SICmpOpc, unsigned FCmpOpc) {
|
2007-08-27 00:34:22 +08:00
|
|
|
Value *Result;
|
2007-08-24 13:35:26 +08:00
|
|
|
QualType LHSTy = E->getLHS()->getType();
|
2008-04-05 00:54:41 +08:00
|
|
|
if (!LHSTy->isAnyComplexType()) {
|
2007-08-24 13:35:26 +08:00
|
|
|
Value *LHS = Visit(E->getLHS());
|
|
|
|
Value *RHS = Visit(E->getRHS());
|
|
|
|
|
|
|
|
if (LHS->getType()->isFloatingPoint()) {
|
|
|
|
Result = Builder.CreateFCmp((llvm::FCmpInst::Predicate)FCmpOpc,
|
|
|
|
LHS, RHS, "cmp");
|
2008-05-29 23:09:15 +08:00
|
|
|
} else if (LHSTy->isSignedIntegerType()) {
|
|
|
|
Result = Builder.CreateICmp((llvm::ICmpInst::Predicate)SICmpOpc,
|
2007-08-24 13:35:26 +08:00
|
|
|
LHS, RHS, "cmp");
|
|
|
|
} else {
|
2008-05-29 23:09:15 +08:00
|
|
|
// Unsigned integers and pointers.
|
|
|
|
Result = Builder.CreateICmp((llvm::ICmpInst::Predicate)UICmpOpc,
|
2007-08-24 13:35:26 +08:00
|
|
|
LHS, RHS, "cmp");
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// Complex Comparison: can only be an equality comparison.
|
|
|
|
CodeGenFunction::ComplexPairTy LHS = CGF.EmitComplexExpr(E->getLHS());
|
|
|
|
CodeGenFunction::ComplexPairTy RHS = CGF.EmitComplexExpr(E->getRHS());
|
|
|
|
|
|
|
|
QualType CETy =
|
|
|
|
cast<ComplexType>(LHSTy.getCanonicalType())->getElementType();
|
|
|
|
|
2007-08-27 00:34:22 +08:00
|
|
|
Value *ResultR, *ResultI;
|
2007-08-24 13:35:26 +08:00
|
|
|
if (CETy->isRealFloatingType()) {
|
|
|
|
ResultR = Builder.CreateFCmp((llvm::FCmpInst::Predicate)FCmpOpc,
|
|
|
|
LHS.first, RHS.first, "cmp.r");
|
|
|
|
ResultI = Builder.CreateFCmp((llvm::FCmpInst::Predicate)FCmpOpc,
|
|
|
|
LHS.second, RHS.second, "cmp.i");
|
|
|
|
} else {
|
|
|
|
// Complex comparisons can only be equality comparisons. As such, signed
|
|
|
|
// and unsigned opcodes are the same.
|
|
|
|
ResultR = Builder.CreateICmp((llvm::ICmpInst::Predicate)UICmpOpc,
|
|
|
|
LHS.first, RHS.first, "cmp.r");
|
|
|
|
ResultI = Builder.CreateICmp((llvm::ICmpInst::Predicate)UICmpOpc,
|
|
|
|
LHS.second, RHS.second, "cmp.i");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (E->getOpcode() == BinaryOperator::EQ) {
|
|
|
|
Result = Builder.CreateAnd(ResultR, ResultI, "and.ri");
|
|
|
|
} else {
|
|
|
|
assert(E->getOpcode() == BinaryOperator::NE &&
|
|
|
|
"Complex comparison other than == or != ?");
|
|
|
|
Result = Builder.CreateOr(ResultR, ResultI, "or.ri");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// ZExt result to int.
|
|
|
|
return Builder.CreateZExt(Result, CGF.LLVMIntTy, "cmp.ext");
|
|
|
|
}
|
|
|
|
|
|
|
|
Value *ScalarExprEmitter::VisitBinAssign(const BinaryOperator *E) {
|
|
|
|
LValue LHS = EmitLValue(E->getLHS());
|
|
|
|
Value *RHS = Visit(E->getRHS());
|
|
|
|
|
|
|
|
// Store the value into the LHS.
|
|
|
|
// FIXME: Volatility!
|
|
|
|
CGF.EmitStoreThroughLValue(RValue::get(RHS), LHS, E->getType());
|
2008-05-25 22:13:57 +08:00
|
|
|
|
|
|
|
// For bitfields, we need the value in the bitfield
|
|
|
|
// FIXME: This adds an extra bitfield load
|
|
|
|
if (LHS.isBitfield())
|
|
|
|
return EmitLoadOfLValue(LHS, E->getLHS()->getType());
|
2007-08-24 13:35:26 +08:00
|
|
|
// Return the RHS.
|
|
|
|
return RHS;
|
|
|
|
}
|
|
|
|
|
|
|
|
Value *ScalarExprEmitter::VisitBinLAnd(const BinaryOperator *E) {
|
|
|
|
Value *LHSCond = CGF.EvaluateExprAsBool(E->getLHS());
|
|
|
|
|
2008-04-07 04:42:52 +08:00
|
|
|
llvm::BasicBlock *ContBlock = llvm::BasicBlock::Create("land_cont");
|
|
|
|
llvm::BasicBlock *RHSBlock = llvm::BasicBlock::Create("land_rhs");
|
2007-08-24 13:35:26 +08:00
|
|
|
|
|
|
|
llvm::BasicBlock *OrigBlock = Builder.GetInsertBlock();
|
|
|
|
Builder.CreateCondBr(LHSCond, RHSBlock, ContBlock);
|
|
|
|
|
|
|
|
CGF.EmitBlock(RHSBlock);
|
|
|
|
Value *RHSCond = CGF.EvaluateExprAsBool(E->getRHS());
|
|
|
|
|
|
|
|
// Reaquire the RHS block, as there may be subblocks inserted.
|
|
|
|
RHSBlock = Builder.GetInsertBlock();
|
|
|
|
CGF.EmitBlock(ContBlock);
|
|
|
|
|
|
|
|
// Create a PHI node. If we just evaluted the LHS condition, the result is
|
|
|
|
// false. If we evaluated both, the result is the RHS condition.
|
|
|
|
llvm::PHINode *PN = Builder.CreatePHI(llvm::Type::Int1Ty, "land");
|
|
|
|
PN->reserveOperandSpace(2);
|
|
|
|
PN->addIncoming(llvm::ConstantInt::getFalse(), OrigBlock);
|
|
|
|
PN->addIncoming(RHSCond, RHSBlock);
|
|
|
|
|
|
|
|
// ZExt result to int.
|
|
|
|
return Builder.CreateZExt(PN, CGF.LLVMIntTy, "land.ext");
|
|
|
|
}
|
|
|
|
|
|
|
|
Value *ScalarExprEmitter::VisitBinLOr(const BinaryOperator *E) {
|
|
|
|
Value *LHSCond = CGF.EvaluateExprAsBool(E->getLHS());
|
|
|
|
|
2008-04-07 04:42:52 +08:00
|
|
|
llvm::BasicBlock *ContBlock = llvm::BasicBlock::Create("lor_cont");
|
|
|
|
llvm::BasicBlock *RHSBlock = llvm::BasicBlock::Create("lor_rhs");
|
2007-08-24 13:35:26 +08:00
|
|
|
|
|
|
|
llvm::BasicBlock *OrigBlock = Builder.GetInsertBlock();
|
|
|
|
Builder.CreateCondBr(LHSCond, ContBlock, RHSBlock);
|
|
|
|
|
|
|
|
CGF.EmitBlock(RHSBlock);
|
|
|
|
Value *RHSCond = CGF.EvaluateExprAsBool(E->getRHS());
|
|
|
|
|
|
|
|
// Reaquire the RHS block, as there may be subblocks inserted.
|
|
|
|
RHSBlock = Builder.GetInsertBlock();
|
|
|
|
CGF.EmitBlock(ContBlock);
|
|
|
|
|
|
|
|
// Create a PHI node. If we just evaluted the LHS condition, the result is
|
|
|
|
// true. If we evaluated both, the result is the RHS condition.
|
|
|
|
llvm::PHINode *PN = Builder.CreatePHI(llvm::Type::Int1Ty, "lor");
|
|
|
|
PN->reserveOperandSpace(2);
|
|
|
|
PN->addIncoming(llvm::ConstantInt::getTrue(), OrigBlock);
|
|
|
|
PN->addIncoming(RHSCond, RHSBlock);
|
|
|
|
|
|
|
|
// ZExt result to int.
|
|
|
|
return Builder.CreateZExt(PN, CGF.LLVMIntTy, "lor.ext");
|
|
|
|
}
|
|
|
|
|
|
|
|
Value *ScalarExprEmitter::VisitBinComma(const BinaryOperator *E) {
|
|
|
|
CGF.EmitStmt(E->getLHS());
|
|
|
|
return Visit(E->getRHS());
|
|
|
|
}
|
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Other Operators
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
Value *ScalarExprEmitter::
|
|
|
|
VisitConditionalOperator(const ConditionalOperator *E) {
|
2008-04-07 04:42:52 +08:00
|
|
|
llvm::BasicBlock *LHSBlock = llvm::BasicBlock::Create("cond.?");
|
|
|
|
llvm::BasicBlock *RHSBlock = llvm::BasicBlock::Create("cond.:");
|
|
|
|
llvm::BasicBlock *ContBlock = llvm::BasicBlock::Create("cond.cont");
|
2007-08-24 13:35:26 +08:00
|
|
|
|
2007-11-26 09:40:58 +08:00
|
|
|
// Evaluate the conditional, then convert it to bool. We do this explicitly
|
|
|
|
// because we need the unconverted value if this is a GNU ?: expression with
|
|
|
|
// missing middle value.
|
|
|
|
Value *CondVal = CGF.EmitScalarExpr(E->getCond());
|
2008-01-03 15:05:49 +08:00
|
|
|
Value *CondBoolVal =CGF.EmitScalarConversion(CondVal, E->getCond()->getType(),
|
|
|
|
CGF.getContext().BoolTy);
|
2007-11-26 09:40:58 +08:00
|
|
|
Builder.CreateCondBr(CondBoolVal, LHSBlock, RHSBlock);
|
2007-08-24 13:35:26 +08:00
|
|
|
|
|
|
|
CGF.EmitBlock(LHSBlock);
|
|
|
|
|
|
|
|
// Handle the GNU extension for missing LHS.
|
2007-11-26 09:40:58 +08:00
|
|
|
Value *LHS;
|
|
|
|
if (E->getLHS())
|
2008-05-17 04:38:39 +08:00
|
|
|
LHS = Visit(E->getLHS());
|
2007-11-26 09:40:58 +08:00
|
|
|
else // Perform promotions, to handle cases like "short ?: int"
|
|
|
|
LHS = EmitScalarConversion(CondVal, E->getCond()->getType(), E->getType());
|
|
|
|
|
2007-08-24 13:35:26 +08:00
|
|
|
Builder.CreateBr(ContBlock);
|
|
|
|
LHSBlock = Builder.GetInsertBlock();
|
|
|
|
|
|
|
|
CGF.EmitBlock(RHSBlock);
|
|
|
|
|
2008-05-17 04:38:39 +08:00
|
|
|
Value *RHS = Visit(E->getRHS());
|
2007-08-24 13:35:26 +08:00
|
|
|
Builder.CreateBr(ContBlock);
|
|
|
|
RHSBlock = Builder.GetInsertBlock();
|
|
|
|
|
|
|
|
CGF.EmitBlock(ContBlock);
|
|
|
|
|
2008-06-05 03:15:45 +08:00
|
|
|
if (!LHS || !RHS) {
|
2007-12-01 01:56:23 +08:00
|
|
|
assert(E->getType()->isVoidType() && "Non-void value should have a value");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2007-08-24 13:35:26 +08:00
|
|
|
// Create a PHI node for the real part.
|
|
|
|
llvm::PHINode *PN = Builder.CreatePHI(LHS->getType(), "cond");
|
|
|
|
PN->reserveOperandSpace(2);
|
|
|
|
PN->addIncoming(LHS, LHSBlock);
|
|
|
|
PN->addIncoming(RHS, RHSBlock);
|
|
|
|
return PN;
|
|
|
|
}
|
|
|
|
|
|
|
|
Value *ScalarExprEmitter::VisitChooseExpr(ChooseExpr *E) {
|
|
|
|
// Emit the LHS or RHS as appropriate.
|
2007-10-31 04:59:40 +08:00
|
|
|
return
|
|
|
|
Visit(E->isConditionTrue(CGF.getContext()) ? E->getLHS() : E->getRHS());
|
2007-08-24 13:35:26 +08:00
|
|
|
}
|
|
|
|
|
2008-01-18 01:46:27 +08:00
|
|
|
Value *ScalarExprEmitter::VisitOverloadExpr(OverloadExpr *E) {
|
2008-01-31 04:50:20 +08:00
|
|
|
return CGF.EmitCallExpr(E->getFn(), E->arg_begin(),
|
This patch is motivated by numerous strict-aliasing warnings when compiling
clang as a Release build.
The big change is that all AST nodes (subclasses of Stmt) whose children are
Expr* store their children as Stmt* or arrays of Stmt*. This is to remove
strict-aliasing warnings when using StmtIterator. None of the interfaces of any
of the classes have changed (except those with arg_iterators, see below), as the
accessor methods introduce the needed casts (via cast<>). While this extra
casting may seem cumbersome, it actually adds some important sanity checks
throughout the codebase, as clients using StmtIterator can potentially overwrite
children that are expected to be Expr* with Stmt* (that aren't Expr*). The casts
provide extra sanity checks that are operational in debug builds to catch
invariant violations such as these.
For classes that have arg_iterators (e.g., CallExpr), the definition of
arg_iterator has been replaced. Instead of it being Expr**, it is an actual
class (called ExprIterator) that wraps a Stmt**, and provides the necessary
operators for iteration. The nice thing about this class is that it also uses
cast<> to type-checking, which introduces extra sanity checks throughout the
codebase that are useful for debugging.
A few of the CodeGen functions that use arg_iterator (especially from
OverloadExpr) have been modified to take begin and end iterators instead of a
base Expr** and the number of arguments. This matches more with the abstraction
of iteration. This still needs to be cleaned up a little bit, as clients expect
that ExprIterator is a RandomAccessIterator (which we may or may not wish to
allow for efficiency of representation).
This is a fairly large patch. It passes the tests (except CodeGen/bitfield.c,
which was already broken) on both a Debug and Release build, but it should
obviously be reviewed.
llvm-svn: 52378
2008-06-17 10:43:46 +08:00
|
|
|
E->arg_end(CGF.getContext())).getScalarVal();
|
2008-01-18 01:46:27 +08:00
|
|
|
}
|
|
|
|
|
2007-12-01 01:56:23 +08:00
|
|
|
Value *ScalarExprEmitter::VisitVAArgExpr(VAArgExpr *VE) {
|
2007-10-16 04:28:48 +08:00
|
|
|
llvm::Value *ArgValue = EmitLValue(VE->getSubExpr()).getAddress();
|
|
|
|
|
|
|
|
llvm::Value *V = Builder.CreateVAArg(ArgValue, ConvertType(VE->getType()));
|
|
|
|
return V;
|
|
|
|
}
|
|
|
|
|
2007-12-01 01:56:23 +08:00
|
|
|
Value *ScalarExprEmitter::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
|
2007-10-29 13:01:08 +08:00
|
|
|
std::string str;
|
2008-01-23 06:44:46 +08:00
|
|
|
llvm::SmallVector<const RecordType *, 8> EncodingRecordTypes;
|
|
|
|
CGF.getContext().getObjCEncodingForType(E->getEncodedType(), str,
|
|
|
|
EncodingRecordTypes);
|
2007-10-29 13:01:08 +08:00
|
|
|
|
|
|
|
llvm::Constant *C = llvm::ConstantArray::get(str);
|
|
|
|
C = new llvm::GlobalVariable(C->getType(), true,
|
|
|
|
llvm::GlobalValue::InternalLinkage,
|
|
|
|
C, ".str", &CGF.CGM.getModule());
|
|
|
|
llvm::Constant *Zero = llvm::Constant::getNullValue(llvm::Type::Int32Ty);
|
|
|
|
llvm::Constant *Zeros[] = { Zero, Zero };
|
|
|
|
C = llvm::ConstantExpr::getGetElementPtr(C, Zeros, 2);
|
|
|
|
|
|
|
|
return C;
|
|
|
|
}
|
|
|
|
|
2007-08-24 13:35:26 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Entry Point into this File
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
/// EmitComplexExpr - Emit the computation of the specified expression of
|
|
|
|
/// complex type, ignoring the result.
|
|
|
|
Value *CodeGenFunction::EmitScalarExpr(const Expr *E) {
|
|
|
|
assert(E && !hasAggregateLLVMType(E->getType()) &&
|
|
|
|
"Invalid scalar expression to emit");
|
|
|
|
|
|
|
|
return ScalarExprEmitter(*this).Visit(const_cast<Expr*>(E));
|
|
|
|
}
|
2007-08-26 14:48:56 +08:00
|
|
|
|
|
|
|
/// EmitScalarConversion - Emit a conversion from the specified type to the
|
|
|
|
/// specified destination type, both of which are LLVM scalar types.
|
2007-08-27 00:34:22 +08:00
|
|
|
Value *CodeGenFunction::EmitScalarConversion(Value *Src, QualType SrcTy,
|
|
|
|
QualType DstTy) {
|
2007-08-26 14:48:56 +08:00
|
|
|
assert(!hasAggregateLLVMType(SrcTy) && !hasAggregateLLVMType(DstTy) &&
|
|
|
|
"Invalid scalar expression to emit");
|
|
|
|
return ScalarExprEmitter(*this).EmitScalarConversion(Src, SrcTy, DstTy);
|
|
|
|
}
|
2007-08-27 00:34:22 +08:00
|
|
|
|
|
|
|
/// EmitComplexToScalarConversion - Emit a conversion from the specified
|
|
|
|
/// complex type to the specified destination type, where the destination
|
|
|
|
/// type is an LLVM scalar type.
|
|
|
|
Value *CodeGenFunction::EmitComplexToScalarConversion(ComplexPairTy Src,
|
|
|
|
QualType SrcTy,
|
|
|
|
QualType DstTy) {
|
2008-04-05 00:54:41 +08:00
|
|
|
assert(SrcTy->isAnyComplexType() && !hasAggregateLLVMType(DstTy) &&
|
2007-08-27 00:34:22 +08:00
|
|
|
"Invalid complex -> scalar conversion");
|
|
|
|
return ScalarExprEmitter(*this).EmitComplexToScalarConversion(Src, SrcTy,
|
|
|
|
DstTy);
|
|
|
|
}
|
2007-12-11 03:35:18 +08:00
|
|
|
|
|
|
|
Value *CodeGenFunction::EmitShuffleVector(Value* V1, Value *V2, ...) {
|
|
|
|
assert(V1->getType() == V2->getType() &&
|
|
|
|
"Vector operands must be of the same type");
|
|
|
|
|
|
|
|
unsigned NumElements =
|
|
|
|
cast<llvm::VectorType>(V1->getType())->getNumElements();
|
|
|
|
|
|
|
|
va_list va;
|
|
|
|
va_start(va, V2);
|
|
|
|
|
|
|
|
llvm::SmallVector<llvm::Constant*, 16> Args;
|
|
|
|
|
|
|
|
for (unsigned i = 0; i < NumElements; i++) {
|
|
|
|
int n = va_arg(va, int);
|
|
|
|
|
|
|
|
assert(n >= 0 && n < (int)NumElements * 2 &&
|
|
|
|
"Vector shuffle index out of bounds!");
|
|
|
|
|
|
|
|
Args.push_back(llvm::ConstantInt::get(llvm::Type::Int32Ty, n));
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *Name = va_arg(va, const char *);
|
|
|
|
va_end(va);
|
|
|
|
|
|
|
|
llvm::Constant *Mask = llvm::ConstantVector::get(&Args[0], NumElements);
|
|
|
|
|
|
|
|
return Builder.CreateShuffleVector(V1, V2, Mask, Name);
|
|
|
|
}
|
|
|
|
|
2007-12-16 05:23:30 +08:00
|
|
|
llvm::Value *CodeGenFunction::EmitVector(llvm::Value * const *Vals,
|
2007-12-30 10:59:45 +08:00
|
|
|
unsigned NumVals, bool isSplat)
|
2007-12-16 05:23:30 +08:00
|
|
|
{
|
|
|
|
llvm::Value *Vec
|
|
|
|
= llvm::UndefValue::get(llvm::VectorType::get(Vals[0]->getType(), NumVals));
|
|
|
|
|
|
|
|
for (unsigned i = 0, e = NumVals ; i != e; ++i) {
|
2007-12-30 10:59:45 +08:00
|
|
|
llvm::Value *Val = isSplat ? Vals[0] : Vals[i];
|
2007-12-16 05:23:30 +08:00
|
|
|
llvm::Value *Idx = llvm::ConstantInt::get(llvm::Type::Int32Ty, i);
|
2007-12-30 10:59:45 +08:00
|
|
|
Vec = Builder.CreateInsertElement(Vec, Val, Idx, "tmp");
|
2007-12-16 05:23:30 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return Vec;
|
|
|
|
}
|