completely refactor codegen of scalar expressions out into its own CGExprScalar.cpp file.

This patch temporarily breaks compound assignment operators, but greatly simplifies many
things.

llvm-svn: 41355
This commit is contained in:
Chris Lattner 2007-08-24 05:35:26 +00:00
parent 504dc0aaed
commit 2da04b3322
8 changed files with 678 additions and 708 deletions

View File

@ -84,8 +84,10 @@ void CodeGenFunction::EmitLocalBlockVarDecl(const BlockVarDecl &D) {
DMEntry = DeclPtr;
// If this local has an initializer, emit it now.
if (const Expr *Init = D.getInit())
EmitStoreThroughLValue(EmitExpr(Init), LValue::MakeAddr(DeclPtr), Ty);
if (const Expr *Init = D.getInit()) {
// FIXME: This could be much better for aggregates / complex.
EmitStoreThroughLValue(EmitAnyExpr(Init), LValue::MakeAddr(DeclPtr), Ty);
}
}
/// Emit an alloca for the specified parameter and set up LocalDeclMap.

View File

@ -411,7 +411,7 @@ LValue CodeGenFunction::EmitUnaryOpLValue(const UnaryOperator *E) {
assert(E->getOpcode() == UnaryOperator::Deref &&
"'*' is the only unary operator that produces an lvalue");
return LValue::MakeAddr(EmitExpr(E->getSubExpr()).getVal());
return LValue::MakeAddr(EmitScalarExpr(E->getSubExpr()));
}
LValue CodeGenFunction::EmitStringLiteralLValue(const StringLiteral *E) {
@ -468,7 +468,7 @@ LValue CodeGenFunction::EmitPreDefinedLValue(const PreDefinedExpr *E) {
LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E) {
// The index must always be an integer, which is not an aggregate. Emit it.
llvm::Value *Idx = EmitExpr(E->getIdx()).getVal();
llvm::Value *Idx = EmitScalarExpr(E->getIdx());
// If the base is a vector type, then we are forming a vector element lvalue
// with this subscript.
@ -481,7 +481,7 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E) {
}
// The base must be a pointer, which is not an aggregate. Emit it.
llvm::Value *Base = EmitExpr(E->getBase()).getVal();
llvm::Value *Base = EmitScalarExpr(E->getBase());
// Extend or truncate the index type to 32 or 64-bits.
QualType IdxTy = E->getIdx()->getType();
@ -517,7 +517,7 @@ EmitOCUVectorElementExpr(const OCUVectorElementExpr *E) {
/// result of the expression doesn't need to be generated into memory.
RValue CodeGenFunction::EmitAnyExpr(const Expr *E, bool NeedResult) {
if (!hasAggregateLLVMType(E->getType()))
return EmitExpr(E);
return RValue::get(EmitScalarExpr(E));
llvm::Value *DestMem = 0;
if (NeedResult)
@ -533,151 +533,6 @@ RValue CodeGenFunction::EmitAnyExpr(const Expr *E, bool NeedResult) {
return RValue::getAggregate(DestMem);
}
RValue CodeGenFunction::EmitExpr(const Expr *E) {
assert(E && !hasAggregateLLVMType(E->getType()) &&
"Invalid scalar expression to emit");
switch (E->getStmtClass()) {
default:
fprintf(stderr, "Unimplemented expr!\n");
E->dump();
return RValue::get(llvm::UndefValue::get(llvm::Type::Int32Ty));
// l-values.
case Expr::DeclRefExprClass:
// DeclRef's of EnumConstantDecl's are simple rvalues.
if (const EnumConstantDecl *EC =
dyn_cast<EnumConstantDecl>(cast<DeclRefExpr>(E)->getDecl()))
return RValue::get(llvm::ConstantInt::get(EC->getInitVal()));
return EmitLoadOfLValue(E);
case Expr::ArraySubscriptExprClass:
return EmitArraySubscriptExprRV(cast<ArraySubscriptExpr>(E));
case Expr::OCUVectorElementExprClass:
return EmitLoadOfLValue(E);
case Expr::PreDefinedExprClass:
case Expr::StringLiteralClass:
return RValue::get(EmitLValue(E).getAddress());
// Leaf expressions.
case Expr::IntegerLiteralClass:
return EmitIntegerLiteral(cast<IntegerLiteral>(E));
case Expr::FloatingLiteralClass:
return EmitFloatingLiteral(cast<FloatingLiteral>(E));
case Expr::CharacterLiteralClass:
return EmitCharacterLiteral(cast<CharacterLiteral>(E));
case Expr::TypesCompatibleExprClass:
return EmitTypesCompatibleExpr(cast<TypesCompatibleExpr>(E));
// Operators.
case Expr::ParenExprClass:
return EmitExpr(cast<ParenExpr>(E)->getSubExpr());
case Expr::UnaryOperatorClass:
return EmitUnaryOperator(cast<UnaryOperator>(E));
case Expr::SizeOfAlignOfTypeExprClass:
return EmitSizeAlignOf(cast<SizeOfAlignOfTypeExpr>(E)->getArgumentType(),
E->getType(),
cast<SizeOfAlignOfTypeExpr>(E)->isSizeOf());
case Expr::ImplicitCastExprClass:
return EmitImplicitCastExpr(cast<ImplicitCastExpr>(E));
case Expr::CastExprClass:
return EmitCastExpr(cast<CastExpr>(E)->getSubExpr(), E->getType());
case Expr::CallExprClass:
return EmitCallExpr(cast<CallExpr>(E));
case Expr::BinaryOperatorClass:
return EmitBinaryOperator(cast<BinaryOperator>(E));
case Expr::ConditionalOperatorClass:
return EmitConditionalOperator(cast<ConditionalOperator>(E));
case Expr::ChooseExprClass:
return EmitChooseExpr(cast<ChooseExpr>(E));
case Expr::ObjCStringLiteralClass:
return EmitObjCStringLiteral(cast<ObjCStringLiteral>(E));
}
}
RValue CodeGenFunction::EmitIntegerLiteral(const IntegerLiteral *E) {
return RValue::get(llvm::ConstantInt::get(E->getValue()));
}
RValue CodeGenFunction::EmitFloatingLiteral(const FloatingLiteral *E) {
return RValue::get(llvm::ConstantFP::get(ConvertType(E->getType()),
E->getValue()));
}
RValue CodeGenFunction::EmitCharacterLiteral(const CharacterLiteral *E) {
return RValue::get(llvm::ConstantInt::get(ConvertType(E->getType()),
E->getValue()));
}
RValue CodeGenFunction::EmitTypesCompatibleExpr(const TypesCompatibleExpr *E) {
return RValue::get(llvm::ConstantInt::get(ConvertType(E->getType()),
E->typesAreCompatible()));
}
/// EmitChooseExpr - Implement __builtin_choose_expr.
RValue CodeGenFunction::EmitChooseExpr(const ChooseExpr *E) {
llvm::APSInt CondVal(32);
bool IsConst = E->getCond()->isIntegerConstantExpr(CondVal, getContext());
assert(IsConst && "Condition of choose expr must be i-c-e"); IsConst=IsConst;
// Emit the LHS or RHS as appropriate.
return EmitExpr(CondVal != 0 ? E->getLHS() : E->getRHS());
}
RValue CodeGenFunction::EmitArraySubscriptExprRV(const 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.
llvm::Value *Base = EmitExpr(E->getBase()).getVal();
llvm::Value *Idx = EmitExpr(E->getIdx()).getVal();
// FIXME: Convert Idx to i32 type.
return RValue::get(Builder.CreateExtractElement(Base, Idx, "vecext"));
}
// EmitCastExpr - 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.
RValue CodeGenFunction::EmitCastExpr(const Expr *Op, QualType DestTy) {
RValue Src = EmitAnyExpr(Op);
// If the destination is void, just evaluate the source.
if (DestTy->isVoidType())
return RValue::getAggregate(0);
return EmitConversion(Src, Op->getType(), DestTy);
}
/// EmitImplicitCastExpr - Implicit casts are the same as normal casts, but also
/// handle things like function to pointer-to-function decay, and array to
/// pointer decay.
RValue CodeGenFunction::EmitImplicitCastExpr(const ImplicitCastExpr *E) {
const Expr *Op = E->getSubExpr();
QualType OpTy = Op->getType().getCanonicalType();
// If this is due to array->pointer conversion, emit the array expression as
// an l-value.
if (isa<ArrayType>(OpTy)) {
// FIXME: For now we assume that all source arrays map to LLVM arrays. This
// will not true when we add support for VLAs.
llvm::Value *V = EmitLValue(Op).getAddress(); // Bitfields can't be arrays.
assert(isa<llvm::PointerType>(V->getType()) &&
isa<llvm::ArrayType>(cast<llvm::PointerType>(V->getType())
->getElementType()) &&
"Doesn't support VLAs yet!");
llvm::Constant *Idx0 = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0);
return RValue::get(Builder.CreateGEP(V, Idx0, Idx0, "arraydecay"));
}
return EmitCastExpr(Op, E->getType());
}
RValue CodeGenFunction::EmitCallExpr(const CallExpr *E) {
if (const ImplicitCastExpr *IcExpr =
@ -689,7 +544,7 @@ RValue CodeGenFunction::EmitCallExpr(const CallExpr *E) {
if (unsigned builtinID = FDecl->getIdentifier()->getBuiltinID())
return EmitBuiltinExpr(builtinID, E);
llvm::Value *Callee = EmitExpr(E->getCallee()).getVal();
llvm::Value *Callee = EmitScalarExpr(E->getCallee());
// The callee type will always be a pointer to function type, get the function
// type.
@ -756,145 +611,7 @@ RValue CodeGenFunction::EmitCallExpr(const CallExpr *E) {
// Unary Operator Emission
//===----------------------------------------------------------------------===//
RValue CodeGenFunction::EmitUnaryOperator(const UnaryOperator *E) {
switch (E->getOpcode()) {
default:
printf("Unimplemented unary expr!\n");
E->dump();
return RValue::get(llvm::UndefValue::get(llvm::Type::Int32Ty));
case UnaryOperator::PostInc:
case UnaryOperator::PostDec:
case UnaryOperator::PreInc :
case UnaryOperator::PreDec : return EmitUnaryIncDec(E);
case UnaryOperator::AddrOf : return EmitUnaryAddrOf(E);
case UnaryOperator::Deref : return EmitLoadOfLValue(E);
case UnaryOperator::Plus : return EmitUnaryPlus(E);
case UnaryOperator::Minus : return EmitUnaryMinus(E);
case UnaryOperator::Not : return EmitUnaryNot(E);
case UnaryOperator::LNot : return EmitUnaryLNot(E);
case UnaryOperator::SizeOf :
return EmitSizeAlignOf(E->getSubExpr()->getType(), E->getType(), true);
case UnaryOperator::AlignOf :
return EmitSizeAlignOf(E->getSubExpr()->getType(), E->getType(), false);
// FIXME: real/imag
case UnaryOperator::Extension: return EmitExpr(E->getSubExpr());
}
}
RValue CodeGenFunction::EmitUnaryIncDec(const UnaryOperator *E) {
LValue LV = EmitLValue(E->getSubExpr());
RValue InVal = EmitLoadOfLValue(LV, E->getSubExpr()->getType());
// We know the operand is real or pointer type, so it must be an LLVM scalar.
assert(InVal.isScalar() && "Unknown thing to increment");
llvm::Value *InV = InVal.getVal();
int AmountVal = 1;
if (E->getOpcode() == UnaryOperator::PreDec ||
E->getOpcode() == UnaryOperator::PostDec)
AmountVal = -1;
llvm::Value *NextVal;
if (isa<llvm::IntegerType>(InV->getType())) {
NextVal = llvm::ConstantInt::get(InV->getType(), AmountVal);
NextVal = Builder.CreateAdd(InV, NextVal, AmountVal == 1 ? "inc" : "dec");
} else if (InV->getType()->isFloatingPoint()) {
NextVal = llvm::ConstantFP::get(InV->getType(), AmountVal);
NextVal = Builder.CreateAdd(InV, NextVal, AmountVal == 1 ? "inc" : "dec");
} else {
// FIXME: This is not right for pointers to VLA types.
assert(isa<llvm::PointerType>(InV->getType()));
NextVal = llvm::ConstantInt::get(llvm::Type::Int32Ty, AmountVal);
NextVal = Builder.CreateGEP(InV, NextVal, AmountVal == 1 ? "inc" : "dec");
}
RValue NextValToStore = RValue::get(NextVal);
// Store the updated result through the lvalue.
EmitStoreThroughLValue(NextValToStore, LV, E->getSubExpr()->getType());
// If this is a postinc, return the value read from memory, otherwise use the
// updated value.
if (E->getOpcode() == UnaryOperator::PreDec ||
E->getOpcode() == UnaryOperator::PreInc)
return NextValToStore;
else
return InVal;
}
/// C99 6.5.3.2
RValue CodeGenFunction::EmitUnaryAddrOf(const UnaryOperator *E) {
// The address of the operand is just its lvalue. It cannot be a bitfield.
return RValue::get(EmitLValue(E->getSubExpr()).getAddress());
}
RValue CodeGenFunction::EmitUnaryPlus(const UnaryOperator *E) {
assert(E->getType().getCanonicalType() ==
E->getSubExpr()->getType().getCanonicalType() && "Bad unary plus!");
// Unary plus just returns its value.
return EmitExpr(E->getSubExpr());
}
RValue CodeGenFunction::EmitUnaryMinus(const UnaryOperator *E) {
assert(E->getType().getCanonicalType() ==
E->getSubExpr()->getType().getCanonicalType() && "Bad unary minus!");
// Unary minus performs promotions, then negates its arithmetic operand.
RValue V = EmitExpr(E->getSubExpr());
if (V.isScalar())
return RValue::get(Builder.CreateNeg(V.getVal(), "neg"));
assert(0 && "FIXME: This doesn't handle complex operands yet");
}
RValue CodeGenFunction::EmitUnaryNot(const UnaryOperator *E) {
// Unary not performs promotions, then complements its integer operand.
RValue V = EmitExpr(E->getSubExpr());
if (V.isScalar())
return RValue::get(Builder.CreateNot(V.getVal(), "neg"));
assert(0 && "FIXME: This doesn't handle integer complex operands yet (GNU)");
}
/// C99 6.5.3.3
RValue CodeGenFunction::EmitUnaryLNot(const UnaryOperator *E) {
// Compare operand to zero.
llvm::Value *BoolVal = 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 RValue::get(Builder.CreateZExt(BoolVal, LLVMIntTy, "lnot.ext"));
}
/// EmitSizeAlignOf - Return the size or alignment of the 'TypeToSize' type as
/// an integer (RetType).
RValue CodeGenFunction::EmitSizeAlignOf(QualType TypeToSize,
QualType RetType, bool isSizeOf) {
/// FIXME: This doesn't handle VLAs yet!
std::pair<uint64_t, unsigned> Info =
getContext().getTypeInfo(TypeToSize, SourceLocation());
uint64_t Val = isSizeOf ? Info.first : Info.second;
Val /= 8; // Return size in bytes, not bits.
assert(RetType->isIntegerType() && "Result type must be an integer!");
unsigned ResultWidth = getContext().getTypeSize(RetType, SourceLocation());
return RValue::get(llvm::ConstantInt::get(llvm::APInt(ResultWidth, Val)));
}
//===--------------------------------------------------------------------===//
// Binary Operator Emission
//===--------------------------------------------------------------------===//
#if 0
/// EmitCompoundAssignmentOperands - Compound assignment operations (like +=)
/// are strange in that the result of the operation is not the same type as the
@ -946,18 +663,6 @@ RValue CodeGenFunction::EmitBinaryOperator(const BinaryOperator *E) {
fprintf(stderr, "Unimplemented binary expr!\n");
E->dump();
return RValue::get(llvm::UndefValue::get(llvm::Type::Int32Ty));
case BinaryOperator::Mul:
LHS = EmitExpr(E->getLHS());
RHS = EmitExpr(E->getRHS());
return EmitMul(LHS, RHS, E->getType());
case BinaryOperator::Div:
LHS = EmitExpr(E->getLHS());
RHS = EmitExpr(E->getRHS());
return EmitDiv(LHS, RHS, E->getType());
case BinaryOperator::Rem:
LHS = EmitExpr(E->getLHS());
RHS = EmitExpr(E->getRHS());
return EmitRem(LHS, RHS, E->getType());
case BinaryOperator::Add:
LHS = EmitExpr(E->getLHS());
RHS = EmitExpr(E->getRHS());
@ -966,61 +671,6 @@ RValue CodeGenFunction::EmitBinaryOperator(const BinaryOperator *E) {
return EmitPointerAdd(LHS, E->getLHS()->getType(),
RHS, E->getRHS()->getType(), E->getType());
case BinaryOperator::Sub:
LHS = EmitExpr(E->getLHS());
RHS = EmitExpr(E->getRHS());
if (!E->getLHS()->getType()->isPointerType())
return EmitSub(LHS, RHS, E->getType());
return EmitPointerSub(LHS, E->getLHS()->getType(),
RHS, E->getRHS()->getType(), E->getType());
case BinaryOperator::Shl:
LHS = EmitExpr(E->getLHS());
RHS = EmitExpr(E->getRHS());
return EmitShl(LHS, RHS, E->getType());
case BinaryOperator::Shr:
LHS = EmitExpr(E->getLHS());
RHS = EmitExpr(E->getRHS());
return EmitShr(LHS, RHS, E->getType());
case BinaryOperator::And:
LHS = EmitExpr(E->getLHS());
RHS = EmitExpr(E->getRHS());
return EmitAnd(LHS, RHS, E->getType());
case BinaryOperator::Xor:
LHS = EmitExpr(E->getLHS());
RHS = EmitExpr(E->getRHS());
return EmitXor(LHS, RHS, E->getType());
case BinaryOperator::Or :
LHS = EmitExpr(E->getLHS());
RHS = EmitExpr(E->getRHS());
return EmitOr(LHS, RHS, E->getType());
case BinaryOperator::LAnd: return EmitBinaryLAnd(E);
case BinaryOperator::LOr: return EmitBinaryLOr(E);
case BinaryOperator::LT:
return EmitBinaryCompare(E, llvm::ICmpInst::ICMP_ULT,
llvm::ICmpInst::ICMP_SLT,
llvm::FCmpInst::FCMP_OLT);
case BinaryOperator::GT:
return EmitBinaryCompare(E, llvm::ICmpInst::ICMP_UGT,
llvm::ICmpInst::ICMP_SGT,
llvm::FCmpInst::FCMP_OGT);
case BinaryOperator::LE:
return EmitBinaryCompare(E, llvm::ICmpInst::ICMP_ULE,
llvm::ICmpInst::ICMP_SLE,
llvm::FCmpInst::FCMP_OLE);
case BinaryOperator::GE:
return EmitBinaryCompare(E, llvm::ICmpInst::ICMP_UGE,
llvm::ICmpInst::ICMP_SGE,
llvm::FCmpInst::FCMP_OGE);
case BinaryOperator::EQ:
return EmitBinaryCompare(E, llvm::ICmpInst::ICMP_EQ,
llvm::ICmpInst::ICMP_EQ,
llvm::FCmpInst::FCMP_OEQ);
case BinaryOperator::NE:
return EmitBinaryCompare(E, llvm::ICmpInst::ICMP_NE,
llvm::ICmpInst::ICMP_NE,
llvm::FCmpInst::FCMP_UNE);
case BinaryOperator::Assign:
return EmitBinaryAssign(E);
@ -1059,327 +709,8 @@ RValue CodeGenFunction::EmitBinaryOperator(const BinaryOperator *E) {
LHS = EmitSub(LHS, RHS, CAO->getComputationType());
return EmitCompoundAssignmentResult(CAO, LHSLV, LHS);
}
case BinaryOperator::ShlAssign: {
const CompoundAssignOperator *CAO = cast<CompoundAssignOperator>(E);
LValue LHSLV;
EmitCompoundAssignmentOperands(CAO, LHSLV, LHS, RHS);
LHS = EmitShl(LHS, RHS, CAO->getComputationType());
return EmitCompoundAssignmentResult(CAO, LHSLV, LHS);
}
case BinaryOperator::ShrAssign: {
const CompoundAssignOperator *CAO = cast<CompoundAssignOperator>(E);
LValue LHSLV;
EmitCompoundAssignmentOperands(CAO, LHSLV, LHS, RHS);
LHS = EmitShr(LHS, RHS, CAO->getComputationType());
return EmitCompoundAssignmentResult(CAO, LHSLV, LHS);
}
case BinaryOperator::AndAssign: {
const CompoundAssignOperator *CAO = cast<CompoundAssignOperator>(E);
LValue LHSLV;
EmitCompoundAssignmentOperands(CAO, LHSLV, LHS, RHS);
LHS = EmitAnd(LHS, RHS, CAO->getComputationType());
return EmitCompoundAssignmentResult(CAO, LHSLV, LHS);
}
case BinaryOperator::OrAssign: {
const CompoundAssignOperator *CAO = cast<CompoundAssignOperator>(E);
LValue LHSLV;
EmitCompoundAssignmentOperands(CAO, LHSLV, LHS, RHS);
LHS = EmitOr(LHS, RHS, CAO->getComputationType());
return EmitCompoundAssignmentResult(CAO, LHSLV, LHS);
}
case BinaryOperator::XorAssign: {
const CompoundAssignOperator *CAO = cast<CompoundAssignOperator>(E);
LValue LHSLV;
EmitCompoundAssignmentOperands(CAO, LHSLV, LHS, RHS);
LHS = EmitXor(LHS, RHS, CAO->getComputationType());
return EmitCompoundAssignmentResult(CAO, LHSLV, LHS);
}
case BinaryOperator::Comma: return EmitBinaryComma(E);
}
}
RValue CodeGenFunction::EmitMul(RValue LHS, RValue RHS, QualType ResTy) {
return RValue::get(Builder.CreateMul(LHS.getVal(), RHS.getVal(), "mul"));
}
RValue CodeGenFunction::EmitDiv(RValue LHS, RValue RHS, QualType ResTy) {
if (LHS.getVal()->getType()->isFloatingPoint())
return RValue::get(Builder.CreateFDiv(LHS.getVal(), RHS.getVal(), "div"));
else if (ResTy->isUnsignedIntegerType())
return RValue::get(Builder.CreateUDiv(LHS.getVal(), RHS.getVal(), "div"));
else
return RValue::get(Builder.CreateSDiv(LHS.getVal(), RHS.getVal(), "div"));
}
RValue CodeGenFunction::EmitRem(RValue LHS, RValue RHS, QualType ResTy) {
// Rem in C can't be a floating point type: C99 6.5.5p2.
if (ResTy->isUnsignedIntegerType())
return RValue::get(Builder.CreateURem(LHS.getVal(), RHS.getVal(), "rem"));
else
return RValue::get(Builder.CreateSRem(LHS.getVal(), RHS.getVal(), "rem"));
}
RValue CodeGenFunction::EmitAdd(RValue LHS, RValue RHS, QualType ResTy) {
return RValue::get(Builder.CreateAdd(LHS.getVal(), RHS.getVal(), "add"));
}
RValue CodeGenFunction::EmitPointerAdd(RValue LHS, QualType LHSTy,
RValue RHS, QualType RHSTy,
QualType ResTy) {
llvm::Value *LHSValue = LHS.getVal();
llvm::Value *RHSValue = RHS.getVal();
if (LHSTy->isPointerType()) {
// pointer + int
return RValue::get(Builder.CreateGEP(LHSValue, RHSValue, "add.ptr"));
} else {
// int + pointer
return RValue::get(Builder.CreateGEP(RHSValue, LHSValue, "add.ptr"));
}
}
RValue CodeGenFunction::EmitSub(RValue LHS, RValue RHS, QualType ResTy) {
return RValue::get(Builder.CreateSub(LHS.getVal(), RHS.getVal(), "sub"));
}
RValue CodeGenFunction::EmitPointerSub(RValue LHS, QualType LHSTy,
RValue RHS, QualType RHSTy,
QualType ResTy) {
llvm::Value *LHSValue = LHS.getVal();
llvm::Value *RHSValue = RHS.getVal();
if (const PointerType *RHSPtrType =
dyn_cast<PointerType>(RHSTy.getTypePtr())) {
// pointer - pointer
const PointerType *LHSPtrType = cast<PointerType>(LHSTy.getTypePtr());
QualType LHSElementType = LHSPtrType->getPointeeType();
assert(LHSElementType == RHSPtrType->getPointeeType() &&
"can't subtract pointers with differing element types");
uint64_t ElementSize = getContext().getTypeSize(LHSElementType,
SourceLocation()) / 8;
const llvm::Type *ResultType = ConvertType(ResTy);
llvm::Value *CastLHS = Builder.CreatePtrToInt(LHSValue, ResultType,
"sub.ptr.lhs.cast");
llvm::Value *CastRHS = Builder.CreatePtrToInt(RHSValue, ResultType,
"sub.ptr.rhs.cast");
llvm::Value *BytesBetween = Builder.CreateSub(CastLHS, CastRHS,
"sub.ptr.sub");
// 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)) {
llvm::Value *ShAmt =
llvm::ConstantInt::get(ResultType, llvm::Log2_64(ElementSize));
return RValue::get(Builder.CreateAShr(BytesBetween, ShAmt,"sub.ptr.shr"));
} else {
// Otherwise, do a full sdiv.
llvm::Value *BytesPerElement =
llvm::ConstantInt::get(ResultType, ElementSize);
return RValue::get(Builder.CreateSDiv(BytesBetween, BytesPerElement,
"sub.ptr.div"));
}
} else {
// pointer - int
llvm::Value *NegatedRHS = Builder.CreateNeg(RHSValue, "sub.ptr.neg");
return RValue::get(Builder.CreateGEP(LHSValue, NegatedRHS, "sub.ptr"));
}
}
RValue CodeGenFunction::EmitShl(RValue LHSV, RValue RHSV, QualType ResTy) {
llvm::Value *LHS = LHSV.getVal(), *RHS = RHSV.getVal();
// LLVM requires the LHS and RHS to be the same type, promote or truncate the
// RHS to the same size as the LHS.
if (LHS->getType() != RHS->getType())
RHS = Builder.CreateIntCast(RHS, LHS->getType(), false, "sh_prom");
return RValue::get(Builder.CreateShl(LHS, RHS, "shl"));
}
RValue CodeGenFunction::EmitShr(RValue LHSV, RValue RHSV, QualType ResTy) {
llvm::Value *LHS = LHSV.getVal(), *RHS = RHSV.getVal();
// LLVM requires the LHS and RHS to be the same type, promote or truncate the
// RHS to the same size as the LHS.
if (LHS->getType() != RHS->getType())
RHS = Builder.CreateIntCast(RHS, LHS->getType(), false, "sh_prom");
if (ResTy->isUnsignedIntegerType())
return RValue::get(Builder.CreateLShr(LHS, RHS, "shr"));
else
return RValue::get(Builder.CreateAShr(LHS, RHS, "shr"));
}
RValue CodeGenFunction::EmitBinaryCompare(const BinaryOperator *E,
unsigned UICmpOpc, unsigned SICmpOpc,
unsigned FCmpOpc) {
llvm::Value *Result;
QualType LHSTy = E->getLHS()->getType();
if (!LHSTy->isComplexType()) {
RValue LHS = EmitExpr(E->getLHS());
RValue RHS = EmitExpr(E->getRHS());
if (LHSTy->isRealFloatingType()) {
Result = Builder.CreateFCmp((llvm::FCmpInst::Predicate)FCmpOpc,
LHS.getVal(), RHS.getVal(), "cmp");
} else if (LHSTy->isUnsignedIntegerType()) {
// FIXME: This check isn't right for "unsigned short < int" where ushort
// promotes to int and does a signed compare.
Result = Builder.CreateICmp((llvm::ICmpInst::Predicate)UICmpOpc,
LHS.getVal(), RHS.getVal(), "cmp");
} else {
// Signed integers and pointers.
Result = Builder.CreateICmp((llvm::ICmpInst::Predicate)SICmpOpc,
LHS.getVal(), RHS.getVal(), "cmp");
}
} else {
// Complex Comparison: can only be an equality comparison.
ComplexPairTy LHS = EmitComplexExpr(E->getLHS());
ComplexPairTy RHS = EmitComplexExpr(E->getRHS());
QualType CETy =
cast<ComplexType>(LHSTy.getCanonicalType())->getElementType();
llvm::Value *ResultR, *ResultI;
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 RValue::get(Builder.CreateZExt(Result, LLVMIntTy, "cmp.ext"));
}
RValue CodeGenFunction::EmitAnd(RValue LHS, RValue RHS, QualType ResTy) {
return RValue::get(Builder.CreateAnd(LHS.getVal(), RHS.getVal(), "and"));
}
RValue CodeGenFunction::EmitXor(RValue LHS, RValue RHS, QualType ResTy) {
return RValue::get(Builder.CreateXor(LHS.getVal(), RHS.getVal(), "xor"));
}
RValue CodeGenFunction::EmitOr(RValue LHS, RValue RHS, QualType ResTy) {
return RValue::get(Builder.CreateOr(LHS.getVal(), RHS.getVal(), "or"));
}
RValue CodeGenFunction::EmitBinaryLAnd(const BinaryOperator *E) {
llvm::Value *LHSCond = EvaluateExprAsBool(E->getLHS());
llvm::BasicBlock *ContBlock = new llvm::BasicBlock("land_cont");
llvm::BasicBlock *RHSBlock = new llvm::BasicBlock("land_rhs");
llvm::BasicBlock *OrigBlock = Builder.GetInsertBlock();
Builder.CreateCondBr(LHSCond, RHSBlock, ContBlock);
EmitBlock(RHSBlock);
llvm::Value *RHSCond = EvaluateExprAsBool(E->getRHS());
// Reaquire the RHS block, as there may be subblocks inserted.
RHSBlock = Builder.GetInsertBlock();
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 RValue::get(Builder.CreateZExt(PN, LLVMIntTy, "land.ext"));
}
RValue CodeGenFunction::EmitBinaryLOr(const BinaryOperator *E) {
llvm::Value *LHSCond = EvaluateExprAsBool(E->getLHS());
llvm::BasicBlock *ContBlock = new llvm::BasicBlock("lor_cont");
llvm::BasicBlock *RHSBlock = new llvm::BasicBlock("lor_rhs");
llvm::BasicBlock *OrigBlock = Builder.GetInsertBlock();
Builder.CreateCondBr(LHSCond, ContBlock, RHSBlock);
EmitBlock(RHSBlock);
llvm::Value *RHSCond = EvaluateExprAsBool(E->getRHS());
// Reaquire the RHS block, as there may be subblocks inserted.
RHSBlock = Builder.GetInsertBlock();
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 RValue::get(Builder.CreateZExt(PN, LLVMIntTy, "lor.ext"));
}
RValue CodeGenFunction::EmitBinaryAssign(const BinaryOperator *E) {
assert(E->getLHS()->getType().getCanonicalType() ==
E->getRHS()->getType().getCanonicalType() && "Invalid assignment");
LValue LHS = EmitLValue(E->getLHS());
RValue RHS = EmitExpr(E->getRHS());
// Store the value into the LHS.
EmitStoreThroughLValue(RHS, LHS, E->getType());
// Return the RHS.
return RHS;
}
RValue CodeGenFunction::EmitBinaryComma(const BinaryOperator *E) {
EmitStmt(E->getLHS());
return EmitExpr(E->getRHS());
}
RValue CodeGenFunction::EmitConditionalOperator(const ConditionalOperator *E) {
llvm::BasicBlock *LHSBlock = new llvm::BasicBlock("cond.?");
llvm::BasicBlock *RHSBlock = new llvm::BasicBlock("cond.:");
llvm::BasicBlock *ContBlock = new llvm::BasicBlock("cond.cont");
llvm::Value *Cond = EvaluateExprAsBool(E->getCond());
Builder.CreateCondBr(Cond, LHSBlock, RHSBlock);
EmitBlock(LHSBlock);
// Handle the GNU extension for missing LHS.
llvm::Value *LHSValue = E->getLHS() ? EmitExpr(E->getLHS()).getVal() : Cond;
Builder.CreateBr(ContBlock);
LHSBlock = Builder.GetInsertBlock();
EmitBlock(RHSBlock);
llvm::Value *RHSValue = EmitExpr(E->getRHS()).getVal();
Builder.CreateBr(ContBlock);
RHSBlock = Builder.GetInsertBlock();
const llvm::Type *LHSType = LHSValue->getType();
assert(LHSType == RHSValue->getType() && "?: LHS & RHS must have same type");
EmitBlock(ContBlock);
llvm::PHINode *PN = Builder.CreatePHI(LHSType, "cond");
PN->reserveOperandSpace(2);
PN->addIncoming(LHSValue, LHSBlock);
PN->addIncoming(RHSValue, RHSBlock);
return RValue::get(PN);
}
#endif

View File

@ -119,7 +119,6 @@ public:
ComplexPairTy VisitConditionalOperator(const ConditionalOperator *CO);
ComplexPairTy VisitChooseExpr(ChooseExpr *CE);
// case Expr::ChooseExprClass:
};
} // end anonymous namespace.

View File

@ -0,0 +1,648 @@
//===--- CGExprScalar.cpp - Emit LLVM Code for Scalar Exprs ---------------===//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by Chris Lattner and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// 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"
#include "llvm/Constants.h"
#include "llvm/Function.h"
#include "llvm/Support/Compiler.h"
using namespace clang;
using namespace CodeGen;
using llvm::Value;
//===----------------------------------------------------------------------===//
// Scalar Expression Emitter
//===----------------------------------------------------------------------===//
struct BinOpInfo {
Value *LHS;
Value *RHS;
const BinaryOperator *E;
};
namespace {
class VISIBILITY_HIDDEN ScalarExprEmitter
: public StmtVisitor<ScalarExprEmitter, Value*> {
CodeGenFunction &CGF;
llvm::LLVMBuilder &Builder;
public:
ScalarExprEmitter(CodeGenFunction &cgf) : CGF(cgf), Builder(CGF.Builder) {
}
//===--------------------------------------------------------------------===//
// 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) {
return CGF.EmitLoadOfLValue(LV, T).getVal();
}
/// 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());
}
//===--------------------------------------------------------------------===//
// Visitor Methods
//===--------------------------------------------------------------------===//
Value *VisitStmt(Stmt *S) {
S->dump();
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) {
return llvm::ConstantFP::get(ConvertType(E->getType()), E->getValue());
}
Value *VisitCharacterLiteral(const CharacterLiteral *E) {
return llvm::ConstantInt::get(ConvertType(E->getType()), E->getValue());
}
Value *VisitTypesCompatibleExpr(const TypesCompatibleExpr *E) {
return llvm::ConstantInt::get(ConvertType(E->getType()),
E->typesAreCompatible());
}
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);
}
Value *VisitArraySubscriptExpr(ArraySubscriptExpr *E);
Value *VisitMemberExpr(Expr *E) { return EmitLoadOfLValue(E); }
Value *VisitOCUVectorElementExpr(Expr *E) { return EmitLoadOfLValue(E); }
Value *VisitStringLiteral(Expr *E) { return EmitLValue(E).getAddress(); }
Value *VisitPreDefinedExpr(Expr *E) { return EmitLValue(E).getAddress(); }
// FIXME: CompoundLiteralExpr
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) {
return CGF.EmitCallExpr(E).getVal();
}
// 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,
bool isSizeOf);
// FIXME: Real,Imag.
Value *VisitUnaryExtension(const UnaryOperator *E) {
return Visit(E->getSubExpr());
}
// Binary Operators.
BinOpInfo EmitBinOps(const BinaryOperator *E);
Value *VisitBinMul(const BinaryOperator *E) { return EmitMul(EmitBinOps(E)); }
Value *VisitBinDiv(const BinaryOperator *E) { return EmitDiv(EmitBinOps(E)); }
Value *VisitBinRem(const BinaryOperator *E) { return EmitRem(EmitBinOps(E)); }
Value *VisitBinAdd(const BinaryOperator *E) { return EmitAdd(EmitBinOps(E)); }
Value *VisitBinSub(const BinaryOperator *E) { return EmitSub(EmitBinOps(E)); }
Value *VisitBinShl(const BinaryOperator *E) { return EmitShl(EmitBinOps(E)); }
Value *VisitBinShr(const BinaryOperator *E) { return EmitShr(EmitBinOps(E)); }
Value *VisitBinAnd(const BinaryOperator *E) { return EmitAnd(EmitBinOps(E)); }
Value *VisitBinXor(const BinaryOperator *E) { return EmitXor(EmitBinOps(E)); }
Value *VisitBinOr (const BinaryOperator *E) { return EmitOr (EmitBinOps(E)); }
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");
}
// 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);
// FIXME: Compound assignment operators.
Value *VisitBinComma (const BinaryOperator *E);
// Other Operators.
Value *VisitConditionalOperator(const ConditionalOperator *CO);
Value *VisitChooseExpr(ChooseExpr *CE);
Value *VisitObjCStringLiteral(const ObjCStringLiteral *E) {
return CGF.EmitObjCStringLiteral(E);
}
};
} // end anonymous namespace.
//===----------------------------------------------------------------------===//
// Utilities
//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
// Visitor Methods
//===----------------------------------------------------------------------===//
Value *ScalarExprEmitter::VisitExpr(Expr *E) {
fprintf(stderr, "Unimplemented scalar expr!\n");
E->dump();
if (E->getType()->isVoidType())
return 0;
return llvm::UndefValue::get(CGF.ConvertType(E->getType()));
}
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.
llvm::Value *V = EmitLValue(Op).getAddress(); // Bitfields can't be arrays.
assert(isa<llvm::PointerType>(V->getType()) &&
isa<llvm::ArrayType>(cast<llvm::PointerType>(V->getType())
->getElementType()) &&
"Doesn't support VLAs yet!");
llvm::Constant *Idx0 = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0);
return Builder.CreateGEP(V, Idx0, Idx0, "arraydecay");
}
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) {
RValue Src = CGF.EmitAnyExpr(E);
// If the destination is void, just evaluate the source.
if (DestTy->isVoidType())
return 0;
// FIXME: Refactor EmitConversion to not return an RValue. Sink it into this
// method.
return CGF.EmitConversion(Src, E->getType(), DestTy).getVal();
}
//===----------------------------------------------------------------------===//
// Unary Operators
//===----------------------------------------------------------------------===//
Value *ScalarExprEmitter::VisitPrePostIncDec(const UnaryOperator *E,
bool isInc, bool isPre) {
LValue LV = EmitLValue(E->getSubExpr());
// FIXME: Handle volatile!
Value *InVal = CGF.EmitLoadOfLValue(LV/* false*/,
E->getSubExpr()->getType()).getVal();
int AmountVal = isInc ? 1 : -1;
Value *NextVal;
if (isa<llvm::IntegerType>(InVal->getType()))
NextVal = llvm::ConstantInt::get(InVal->getType(), AmountVal);
else
NextVal = llvm::ConstantFP::get(InVal->getType(), AmountVal);
// Add the inc/dec to the real part.
NextVal = Builder.CreateAdd(InVal, NextVal, isInc ? "inc" : "dec");
// 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,
QualType RetType,bool isSizeOf){
/// FIXME: This doesn't handle VLAs yet!
std::pair<uint64_t, unsigned> Info =
CGF.getContext().getTypeInfo(TypeToSize, SourceLocation());
uint64_t Val = isSizeOf ? Info.first : Info.second;
Val /= 8; // Return size in bytes, not bits.
assert(RetType->isIntegerType() && "Result type must be an integer!");
unsigned ResultWidth = CGF.getContext().getTypeSize(RetType,SourceLocation());
return llvm::ConstantInt::get(llvm::APInt(ResultWidth, Val));
}
//===----------------------------------------------------------------------===//
// Binary Operators
//===----------------------------------------------------------------------===//
BinOpInfo ScalarExprEmitter::EmitBinOps(const BinaryOperator *E) {
BinOpInfo Result;
Result.LHS = Visit(E->getLHS());
Result.RHS = Visit(E->getRHS());
Result.E = E;
return Result;
}
Value *ScalarExprEmitter::EmitDiv(const BinOpInfo &Ops) {
if (Ops.LHS->getType()->isFloatingPoint())
return Builder.CreateFDiv(Ops.LHS, Ops.RHS, "div");
else if (Ops.E->getType()->isUnsignedIntegerType())
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.
if (Ops.E->getType()->isUnsignedIntegerType())
return Builder.CreateURem(Ops.LHS, Ops.RHS, "rem");
else
return Builder.CreateSRem(Ops.LHS, Ops.RHS, "rem");
}
Value *ScalarExprEmitter::EmitAdd(const BinOpInfo &Ops) {
if (!Ops.E->getType()->isPointerType())
return Builder.CreateAdd(Ops.LHS, Ops.RHS, "add");
if (isa<llvm::PointerType>(Ops.LHS->getType())) // pointer + int
return Builder.CreateGEP(Ops.LHS, Ops.RHS, "add.ptr");
// int + pointer
return Builder.CreateGEP(Ops.RHS, Ops.LHS, "add.ptr");
}
Value *ScalarExprEmitter::EmitSub(const BinOpInfo &Ops) {
if (!isa<llvm::PointerType>(Ops.LHS->getType()))
return Builder.CreateSub(Ops.LHS, Ops.RHS, "sub");
// FIXME: This isn't right for -=.
QualType LHSTy = Ops.E->getLHS()->getType();
QualType RHSTy = Ops.E->getRHS()->getType();
const PointerType *RHSPtrType = dyn_cast<PointerType>(RHSTy.getTypePtr());
if (RHSPtrType == 0) { // pointer - int
Value *NegatedRHS = Builder.CreateNeg(Ops.RHS, "sub.ptr.neg");
return Builder.CreateGEP(Ops.LHS, NegatedRHS, "sub.ptr");
}
// pointer - pointer
const PointerType *LHSPtrType = cast<PointerType>(LHSTy.getTypePtr());
QualType LHSElementType = LHSPtrType->getPointeeType();
assert(LHSElementType == RHSPtrType->getPointeeType() &&
"can't subtract pointers with differing element types");
uint64_t ElementSize = CGF.getContext().getTypeSize(LHSElementType,
SourceLocation()) / 8;
const llvm::Type *ResultType = ConvertType(Ops.E->getType());
Value *CastLHS = Builder.CreatePtrToInt(Ops.LHS, ResultType,
"sub.ptr.lhs.cast");
Value *CastRHS = Builder.CreatePtrToInt(Ops.RHS, ResultType,
"sub.ptr.rhs.cast");
Value *BytesBetween = Builder.CreateSub(CastLHS, CastRHS,
"sub.ptr.sub");
// 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");
}
// Otherwise, do a full sdiv.
Value *BytesPerElt = llvm::ConstantInt::get(ResultType, ElementSize);
return Builder.CreateSDiv(BytesBetween, BytesPerElt, "sub.ptr.div");
}
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");
if (Ops.E->getType()->isUnsignedIntegerType())
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) {
llvm::Value *Result;
QualType LHSTy = E->getLHS()->getType();
if (!LHSTy->isComplexType()) {
Value *LHS = Visit(E->getLHS());
Value *RHS = Visit(E->getRHS());
if (LHS->getType()->isFloatingPoint()) {
Result = Builder.CreateFCmp((llvm::FCmpInst::Predicate)FCmpOpc,
LHS, RHS, "cmp");
} else if (LHSTy->isUnsignedIntegerType()) {
Result = Builder.CreateICmp((llvm::ICmpInst::Predicate)UICmpOpc,
LHS, RHS, "cmp");
} else {
// Signed integers and pointers.
Result = Builder.CreateICmp((llvm::ICmpInst::Predicate)SICmpOpc,
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();
llvm::Value *ResultR, *ResultI;
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());
// Return the RHS.
return RHS;
}
Value *ScalarExprEmitter::VisitBinLAnd(const BinaryOperator *E) {
Value *LHSCond = CGF.EvaluateExprAsBool(E->getLHS());
llvm::BasicBlock *ContBlock = new llvm::BasicBlock("land_cont");
llvm::BasicBlock *RHSBlock = new llvm::BasicBlock("land_rhs");
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());
llvm::BasicBlock *ContBlock = new llvm::BasicBlock("lor_cont");
llvm::BasicBlock *RHSBlock = new llvm::BasicBlock("lor_rhs");
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) {
llvm::BasicBlock *LHSBlock = new llvm::BasicBlock("cond.?");
llvm::BasicBlock *RHSBlock = new llvm::BasicBlock("cond.:");
llvm::BasicBlock *ContBlock = new llvm::BasicBlock("cond.cont");
Value *Cond = CGF.EvaluateExprAsBool(E->getCond());
Builder.CreateCondBr(Cond, LHSBlock, RHSBlock);
CGF.EmitBlock(LHSBlock);
// Handle the GNU extension for missing LHS.
Value *LHS = E->getLHS() ? Visit(E->getLHS()) : Cond;
Builder.CreateBr(ContBlock);
LHSBlock = Builder.GetInsertBlock();
CGF.EmitBlock(RHSBlock);
Value *RHS = Visit(E->getRHS());
Builder.CreateBr(ContBlock);
RHSBlock = Builder.GetInsertBlock();
CGF.EmitBlock(ContBlock);
// 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) {
llvm::APSInt CondVal(32);
bool IsConst = E->getCond()->isIntegerConstantExpr(CondVal, CGF.getContext());
assert(IsConst && "Condition of choose expr must be i-c-e"); IsConst=IsConst;
// Emit the LHS or RHS as appropriate.
return Visit(CondVal != 0 ? E->getLHS() : E->getRHS());
}
//===----------------------------------------------------------------------===//
// 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));
}

