1919#include " clang/AST/CharUnits.h"
2020#include " clang/AST/Type.h"
2121
22- #include " llvm/ADT/PointerIntPair.h"
23-
2422#include " mlir/IR/Value.h"
2523
2624#include " clang/CIR/MissingFeatures.h"
@@ -34,28 +32,85 @@ namespace clang::CIRGen {
3432class RValue {
3533 enum Flavor { Scalar, Complex, Aggregate };
3634
37- // Stores first value and flavor.
38- llvm::PointerIntPair<mlir::Value, 2 , Flavor> v1;
39- // Stores second value and volatility.
40- llvm::PointerIntPair<llvm::PointerUnion<mlir::Value, int *>, 1 , bool > v2;
41- // Stores element type for aggregate values.
42- mlir::Type elementType;
35+ union {
36+ // Stores first and second value.
37+ struct {
38+ mlir::Value first;
39+ mlir::Value second;
40+ } vals;
41+
42+ // Stores aggregate address.
43+ Address aggregateAddr;
44+ };
45+
46+ unsigned isVolatile : 1 ;
47+ unsigned flavor : 2 ;
4348
4449public:
45- bool isScalar () const { return v1.getInt () == Scalar; }
46- bool isAggregate () const { return v1.getInt () == Aggregate; }
50+ RValue () : vals{nullptr , nullptr }, flavor(Scalar) {}
51+
52+ bool isScalar () const { return flavor == Scalar; }
53+ bool isComplex () const { return flavor == Complex; }
54+ bool isAggregate () const { return flavor == Aggregate; }
55+
56+ bool isVolatileQualified () const { return isVolatile; }
4757
48- // / Return the mlir::Value of this scalar value.
58+ // / Return the value of this scalar value.
4959 mlir::Value getScalarVal () const {
5060 assert (isScalar () && " Not a scalar!" );
51- return v1.getPointer ();
61+ return vals.first ;
62+ }
63+
64+ // / Return the real/imag components of this complex value.
65+ std::pair<mlir::Value, mlir::Value> getComplexVal () const {
66+ return std::make_pair (vals.first , vals.second );
67+ }
68+
69+ // / Return the value of the address of the aggregate.
70+ Address getAggregateAddress () const {
71+ assert (isAggregate () && " Not an aggregate!" );
72+ return aggregateAddr;
73+ }
74+
75+ mlir::Value getAggregatePointer (QualType pointeeType) const {
76+ return getAggregateAddress ().getPointer ();
77+ }
78+
79+ static RValue getIgnored () {
80+ // FIXME: should we make this a more explicit state?
81+ return get (nullptr );
5282 }
5383
5484 static RValue get (mlir::Value v) {
5585 RValue er;
56- er.v1 .setPointer (v);
57- er.v1 .setInt (Scalar);
58- er.v2 .setInt (false );
86+ er.vals .first = v;
87+ er.flavor = Scalar;
88+ er.isVolatile = false ;
89+ return er;
90+ }
91+
92+ static RValue getComplex (mlir::Value v1, mlir::Value v2) {
93+ RValue er;
94+ er.vals = {v1, v2};
95+ er.flavor = Complex;
96+ er.isVolatile = false ;
97+ return er;
98+ }
99+ static RValue getComplex (const std::pair<mlir::Value, mlir::Value> &c) {
100+ return getComplex (c.first , c.second );
101+ }
102+ // FIXME: Aggregate rvalues need to retain information about whether they are
103+ // volatile or not. Remove default to find all places that probably get this
104+ // wrong.
105+
106+ // / Convert an Address to an RValue. If the Address is not
107+ // / signed, create an RValue using the unsigned address. Otherwise, resign the
108+ // / address using the provided type.
109+ static RValue getAggregate (Address addr, bool isVolatile = false ) {
110+ RValue er;
111+ er.aggregateAddr = addr;
112+ er.flavor = Aggregate;
113+ er.isVolatile = isVolatile;
59114 return er;
60115 }
61116};
0 commit comments