Skip to content

Commit 2ba4e3a

Browse files
author
Melanie Blower
committed
Move BinaryOperators.FPOptions to trailing storage
Reviewers: rjmccall Differential Revision: https://reviews.llvm.org/D76384
1 parent 14d89bf commit 2ba4e3a

23 files changed

+297
-152
lines changed

clang/include/clang/AST/Expr.h

Lines changed: 101 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -3475,17 +3475,36 @@ class BinaryOperator : public Expr {
34753475
public:
34763476
typedef BinaryOperatorKind Opcode;
34773477

3478-
BinaryOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy,
3479-
ExprValueKind VK, ExprObjectKind OK, SourceLocation opLoc,
3480-
FPOptions FPFeatures)
3478+
protected:
3479+
size_t offsetOfTrailingStorage() const;
3480+
3481+
/// Return a pointer to the trailing FPOptions
3482+
FPOptions *getTrailingFPFeatures() {
3483+
assert(BinaryOperatorBits.HasFPFeatures);
3484+
return reinterpret_cast<FPOptions *>(reinterpret_cast<char *>(this) +
3485+
offsetOfTrailingStorage());
3486+
}
3487+
const FPOptions *getTrailingFPFeatures() const {
3488+
assert(BinaryOperatorBits.HasFPFeatures);
3489+
return reinterpret_cast<const FPOptions *>(
3490+
reinterpret_cast<const char *>(this) + offsetOfTrailingStorage());
3491+
}
3492+
3493+
/// Build a binary operator, assuming that appropriate storage has been
3494+
/// allocated for the trailing objects when needed.
3495+
BinaryOperator(const ASTContext &Ctx, Expr *lhs, Expr *rhs, Opcode opc,
3496+
QualType ResTy, ExprValueKind VK, ExprObjectKind OK,
3497+
SourceLocation opLoc, FPOptions FPFeatures)
34813498
: Expr(BinaryOperatorClass, ResTy, VK, OK) {
34823499
BinaryOperatorBits.Opc = opc;
3483-
BinaryOperatorBits.FPFeatures = FPFeatures.getInt();
3500+
assert(!isCompoundAssignmentOp() &&
3501+
"Use CompoundAssignOperator for compound assignments");
34843502
BinaryOperatorBits.OpLoc = opLoc;
34853503
SubExprs[LHS] = lhs;
34863504
SubExprs[RHS] = rhs;
3487-
assert(!isCompoundAssignmentOp() &&
3488-
"Use CompoundAssignOperator for compound assignments");
3505+
BinaryOperatorBits.HasFPFeatures = FPFeatures.requiresTrailingStorage(Ctx);
3506+
if (BinaryOperatorBits.HasFPFeatures)
3507+
*getTrailingFPFeatures() = FPFeatures;
34893508
setDependence(computeDependence(this));
34903509
}
34913510

@@ -3494,6 +3513,13 @@ class BinaryOperator : public Expr {
34943513
BinaryOperatorBits.Opc = BO_Comma;
34953514
}
34963515

3516+
public:
3517+
static BinaryOperator *CreateEmpty(const ASTContext &C, bool hasFPFeatures);
3518+
3519+
static BinaryOperator *Create(const ASTContext &C, Expr *lhs, Expr *rhs,
3520+
Opcode opc, QualType ResTy, ExprValueKind VK,
3521+
ExprObjectKind OK, SourceLocation opLoc,
3522+
FPOptions FPFeatures);
34973523
SourceLocation getExprLoc() const { return getOperatorLoc(); }
34983524
SourceLocation getOperatorLoc() const { return BinaryOperatorBits.OpLoc; }
34993525
void setOperatorLoc(SourceLocation L) { BinaryOperatorBits.OpLoc = L; }
@@ -3634,42 +3660,69 @@ class BinaryOperator : public Expr {
36343660
return const_child_range(&SubExprs[0], &SubExprs[0] + END_EXPR);
36353661
}
36363662