View File

@ -15,14 +15,11 @@
#include "CodeGenModule.h"
#include "clang/AST/Expr.h"
#include "llvm/Constant.h"
using namespace clang;
using namespace CodeGen;
RValue CodeGenFunction::EmitObjCStringLiteral(const ObjCStringLiteral* E)
{
llvm::Value *CodeGenFunction::EmitObjCStringLiteral(const ObjCStringLiteral *E){
std::string S(E->getString()->getStrData(), E->getString()->getByteLength());
return RValue::get(CGM.GetAddrOfConstantCFString(S));
return CGM.GetAddrOfConstantCFString(S);
}

View File

@ -275,8 +275,9 @@ void CodeGenFunction::EmitReturnStmt(const ReturnStmt &S) {
// Emit the result value, even if unused, to evalute the side effects.
const Expr *RV = S.getRetValue();
// FIXME: Handle return of an aggregate!
if (RV)
RetVal = EmitExpr(RV);
if (RV)
// FIXME: This could be much better for return of aggregate: return inplace.
RetVal = EmitAnyExpr(RV);
else // Silence a bogus GCC warning.
RetVal = RValue::get(0);

View File

@ -185,7 +185,6 @@ class CodeGenFunction {
public:
typedef std::pair<llvm::Value *, llvm::Value *> ComplexPairTy;
llvm::LLVMBuilder Builder;
private:
const FunctionDecl *CurFuncDecl;
llvm::Function *CurFn;
@ -197,6 +196,7 @@ private:
const llvm::Type *LLVMIntTy;
unsigned LLVMPointerWidth;
private:
/// LocalDeclMap - This keeps track of the LLVM allocas or globals for local C
/// decls.
llvm::DenseMap<const Decl*, llvm::Value*> LocalDeclMap;
@ -345,29 +345,12 @@ public:
/// result of the expression doesn't need to be generated into memory.
RValue EmitAnyExpr(const Expr *E, bool NeedResult = true);
RValue EmitExpr(const Expr *E);
RValue EmitIntegerLiteral(const IntegerLiteral *E);
RValue EmitFloatingLiteral(const FloatingLiteral *E);
RValue EmitCharacterLiteral(const CharacterLiteral *E);
RValue EmitTypesCompatibleExpr(const TypesCompatibleExpr *E);
RValue EmitImplicitCastExpr(const ImplicitCastExpr *Op);
RValue EmitCastExpr(const Expr *Op, QualType DestTy);
RValue EmitCallExpr(const CallExpr *E);
RValue EmitBuiltinExpr(unsigned builtinID, const CallExpr *E);
RValue EmitArraySubscriptExprRV(const ArraySubscriptExpr *E);
// Unary Operators.
RValue EmitUnaryOperator(const UnaryOperator *E);
RValue EmitUnaryIncDec (const UnaryOperator *E);
RValue EmitUnaryAddrOf (const UnaryOperator *E);
RValue EmitUnaryPlus (const UnaryOperator *E);
RValue EmitUnaryMinus (const UnaryOperator *E);
RValue EmitUnaryNot (const UnaryOperator *E);
RValue EmitUnaryLNot (const UnaryOperator *E);
RValue EmitSizeAlignOf (QualType TypeToSize, QualType RetType,bool isSizeOf);
// FIXME: real/imag
#if 0
RValue EmitExpr(const Expr *E);
// Binary Operators.
RValue EmitBinaryOperator(const BinaryOperator *E);
RValue EmitBinaryMul(const BinaryOperator *E);
@ -398,8 +381,9 @@ public:
// Conditional Operator.
RValue EmitConditionalOperator(const ConditionalOperator *E);
RValue EmitChooseExpr(const ChooseExpr *E);
#endif
RValue EmitObjCStringLiteral(const ObjCStringLiteral* E);
llvm::Value *EmitObjCStringLiteral(const ObjCStringLiteral *E);
//===--------------------------------------------------------------------===//
// Aggregate Expression Emission
@ -408,6 +392,10 @@ public:
void EmitAggregateCopy(llvm::Value *DestPtr, llvm::Value *SrcPtr,
QualType EltTy);
/// EmitScalarExpr - Emit the computation of the specified expression of
/// LLVM scalar type, returning the result.
llvm::Value *EmitScalarExpr(const Expr *E);
/// EmitAggExpr - Emit the computation of the specified expression of
/// aggregate type. The result is computed into DestPtr. Note that if
/// DestPtr is null, the value of the aggregate expression is not needed.

View File

@ -27,6 +27,7 @@
DE1733700B068DC60080B521 /* DeclSpec.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE17336F0B068DC60080B521 /* DeclSpec.h */; };
DE1F22030A7D852A00FBF588 /* Parser.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE1F22020A7D852A00FBF588 /* Parser.h */; };
DE224FF80C7AA98800D370A5 /* CGExprComplex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE224FF70C7AA98800D370A5 /* CGExprComplex.cpp */; };
DE2252700C7E82D000D370A5 /* CGExprScalar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE22526F0C7E82D000D370A5 /* CGExprScalar.cpp */; };
DE344AB80AE5DF6D00DBC861 /* HeaderSearch.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE344AB70AE5DF6D00DBC861 /* HeaderSearch.h */; };
DE344B540AE5E46C00DBC861 /* HeaderSearch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE344B530AE5E46C00DBC861 /* HeaderSearch.cpp */; };
DE3450D70AEB543100DBC861 /* DirectoryLookup.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE3450D60AEB543100DBC861 /* DirectoryLookup.h */; };
@ -220,6 +221,7 @@
DE17336F0B068DC60080B521 /* DeclSpec.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = DeclSpec.h; path = clang/Parse/DeclSpec.h; sourceTree = "<group>"; };
DE1F22020A7D852A00FBF588 /* Parser.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Parser.h; path = clang/Parse/Parser.h; sourceTree = "<group>"; };
DE224FF70C7AA98800D370A5 /* CGExprComplex.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = CGExprComplex.cpp; path = CodeGen/CGExprComplex.cpp; sourceTree = "<group>"; };
DE22526F0C7E82D000D370A5 /* CGExprScalar.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = CGExprScalar.cpp; path = CodeGen/CGExprScalar.cpp; sourceTree = "<group>"; };
DE344AB70AE5DF6D00DBC861 /* HeaderSearch.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = HeaderSearch.h; sourceTree = "<group>"; };
DE344B530AE5E46C00DBC861 /* HeaderSearch.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = HeaderSearch.cpp; sourceTree = "<group>"; };
DE3450D60AEB543100DBC861 /* DirectoryLookup.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DirectoryLookup.h; sourceTree = "<group>"; };
@ -444,6 +446,7 @@
DE4772FB0C10EAEC002239E8 /* CGExpr.cpp */,
DEF2EFF20C6CDD74000C4259 /* CGExprAgg.cpp */,
DE224FF70C7AA98800D370A5 /* CGExprComplex.cpp */,
DE22526F0C7E82D000D370A5 /* CGExprScalar.cpp */,
1A7342470C7B57D500122F56 /* CGObjC.cpp */,
DE4772F90C10EAE5002239E8 /* CGStmt.cpp */,
DE928B120C05659200231DA4 /* ModuleBuilder.cpp */,
@ -704,6 +707,7 @@
DE224FF80C7AA98800D370A5 /* CGExprComplex.cpp in Sources */,
1A7342480C7B57D500122F56 /* CGObjC.cpp in Sources */,
DEC63B1A0C7B940200DBF169 /* CFG.cpp in Sources */,
DE2252700C7E82D000D370A5 /* CGExprScalar.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};