зеркало из https://github.com/microsoft/clang-1.git
Use the more general Evaluate infrastructure for folding constant DeclRefs
instead of checking explicitly for an EnumConstantDecl. This folds references to constant integer VarDecls, which has two benefits: 1. Slightly smaller emitted code from emitting a constant instead of a load, and skipping emitting some constant globals. 2. Some code forgets to define static constant member variables; emitting a load instead of the value in that case leads to a link error. (Such programs are technically not well-formed, but in practice build with g++.) git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@89934 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
7622cd3410
Коммит
28665272c3
|
@ -141,8 +141,11 @@ public:
|
||||||
|
|
||||||
// l-values.
|
// l-values.
|
||||||
Value *VisitDeclRefExpr(DeclRefExpr *E) {
|
Value *VisitDeclRefExpr(DeclRefExpr *E) {
|
||||||
if (const EnumConstantDecl *EC = dyn_cast<EnumConstantDecl>(E->getDecl()))
|
Expr::EvalResult Result;
|
||||||
return llvm::ConstantInt::get(VMContext, EC->getInitVal());
|
if (E->Evaluate(Result, CGF.getContext()) && Result.Val.isInt()) {
|
||||||
|
assert(!Result.HasSideEffects && "Constant declref with side-effect?!");
|
||||||
|
return llvm::ConstantInt::get(VMContext, Result.Val.getInt());
|
||||||
|
}
|
||||||
return EmitLoadOfLValue(E);
|
return EmitLoadOfLValue(E);
|
||||||
}
|
}
|
||||||
Value *VisitObjCSelectorExpr(ObjCSelectorExpr *E) {
|
Value *VisitObjCSelectorExpr(ObjCSelectorExpr *E) {
|
||||||
|
@ -167,21 +170,7 @@ public:
|
||||||
|
|
||||||
Value *VisitArraySubscriptExpr(ArraySubscriptExpr *E);
|
Value *VisitArraySubscriptExpr(ArraySubscriptExpr *E);
|
||||||
Value *VisitShuffleVectorExpr(ShuffleVectorExpr *E);
|
Value *VisitShuffleVectorExpr(ShuffleVectorExpr *E);
|
||||||
Value *VisitMemberExpr(MemberExpr *E) {
|
Value *VisitMemberExpr(MemberExpr *E);
|
||||||
if (const EnumConstantDecl *EC =
|
|
||||||
dyn_cast<EnumConstantDecl>(E->getMemberDecl())) {
|
|
||||||
|
|
||||||
// We still need to emit the base.
|
|
||||||
if (E->isArrow())
|
|
||||||
CGF.EmitScalarExpr(E->getBase());
|
|
||||||
else
|
|
||||||
CGF.EmitLValue(E->getBase());
|
|
||||||
return llvm::ConstantInt::get(VMContext, EC->getInitVal());
|
|
||||||
}
|
|
||||||
|
|
||||||
return EmitLoadOfLValue(E);
|
|
||||||
}
|
|
||||||
|
|
||||||
Value *VisitExtVectorElementExpr(Expr *E) { return EmitLoadOfLValue(E); }
|
Value *VisitExtVectorElementExpr(Expr *E) { return EmitLoadOfLValue(E); }
|
||||||
Value *VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
|
Value *VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
|
||||||
return EmitLoadOfLValue(E);
|
return EmitLoadOfLValue(E);
|
||||||
|
@ -572,6 +561,17 @@ Value *ScalarExprEmitter::VisitShuffleVectorExpr(ShuffleVectorExpr *E) {
|
||||||
Value* SV = llvm::ConstantVector::get(indices.begin(), indices.size());
|
Value* SV = llvm::ConstantVector::get(indices.begin(), indices.size());
|
||||||
return Builder.CreateShuffleVector(V1, V2, SV, "shuffle");
|
return Builder.CreateShuffleVector(V1, V2, SV, "shuffle");
|
||||||
}
|
}
|
||||||
|
Value *ScalarExprEmitter::VisitMemberExpr(MemberExpr *E) {
|
||||||
|
Expr::EvalResult Result;
|
||||||
|
if (E->Evaluate(Result, CGF.getContext()) && Result.Val.isInt()) {
|
||||||
|
if (E->isArrow())
|
||||||
|
CGF.EmitScalarExpr(E->getBase());
|
||||||
|
else
|
||||||
|
EmitLValue(E->getBase());
|
||||||
|
return llvm::ConstantInt::get(VMContext, Result.Val.getInt());
|
||||||
|
}
|
||||||
|
return EmitLoadOfLValue(E);
|
||||||
|
}
|
||||||
|
|
||||||
Value *ScalarExprEmitter::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
|
Value *ScalarExprEmitter::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
|
||||||
TestAndClearIgnoreResultAssign();
|
TestAndClearIgnoreResultAssign();
|
||||||
|
|
Загрузка…
Ссылка в новой задаче