From 9b65551d0b387a7597fb39356a4d8ef10046445e Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Fri, 31 Aug 2007 22:49:20 +0000 Subject: [PATCH] Generalize RValue to handle complex better, generalize EmitCompoundStmt to support any sort of expr, add a new EmitAnyExpr routine. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@41660 91177308-0d34-0410-b5e6-96231b3b80d8 --- CodeGen/CGExpr.cpp | 26 +++++++++++++--- CodeGen/CGExprComplex.cpp | 9 ++++-- CodeGen/CGExprScalar.cpp | 8 ++--- CodeGen/CGStmt.cpp | 14 +++------ CodeGen/CodeGenFunction.h | 64 ++++++++++++++++++++++++++++----------- 5 files changed, 84 insertions(+), 37 deletions(-) diff --git a/CodeGen/CGExpr.cpp b/CodeGen/CGExpr.cpp index d175610a38..d5a5c3f258 100644 --- a/CodeGen/CGExpr.cpp +++ b/CodeGen/CGExpr.cpp @@ -44,6 +44,22 @@ llvm::Value *CodeGenFunction::EvaluateExprAsBool(const Expr *E) { return EmitComplexToScalarConversion(EmitComplexExpr(E), E->getType(),BoolTy); } +/// EmitAnyExpr - Emit code to compute the specified expression which can have +/// any type. The result is returned as an RValue struct. If this is an +/// aggregate expression, the aggloc/agglocvolatile arguments indicate where +/// the result should be returned. +RValue CodeGenFunction::EmitAnyExpr(const Expr *E, llvm::Value *AggLoc, + bool isAggLocVolatile) { + if (!hasAggregateLLVMType(E->getType())) + return RValue::get(EmitScalarExpr(E)); + else if (E->getType()->isComplexType()) + return RValue::getComplex(EmitComplexExpr(E)); + + EmitAggExpr(E, AggLoc, isAggLocVolatile); + return RValue::getAggregate(AggLoc); +} + + //===----------------------------------------------------------------------===// // LValue Expression Emission //===----------------------------------------------------------------------===// @@ -185,7 +201,7 @@ void CodeGenFunction::EmitStoreThroughLValue(RValue Src, LValue Dst, // Read/modify/write the vector, inserting the new element. // FIXME: Volatility. llvm::Value *Vec = Builder.CreateLoad(Dst.getVectorAddr(), "tmp"); - Vec = Builder.CreateInsertElement(Vec, Src.getVal(), + Vec = Builder.CreateInsertElement(Vec, Src.getScalarVal(), Dst.getVectorIdx(), "vecins"); Builder.CreateStore(Vec, Dst.getVectorAddr()); return; @@ -201,14 +217,14 @@ void CodeGenFunction::EmitStoreThroughLValue(RValue Src, LValue Dst, llvm::Value *DstAddr = Dst.getAddress(); assert(Src.isScalar() && "Can't emit an agg store with this method"); // FIXME: Handle volatility etc. - const llvm::Type *SrcTy = Src.getVal()->getType(); + const llvm::Type *SrcTy = Src.getScalarVal()->getType(); const llvm::Type *AddrTy = cast(DstAddr->getType())->getElementType(); if (AddrTy != SrcTy) DstAddr = Builder.CreateBitCast(DstAddr, llvm::PointerType::get(SrcTy), "storetmp"); - Builder.CreateStore(Src.getVal(), DstAddr); + Builder.CreateStore(Src.getScalarVal(), DstAddr); } void CodeGenFunction::EmitStoreThroughOCUComponentLValue(RValue Src, LValue Dst, @@ -219,7 +235,7 @@ void CodeGenFunction::EmitStoreThroughOCUComponentLValue(RValue Src, LValue Dst, // FIXME: Volatility. unsigned EncFields = Dst.getOCUVectorElts(); - llvm::Value *SrcVal = Src.getVal(); + llvm::Value *SrcVal = Src.getScalarVal(); if (const VectorType *VTy = Ty->getAsVectorType()) { unsigned NumSrcElts = VTy->getNumElements(); @@ -425,6 +441,8 @@ RValue CodeGenFunction::EmitCallExpr(llvm::Value *Callee, const CallExpr *E) { llvm::Value *V = Builder.CreateCall(Callee, &Args[0], &Args[0]+Args.size()); if (V->getType() != llvm::Type::VoidTy) V->setName("call"); + else if (E->getType()->isComplexType()) + return RValue::getComplex(LoadComplexFromAddr(Args[0], false)); else if (hasAggregateLLVMType(E->getType())) // Struct return. return RValue::getAggregate(Args[0]); diff --git a/CodeGen/CGExprComplex.cpp b/CodeGen/CGExprComplex.cpp index 6e7996a051..e4598c41f3 100644 --- a/CodeGen/CGExprComplex.cpp +++ b/CodeGen/CGExprComplex.cpp @@ -239,8 +239,7 @@ VisitImaginaryLiteral(const ImaginaryLiteral *IL) { ComplexPairTy ComplexExprEmitter::VisitCallExpr(const CallExpr *E) { - llvm::Value *AggPtr = CGF.EmitCallExpr(E).getAggregateAddr(); - return EmitLoadOfComplex(AggPtr, false); + return CGF.EmitCallExpr(E).getComplexVal(); } /// EmitComplexToComplexCast - Emit a cast from complex value Val to DestType. @@ -511,3 +510,9 @@ void CodeGenFunction::EmitComplexExprIntoAddr(const Expr *E, ComplexPairTy Val = Emitter.Visit(const_cast(E)); Emitter.EmitStoreOfComplex(Val, DestAddr, DestIsVolatile); } + +/// LoadComplexFromAddr - Load a complex number from the specified address. +ComplexPairTy CodeGenFunction::LoadComplexFromAddr(llvm::Value *SrcAddr, + bool SrcIsVolatile) { + return ComplexExprEmitter(*this).EmitLoadOfComplex(SrcAddr, SrcIsVolatile); +} diff --git a/CodeGen/CGExprScalar.cpp b/CodeGen/CGExprScalar.cpp index db0e6bf492..1cc33bdf18 100644 --- a/CodeGen/CGExprScalar.cpp +++ b/CodeGen/CGExprScalar.cpp @@ -51,7 +51,7 @@ public: LValue EmitLValue(const Expr *E) { return CGF.EmitLValue(E); } Value *EmitLoadOfLValue(LValue LV, QualType T) { - return CGF.EmitLoadOfLValue(LV, T).getVal(); + return CGF.EmitLoadOfLValue(LV, T).getScalarVal(); } /// EmitLoadOfLValue - Given an expression with complex type that represents a @@ -126,7 +126,7 @@ public: Value *EmitCastExpr(const Expr *E, QualType T); Value *VisitCallExpr(const CallExpr *E) { - return CGF.EmitCallExpr(E).getVal(); + return CGF.EmitCallExpr(E).getScalarVal(); } Value *VisitStmtExpr(const StmtExpr *E); @@ -440,7 +440,7 @@ Value *ScalarExprEmitter::EmitCastExpr(const Expr *E, QualType DestTy) { } Value *ScalarExprEmitter::VisitStmtExpr(const StmtExpr *E) { - return CGF.EmitCompoundStmt(*E->getSubStmt(), true).getVal(); + return CGF.EmitCompoundStmt(*E->getSubStmt(), true).getScalarVal(); } @@ -453,7 +453,7 @@ Value *ScalarExprEmitter::VisitPrePostIncDec(const UnaryOperator *E, LValue LV = EmitLValue(E->getSubExpr()); // FIXME: Handle volatile! Value *InVal = CGF.EmitLoadOfLValue(LV, // false - E->getSubExpr()->getType()).getVal(); + E->getSubExpr()->getType()).getScalarVal(); int AmountVal = isInc ? 1 : -1; diff --git a/CodeGen/CGStmt.cpp b/CodeGen/CGStmt.cpp index 85a6ca8705..3a4fd9576a 100644 --- a/CodeGen/CGStmt.cpp +++ b/CodeGen/CGStmt.cpp @@ -63,7 +63,8 @@ void CodeGenFunction::EmitStmt(const Stmt *S) { /// EmitCompoundStmt - Emit a compound statement {..} node. If GetLast is true, /// this captures the expression result of the last sub-statement and returns it /// (for use by the statement expression extension). -RValue CodeGenFunction::EmitCompoundStmt(const CompoundStmt &S, bool GetLast) { +RValue CodeGenFunction::EmitCompoundStmt(const CompoundStmt &S, bool GetLast, + llvm::Value *AggLoc, bool isAggVol) { // FIXME: handle vla's etc. if (S.body_empty() || !isa(S.body_back())) GetLast = false; @@ -74,15 +75,8 @@ RValue CodeGenFunction::EmitCompoundStmt(const CompoundStmt &S, bool GetLast) { if (!GetLast) return RValue::get(0); - - const Expr *Last = cast(S.body_back()); - if (!hasAggregateLLVMType(Last->getType())) - return RValue::get(EmitScalarExpr(Last)); - assert(0 && "Unimp"); - //else if (Last->getType()->isComplexType()) - // EmitComplexExpr(Last); - //else - // EmitAggExpr(E, 0, false); + + return EmitAnyExpr(cast(S.body_back()), AggLoc); } void CodeGenFunction::EmitBlock(llvm::BasicBlock *BB) { diff --git a/CodeGen/CodeGenFunction.h b/CodeGen/CodeGenFunction.h index a597f43268..318368d5eb 100644 --- a/CodeGen/CodeGenFunction.h +++ b/CodeGen/CodeGenFunction.h @@ -71,44 +71,65 @@ namespace CodeGen { /// RValue - This trivial value class is used to represent the result of an -/// expression that is evaluated. It can be one of two things: either a simple -/// LLVM SSA value, or the address of an aggregate value in memory. These two -/// possibilities are discriminated by isAggregate/isScalar. +/// expression that is evaluated. It can be one of three things: either a +/// simple LLVM SSA value, a pair of SSA values for complex numbers, or the +/// address of an aggregate value in memory. class RValue { - llvm::Value *V; + llvm::Value *V1, *V2; // TODO: Encode this into the low bit of pointer for more efficient // return-by-value. - bool IsAggregate; + enum { Scalar, Complex, Aggregate } Flavor; // FIXME: Aggregate rvalues need to retain information about whether they are // volatile or not. public: - bool isAggregate() const { return IsAggregate; } - bool isScalar() const { return !IsAggregate; } + bool isScalar() const { return Flavor == Scalar; } + bool isComplex() const { return Flavor == Complex; } + bool isAggregate() const { return Flavor == Aggregate; } - /// getVal() - Return the Value* of this scalar value. - llvm::Value *getVal() const { - assert(!isAggregate() && "Not a scalar!"); - return V; + /// getScalar() - Return the Value* of this scalar value. + llvm::Value *getScalarVal() const { + assert(isScalar() && "Not a scalar!"); + return V1; } + /// getComplexVal - Return the real/imag components of this complex value. + /// + std::pair getComplexVal() const { + return std::pair(V1, V2); + } + /// getAggregateAddr() - Return the Value* of the address of the aggregate. llvm::Value *getAggregateAddr() const { assert(isAggregate() && "Not an aggregate!"); - return V; + return V1; } static RValue get(llvm::Value *V) { RValue ER; - ER.V = V; - ER.IsAggregate = false; + ER.V1 = V; + ER.Flavor = Scalar; + return ER; + } + static RValue getComplex(llvm::Value *V1, llvm::Value *V2) { + RValue ER; + ER.V1 = V1; + ER.V2 = V2; + ER.Flavor = Complex; + return ER; + } + static RValue getComplex(const std::pair &C) { + RValue ER; + ER.V1 = C.first; + ER.V2 = C.second; + ER.Flavor = Complex; return ER; } static RValue getAggregate(llvm::Value *V) { RValue ER; - ER.V = V; - ER.IsAggregate = true; + ER.V1 = V; + ER.Flavor = Aggregate; return ER; } }; @@ -249,6 +270,12 @@ public: /// expression and compare the result against zero, returning an Int1Ty value. llvm::Value *EvaluateExprAsBool(const Expr *E); + /// EmitAnyExpr - Emit code to compute the specified expression which can have + /// any type. The result is returned as an RValue struct. If this is an + /// aggregate expression, the aggloc/agglocvolatile arguments indicate where + /// the result should be returned. + RValue EmitAnyExpr(const Expr *E, llvm::Value *AggLoc = 0, + bool isAggLocVolatile = false); //===--------------------------------------------------------------------===// // Declaration Emission @@ -265,7 +292,8 @@ public: //===--------------------------------------------------------------------===// void EmitStmt(const Stmt *S); - RValue EmitCompoundStmt(const CompoundStmt &S, bool GetLast = false); + RValue EmitCompoundStmt(const CompoundStmt &S, bool GetLast = false, + llvm::Value *AggLoc = 0, bool isAggVol = false); void EmitLabelStmt(const LabelStmt &S); void EmitGotoStmt(const GotoStmt &S); void EmitIfStmt(const IfStmt &S); @@ -364,6 +392,8 @@ public: /// of complex type, storing into the specified Value*. void EmitComplexExprIntoAddr(const Expr *E, llvm::Value *DestAddr, bool DestIsVolatile); + /// LoadComplexFromAddr - Load a complex number from the specified address. + ComplexPairTy LoadComplexFromAddr(llvm::Value *SrcAddr, bool SrcIsVolatile); }; } // end namespace CodeGen } // end namespace clang -- 2.40.0