mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-26 00:56:05 +00:00
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:
parent
cc778061e5
commit
4647a21825
@ -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]);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user