3637-
// Set the FP contractability status of this operator. Only meaningful for
3638-
// operations on floating point types.
3639-
void setFPFeatures(FPOptions F) {
3640-
BinaryOperatorBits.FPFeatures = F.getInt();
3663+
/// Set and fetch the bit that shows whether FPFeatures needs to be
3664+
/// allocated in Trailing Storage
3665+
void setHasStoredFPFeatures(bool B) { BinaryOperatorBits.HasFPFeatures = B; }
3666+
bool hasStoredFPFeatures() const { return BinaryOperatorBits.HasFPFeatures; }
3667+
3668+
/// Get FPFeatures from trailing storage
3669+
FPOptions getStoredFPFeatures() const {
3670+
assert(hasStoredFPFeatures());
3671+
return *getTrailingFPFeatures();
3672+
}
3673+
/// Set FPFeatures in trailing storage, used only by Serialization
3674+
void setStoredFPFeatures(FPOptions F) {
3675+
assert(BinaryOperatorBits.HasFPFeatures);
3676+
*getTrailingFPFeatures() = F;
36413677
}
36423678

3643-
FPOptions getFPFeatures() const {
3644-
return FPOptions(BinaryOperatorBits.FPFeatures);
3679+
// Get the FP features status of this operator. Only meaningful for
3680+
// operations on floating point types.
3681+
FPOptions getFPFeatures(const ASTContext &C) const {
3682+
if (BinaryOperatorBits.HasFPFeatures)
3683+
return getStoredFPFeatures();
3684+
return FPOptions::defaultWithoutTrailingStorage(C);
36453685
}
36463686

36473687
// Get the FP contractability status of this operator. Only meaningful for
36483688
// operations on floating point types.
3649-
bool isFPContractableWithinStatement() const {
3650-
return getFPFeatures().allowFPContractWithinStatement();
3689+
bool isFPContractableWithinStatement(const ASTContext &C) const {
3690+
return getFPFeatures(C).allowFPContractWithinStatement();
36513691
}
36523692

36533693
// Get the FENV_ACCESS status of this operator. Only meaningful for
36543694
// operations on floating point types.
3655-
bool isFEnvAccessOn() const { return getFPFeatures().allowFEnvAccess(); }
3695+
bool isFEnvAccessOn(const ASTContext &C) const {
3696+
return getFPFeatures(C).allowFEnvAccess();
3697+
}
36563698

36573699
protected:
3658-
BinaryOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy,
3659-
ExprValueKind VK, ExprObjectKind OK, SourceLocation opLoc,
3660-
FPOptions FPFeatures, bool dead2)
3700+
BinaryOperator(const ASTContext &Ctx, Expr *lhs, Expr *rhs, Opcode opc,
3701+
QualType ResTy, ExprValueKind VK, ExprObjectKind OK,
3702+
SourceLocation opLoc, FPOptions FPFeatures, bool dead2)
36613703
: Expr(CompoundAssignOperatorClass, ResTy, VK, OK) {
36623704
BinaryOperatorBits.Opc = opc;
3663-
BinaryOperatorBits.FPFeatures = FPFeatures.getInt();
3705+
assert(isCompoundAssignmentOp() &&
3706+
"Use CompoundAssignOperator for compound assignments");
36643707
BinaryOperatorBits.OpLoc = opLoc;
36653708
SubExprs[LHS] = lhs;
36663709
SubExprs[RHS] = rhs;
3710+
BinaryOperatorBits.HasFPFeatures = FPFeatures.requiresTrailingStorage(Ctx);
3711+
if (BinaryOperatorBits.HasFPFeatures)
3712+
*getTrailingFPFeatures() = FPFeatures;
36673713
setDependence(computeDependence(this));
36683714
}
36693715

3716+
/// Construct an empty BinaryOperator, SC is CompoundAssignOperator.
36703717
BinaryOperator(StmtClass SC, EmptyShell Empty) : Expr(SC, Empty) {
36713718
BinaryOperatorBits.Opc = BO_MulAssign;
36723719
}
3720+
3721+
/// Return the size in bytes needed for the trailing objects.
3722+
/// Used to allocate the right amount of storage.
3723+
static unsigned sizeOfTrailingObjects(bool HasFPFeatures) {
3724+
return HasFPFeatures * sizeof(FPOptions);
3725+
}
36733726
};
36743727

36753728
/// CompoundAssignOperator - For compound assignments (e.g. +=), we keep
@@ -3681,22 +3734,33 @@ class BinaryOperator : public Expr {
36813734
class CompoundAssignOperator : public BinaryOperator {
36823735
QualType ComputationLHSType;
36833736
QualType ComputationResultType;
3684-
public:
3685-
CompoundAssignOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResType,
3686-
ExprValueKind VK, ExprObjectKind OK,
3687-
QualType CompLHSType, QualType CompResultType,
3688-
SourceLocation OpLoc, FPOptions FPFeatures)
3689-
: BinaryOperator(lhs, rhs, opc, ResType, VK, OK, OpLoc, FPFeatures,
3690-
true),
3691-
ComputationLHSType(CompLHSType),
3692-
ComputationResultType(CompResultType) {
3737+
3738+
/// Construct an empty CompoundAssignOperator.
3739+
explicit CompoundAssignOperator(const ASTContext &C, EmptyShell Empty,
3740+
bool hasFPFeatures)
3741+
: BinaryOperator(CompoundAssignOperatorClass, Empty) {}
3742+
3743+
protected:
3744+
CompoundAssignOperator(const ASTContext &C, Expr *lhs, Expr *rhs, Opcode opc,
3745+
QualType ResType, ExprValueKind VK, ExprObjectKind OK,
3746+
SourceLocation OpLoc, FPOptions FPFeatures,
3747+
QualType CompLHSType, QualType CompResultType)
3748+
: BinaryOperator(C, lhs, rhs, opc, ResType, VK, OK, OpLoc, FPFeatures,
3749+
true),
3750+
ComputationLHSType(CompLHSType), ComputationResultType(CompResultType) {
36933751
assert(isCompoundAssignmentOp() &&
36943752
"Only should be used for compound assignments");
36953753
}
36963754

3697-
/// Build an empty compound assignment operator expression.
3698-
explicit CompoundAssignOperator(EmptyShell Empty)
3699-
: BinaryOperator(CompoundAssignOperatorClass, Empty) { }
3755+
public:
3756+
static CompoundAssignOperator *CreateEmpty(const ASTContext &C,
3757+
bool hasFPFeatures);
3758+
3759+
static CompoundAssignOperator *
3760+
Create(const ASTContext &C, Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy,
3761+
ExprValueKind VK, ExprObjectKind OK, SourceLocation opLoc,
3762+
FPOptions FPFeatures, QualType CompLHSType = QualType(),
3763+
QualType CompResultType = QualType());
37003764

37013765
// The two computation types are the type the LHS is converted
37023766
// to for the computation and the type of the result; the two are
@@ -3712,6 +3776,12 @@ class CompoundAssignOperator : public BinaryOperator {
37123776
}
37133777
};
37143778

3779+
inline size_t BinaryOperator::offsetOfTrailingStorage() const {
3780+
assert(BinaryOperatorBits.HasFPFeatures);
3781+
return isa<CompoundAssignOperator>(this) ? sizeof(CompoundAssignOperator)
3782+
: sizeof(BinaryOperator);
3783+
}
3784+
37153785
/// AbstractConditionalOperator - An abstract base class for
37163786
/// ConditionalOperator and BinaryConditionalOperator.
37173787
class AbstractConditionalOperator : public Expr {

clang/include/clang/AST/ExprCXX.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ class CXXOperatorCallExpr final : public CallExpr {
166166
// Set the FP contractability status of this operator. Only meaningful for
167167
// operations on floating point types.
168168
void setFPFeatures(FPOptions F) {
169-
CXXOperatorCallExprBits.FPFeatures = F.getInt();
169+
CXXOperatorCallExprBits.FPFeatures = F.getAsOpaqueInt();
170170
}
171171
FPOptions getFPFeatures() const {
172172
return FPOptions(CXXOperatorCallExprBits.FPFeatures);

clang/include/clang/AST/Stmt.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -525,8 +525,9 @@ class alignas(void *) Stmt {
525525
unsigned Opc : 6;
526526

527527
/// This is only meaningful for operations on floating point
528-
/// types and 0 otherwise.
529-
unsigned FPFeatures : 8;
528+
/// types when additional values need to be in trailing storage.
529+
/// It is 0 otherwise.
530+
unsigned HasFPFeatures : 1;
530531

531532
SourceLocation OpLoc;
532533
};

clang/include/clang/Basic/LangOptions.h

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727

2828
namespace clang {
2929

30+
class ASTContext;
31+
3032
/// Bitfields of LangOptions, split out from LangOptions in order to ensure that
3133
/// this large collection of bitfields is a trivial class type.
3234
class LangOptionsBase {
@@ -399,6 +401,14 @@ class FPOptions {
399401
{}
400402
// FIXME: Use getDefaultFEnvAccessMode() when available.
401403

404+
/// Return the default value of FPOptions that's used when trailing
405+
/// storage isn't required.
406+
static FPOptions defaultWithoutTrailingStorage(const ASTContext &C);
407+
408+
/// Does this FPOptions require trailing storage when stored in various
409+
/// AST nodes, or can it be recreated using `defaultWithoutTrailingStorage`?
410+
bool requiresTrailingStorage(const ASTContext &C);
411+
402412
bool allowFPContractWithinStatement() const {
403413
return fp_contract == LangOptions::FPC_On;
404414
}
@@ -450,9 +460,9 @@ class FPOptions {
450460
}
451461

452462
/// Used to serialize this.
453-
unsigned getInt() const {
454-
return fp_contract | (fenv_access << 2) | (rounding << 3)
455-
| (exceptions << 6);
463+
unsigned getAsOpaqueInt() const {
464+
return fp_contract | (fenv_access << 2) | (rounding << 3) |
465+
(exceptions << 6);
456466
}
457467

458468
private:

clang/lib/AST/ASTImporter.cpp

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6703,9 +6703,10 @@ ExpectedStmt ASTNodeImporter::VisitBinaryOperator(BinaryOperator *E) {
67036703
if (Err)
67046704
return std::move(Err);
67056705

6706-
return new (Importer.getToContext()) BinaryOperator(
6707-
ToLHS, ToRHS, E->getOpcode(), ToType, E->getValueKind(),
6708-
E->getObjectKind(), ToOperatorLoc, E->getFPFeatures());
6706+
return BinaryOperator::Create(Importer.getToContext(), ToLHS, ToRHS,
6707+
E->getOpcode(), ToType, E->getValueKind(),
6708+
E->getObjectKind(), ToOperatorLoc,
6709+
E->getFPFeatures(Importer.getFromContext()));
67096710
}
67106711

67116712
ExpectedStmt ASTNodeImporter::VisitConditionalOperator(ConditionalOperator *E) {
@@ -6813,10 +6814,12 @@ ASTNodeImporter::VisitCompoundAssignOperator(CompoundAssignOperator *E) {
68136814
if (Err)
68146815
return std::move(Err);
68156816

6816-
return new (Importer.getToContext()) CompoundAssignOperator(
6817-
ToLHS, ToRHS, E->getOpcode(), ToType, E->getValueKind(),
6818-
E->getObjectKind(), ToComputationLHSType, ToComputationResultType,
6819-
ToOperatorLoc, E->getFPFeatures());
6817+
return CompoundAssignOperator::Create(
6818+
Importer.getToContext(), ToLHS, ToRHS, E->getOpcode(), ToType,
6819+
E->getValueKind(), E->getObjectKind(), ToOperatorLoc,
6820+
E->getFPFeatures(Importer.getFromContext()),
6821+
importChecked(Err, ToComputationLHSType),
6822+
importChecked(Err, ToComputationResultType));
68206823
}
68216824

68226825
Expected<CXXCastPath>

clang/lib/AST/Expr.cpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4347,6 +4347,48 @@ ParenListExpr *ParenListExpr::CreateEmpty(const ASTContext &Ctx,
43474347
return new (Mem) ParenListExpr(EmptyShell(), NumExprs);
43484348
}
43494349

4350+
BinaryOperator *BinaryOperator::CreateEmpty(const ASTContext &C,
4351+
bool HasFPFeatures) {
4352+
unsigned Extra = sizeOfTrailingObjects(HasFPFeatures);
4353+
void *Mem =
4354+
C.Allocate(sizeof(BinaryOperator) + Extra, alignof(BinaryOperator));
4355+
return new (Mem) BinaryOperator(EmptyShell());
4356+
}
4357+
4358+
BinaryOperator *BinaryOperator::Create(const ASTContext &C, Expr *lhs,
4359+
Expr *rhs, Opcode opc, QualType ResTy,
4360+
ExprValueKind VK, ExprObjectKind OK,
4361+
SourceLocation opLoc,
4362+
FPOptions FPFeatures) {
4363+
bool HasFPFeatures = FPFeatures.requiresTrailingStorage(C);
4364+
unsigned Extra = sizeOfTrailingObjects(HasFPFeatures);
4365+
void *Mem =
4366+
C.Allocate(sizeof(BinaryOperator) + Extra, alignof(BinaryOperator));
4367+
return new (Mem)
4368+
BinaryOperator(C, lhs, rhs, opc, ResTy, VK, OK, opLoc, FPFeatures);
4369+
}
4370+
4371+
CompoundAssignOperator *
4372+
CompoundAssignOperator::CreateEmpty(const ASTContext &C, bool HasFPFeatures) {
4373+
unsigned Extra = sizeOfTrailingObjects(HasFPFeatures);
4374+
void *Mem = C.Allocate(sizeof(CompoundAssignOperator) + Extra,
4375+
alignof(CompoundAssignOperator));
4376+
return new (Mem) CompoundAssignOperator(C, EmptyShell(), HasFPFeatures);
4377+
}
4378+
4379+
CompoundAssignOperator *CompoundAssignOperator::Create(
4380+
const ASTContext &C, Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy,
4381+
ExprValueKind VK, ExprObjectKind OK, SourceLocation opLoc,
4382+
FPOptions FPFeatures, QualType CompLHSType, QualType CompResultType) {
4383+
bool HasFPFeatures = FPFeatures.requiresTrailingStorage(C);
4384+
unsigned Extra = sizeOfTrailingObjects(HasFPFeatures);
4385+
void *Mem = C.Allocate(sizeof(CompoundAssignOperator) + Extra,
4386+
alignof(CompoundAssignOperator));
4387+
return new (Mem)
4388+
CompoundAssignOperator(C, lhs, rhs, opc, ResTy, VK, OK, opLoc, FPFeatures,
4389+
CompLHSType, CompResultType);
4390+
}
4391+
43504392
const OpaqueValueExpr *OpaqueValueExpr::findInCopyConstruct(const Expr *e) {
43514393
if (const ExprWithCleanups *ewc = dyn_cast<ExprWithCleanups>(e))
43524394
e = ewc->getSubExpr();

clang/lib/AST/ExprCXX.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -530,11 +530,11 @@ CXXOperatorCallExpr::CXXOperatorCallExpr(OverloadedOperatorKind OpKind,
530530
: CallExpr(CXXOperatorCallExprClass, Fn, /*PreArgs=*/{}, Args, Ty, VK,
531531
OperatorLoc, /*MinNumArgs=*/0, UsesADL) {
532532
CXXOperatorCallExprBits.OperatorKind = OpKind;
533-
CXXOperatorCallExprBits.FPFeatures = FPFeatures.getInt();
533+
CXXOperatorCallExprBits.FPFeatures = FPFeatures.getAsOpaqueInt();
534534
assert(
535535
(CXXOperatorCallExprBits.OperatorKind == static_cast<unsigned>(OpKind)) &&
536536
"OperatorKind overflow!");
537-
assert((CXXOperatorCallExprBits.FPFeatures == FPFeatures.getInt()) &&
537+
assert((CXXOperatorCallExprBits.FPFeatures == FPFeatures.getAsOpaqueInt()) &&
538538
"FPFeatures overflow!");
539539
Range = getSourceRangeImpl();
540540
}
@@ -1639,4 +1639,4 @@ CUDAKernelCallExpr *CUDAKernelCallExpr::CreateEmpty(const ASTContext &Ctx,
16391639
void *Mem = Ctx.Allocate(sizeof(CUDAKernelCallExpr) + SizeOfTrailingObjects,
16401640
alignof(CUDAKernelCallExpr));
16411641
return new (Mem) CUDAKernelCallExpr(NumArgs, Empty);
1642-
}
1642+
}

clang/lib/Analysis/BodyFarm.cpp

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -114,21 +114,20 @@ class ASTMaker {
114114

115115
BinaryOperator *ASTMaker::makeAssignment(const Expr *LHS, const Expr *RHS,
116116
QualType Ty) {
117-
return new (C) BinaryOperator(const_cast<Expr*>(LHS), const_cast<Expr*>(RHS),
118-
BO_Assign, Ty, VK_RValue,
119-
OK_Ordinary, SourceLocation(), FPOptions());
117+
return BinaryOperator::Create(
118+
C, const_cast<Expr *>(LHS), const_cast<Expr *>(RHS), BO_Assign, Ty,
119+
VK_RValue, OK_Ordinary, SourceLocation(), FPOptions(C.getLangOpts()));
120120
}
121121

122122
BinaryOperator *ASTMaker::makeComparison(const Expr *LHS, const Expr *RHS,
123123
BinaryOperator::Opcode Op) {
124124
assert(BinaryOperator::isLogicalOp(Op) ||
125125
BinaryOperator::isComparisonOp(Op));
126-
return new (C) BinaryOperator(const_cast<Expr*>(LHS),
127-
const_cast<Expr*>(RHS),
128-
Op,
129-
C.getLogicalOperationType(),
130-
VK_RValue,
131-
OK_Ordinary, SourceLocation(), FPOptions());
126+
return BinaryOperator::Create(C, const_cast<Expr *>(LHS),
127+
const_cast<Expr *>(RHS), Op,
128+
C.getLogicalOperationType(), VK_RValue,
129+
OK_Ordinary, SourceLocation(),
130+
FPOptions(C.getLangOpts()));
132131
}
133132

134133
CompoundStmt *ASTMaker::makeCompound(ArrayRef<Stmt *> Stmts) {
@@ -296,7 +295,8 @@ static CallExpr *create_call_once_lambda_call(ASTContext &C, ASTMaker M,
296295
/*Args=*/CallArgs,
297296
/*QualType=*/C.VoidTy,
298297
/*ExprValueType=*/VK_RValue,
299-
/*SourceLocation=*/SourceLocation(), FPOptions());
298+
/*SourceLocation=*/SourceLocation(),
299+
/*FPFeatures=*/FPOptions(C.getLangOpts()));
300300
}
301301

302302
/// Create a fake body for std::call_once.

0 commit comments

Comments
 (0)