Generalize RValue to handle complex better, generalize EmitCompoundStmt to

support any sort of expr, add a new EmitAnyExpr routine.

llvm-svn: 41660
This commit is contained in:
Chris Lattner 2007-08-31 22:49:20 +00:00
parent cc778061e5
commit 4647a21825
5 changed files with 84 additions and 37 deletions

View File

@ -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<llvm::PointerType>(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]);

View File

@ -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<Expr*>(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);
}

View File

@ -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;

View File

@ -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<Expr>(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<Expr>(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<Expr>(S.body_back()), AggLoc);
}
void CodeGenFunction::EmitBlock(llvm::BasicBlock *BB) {

View File

@ -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<llvm::Value *, llvm::Value *> getComplexVal() const {
return std::pair<llvm::Value *, llvm::Value *>(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<llvm::Value *, llvm::Value *> &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