Home | History | Annotate | Download | only in CodeGen
      1 //===-- CGValue.h - LLVM CodeGen wrappers for llvm::Value* ------*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // These classes implement wrappers around llvm::Value in order to
     11 // fully represent the range of values for C L- and R- values.
     12 //
     13 //===----------------------------------------------------------------------===//
     14 
     15 #ifndef CLANG_CODEGEN_CGVALUE_H
     16 #define CLANG_CODEGEN_CGVALUE_H
     17 
     18 #include "clang/AST/ASTContext.h"
     19 #include "clang/AST/CharUnits.h"
     20 #include "clang/AST/Type.h"
     21 
     22 namespace llvm {
     23   class Constant;
     24   class Value;
     25 }
     26 
     27 namespace clang {
     28 namespace CodeGen {
     29   class AggValueSlot;
     30   class CGBitFieldInfo;
     31 
     32 /// RValue - This trivial value class is used to represent the result of an
     33 /// expression that is evaluated.  It can be one of three things: either a
     34 /// simple LLVM SSA value, a pair of SSA values for complex numbers, or the
     35 /// address of an aggregate value in memory.
     36 class RValue {
     37   enum Flavor { Scalar, Complex, Aggregate };
     38 
     39   // Stores first value and flavor.
     40   llvm::PointerIntPair<llvm::Value *, 2, Flavor> V1;
     41   // Stores second value and volatility.
     42   llvm::PointerIntPair<llvm::Value *, 1, bool> V2;
     43 
     44 public:
     45   bool isScalar() const { return V1.getInt() == Scalar; }
     46   bool isComplex() const { return V1.getInt() == Complex; }
     47   bool isAggregate() const { return V1.getInt() == Aggregate; }
     48 
     49   bool isVolatileQualified() const { return V2.getInt(); }
     50 
     51   /// getScalarVal() - Return the Value* of this scalar value.
     52   llvm::Value *getScalarVal() const {
     53     assert(isScalar() && "Not a scalar!");
     54     return V1.getPointer();
     55   }
     56 
     57   /// getComplexVal - Return the real/imag components of this complex value.
     58   ///
     59   std::pair<llvm::Value *, llvm::Value *> getComplexVal() const {
     60     return std::make_pair(V1.getPointer(), V2.getPointer());
     61   }
     62 
     63   /// getAggregateAddr() - Return the Value* of the address of the aggregate.
     64   llvm::Value *getAggregateAddr() const {
     65     assert(isAggregate() && "Not an aggregate!");
     66     return V1.getPointer();
     67   }
     68 
     69   static RValue get(llvm::Value *V) {
     70     RValue ER;
     71     ER.V1.setPointer(V);
     72     ER.V1.setInt(Scalar);
     73     ER.V2.setInt(false);
     74     return ER;
     75   }
     76   static RValue getComplex(llvm::Value *V1, llvm::Value *V2) {
     77     RValue ER;
     78     ER.V1.setPointer(V1);
     79     ER.V2.setPointer(V2);
     80     ER.V1.setInt(Complex);
     81     ER.V2.setInt(false);
     82     return ER;
     83   }
     84   static RValue getComplex(const std::pair<llvm::Value *, llvm::Value *> &C) {
     85     return getComplex(C.first, C.second);
     86   }
     87   // FIXME: Aggregate rvalues need to retain information about whether they are
     88   // volatile or not.  Remove default to find all places that probably get this
     89   // wrong.
     90   static RValue getAggregate(llvm::Value *V, bool Volatile = false) {
     91     RValue ER;
     92     ER.V1.setPointer(V);
     93     ER.V1.setInt(Aggregate);
     94     ER.V2.setInt(Volatile);
     95     return ER;
     96   }
     97 };
     98 
     99 
    100 /// LValue - This represents an lvalue references.  Because C/C++ allow
    101 /// bitfields, this is not a simple LLVM pointer, it may be a pointer plus a
    102 /// bitrange.
    103 class LValue {
    104   enum {
    105     Simple,       // This is a normal l-value, use getAddress().
    106     VectorElt,    // This is a vector element l-value (V[i]), use getVector*
    107     BitField,     // This is a bitfield l-value, use getBitfield*.
    108     ExtVectorElt  // This is an extended vector subset, use getExtVectorComp
    109   } LVType;
    110 
    111   llvm::Value *V;
    112 
    113   union {
    114     // Index into a vector subscript: V[i]
    115     llvm::Value *VectorIdx;
    116 
    117     // ExtVector element subset: V.xyx
    118     llvm::Constant *VectorElts;
    119 
    120     // BitField start bit and size
    121     const CGBitFieldInfo *BitFieldInfo;
    122   };
    123 
    124   QualType Type;
    125 
    126   // 'const' is unused here
    127   Qualifiers Quals;
    128 
    129   // The alignment to use when accessing this lvalue.  (For vector elements,
    130   // this is the alignment of the whole vector.)
    131   unsigned short Alignment;
    132 
    133   // objective-c's ivar
    134   bool Ivar:1;
    135 
    136   // objective-c's ivar is an array
    137   bool ObjIsArray:1;
    138 
    139   // LValue is non-gc'able for any reason, including being a parameter or local
    140   // variable.
    141   bool NonGC: 1;
    142 
    143   // Lvalue is a global reference of an objective-c object
    144   bool GlobalObjCRef : 1;
    145 
    146   // Lvalue is a thread local reference
    147   bool ThreadLocalRef : 1;
    148 
    149   Expr *BaseIvarExp;
    150 
    151   /// TBAAInfo - TBAA information to attach to dereferences of this LValue.
    152   llvm::MDNode *TBAAInfo;
    153 
    154 private:
    155   void Initialize(QualType Type, Qualifiers Quals,
    156                   CharUnits Alignment = CharUnits(),
    157                   llvm::MDNode *TBAAInfo = 0) {
    158     this->Type = Type;
    159     this->Quals = Quals;
    160     this->Alignment = Alignment.getQuantity();
    161     assert(this->Alignment == Alignment.getQuantity() &&
    162            "Alignment exceeds allowed max!");
    163 
    164     // Initialize Objective-C flags.
    165     this->Ivar = this->ObjIsArray = this->NonGC = this->GlobalObjCRef = false;
    166     this->ThreadLocalRef = false;
    167     this->BaseIvarExp = 0;
    168     this->TBAAInfo = TBAAInfo;
    169   }
    170 
    171 public:
    172   bool isSimple() const { return LVType == Simple; }
    173   bool isVectorElt() const { return LVType == VectorElt; }
    174   bool isBitField() const { return LVType == BitField; }
    175   bool isExtVectorElt() const { return LVType == ExtVectorElt; }
    176 
    177   bool isVolatileQualified() const { return Quals.hasVolatile(); }
    178   bool isRestrictQualified() const { return Quals.hasRestrict(); }
    179   unsigned getVRQualifiers() const {
    180     return Quals.getCVRQualifiers() & ~Qualifiers::Const;
    181   }
    182 
    183   QualType getType() const { return Type; }
    184 
    185   Qualifiers::ObjCLifetime getObjCLifetime() const {
    186     return Quals.getObjCLifetime();
    187   }
    188 
    189   bool isObjCIvar() const { return Ivar; }
    190   void setObjCIvar(bool Value) { Ivar = Value; }
    191 
    192   bool isObjCArray() const { return ObjIsArray; }
    193   void setObjCArray(bool Value) { ObjIsArray = Value; }
    194 
    195   bool isNonGC () const { return NonGC; }
    196   void setNonGC(bool Value) { NonGC = Value; }
    197 
    198   bool isGlobalObjCRef() const { return GlobalObjCRef; }
    199   void setGlobalObjCRef(bool Value) { GlobalObjCRef = Value; }
    200 
    201   bool isThreadLocalRef() const { return ThreadLocalRef; }
    202   void setThreadLocalRef(bool Value) { ThreadLocalRef = Value;}
    203 
    204   bool isObjCWeak() const {
    205     return Quals.getObjCGCAttr() == Qualifiers::Weak;
    206   }
    207   bool isObjCStrong() const {
    208     return Quals.getObjCGCAttr() == Qualifiers::Strong;
    209   }
    210 
    211   bool isVolatile() const {
    212     return Quals.hasVolatile();
    213   }
    214 
    215   Expr *getBaseIvarExp() const { return BaseIvarExp; }
    216   void setBaseIvarExp(Expr *V) { BaseIvarExp = V; }
    217 
    218   llvm::MDNode *getTBAAInfo() const { return TBAAInfo; }
    219   void setTBAAInfo(llvm::MDNode *N) { TBAAInfo = N; }
    220 
    221   const Qualifiers &getQuals() const { return Quals; }
    222   Qualifiers &getQuals() { return Quals; }
    223 
    224   unsigned getAddressSpace() const { return Quals.getAddressSpace(); }
    225 
    226   CharUnits getAlignment() const { return CharUnits::fromQuantity(Alignment); }
    227   void setAlignment(CharUnits A) { Alignment = A.getQuantity(); }
    228 
    229   // simple lvalue
    230   llvm::Value *getAddress() const { assert(isSimple()); return V; }
    231   void setAddress(llvm::Value *address) {
    232     assert(isSimple());
    233     V = address;
    234   }
    235 
    236   // vector elt lvalue
    237   llvm::Value *getVectorAddr() const { assert(isVectorElt()); return V; }
    238   llvm::Value *getVectorIdx() const { assert(isVectorElt()); return VectorIdx; }
    239 
    240   // extended vector elements.
    241   llvm::Value *getExtVectorAddr() const { assert(isExtVectorElt()); return V; }
    242   llvm::Constant *getExtVectorElts() const {
    243     assert(isExtVectorElt());
    244     return VectorElts;
    245   }
    246 
    247   // bitfield lvalue
    248   llvm::Value *getBitFieldBaseAddr() const {
    249     assert(isBitField());
    250     return V;
    251   }
    252   const CGBitFieldInfo &getBitFieldInfo() const {
    253     assert(isBitField());
    254     return *BitFieldInfo;
    255   }
    256 
    257   static LValue MakeAddr(llvm::Value *address, QualType type,
    258                          CharUnits alignment, ASTContext &Context,
    259                          llvm::MDNode *TBAAInfo = 0) {
    260     Qualifiers qs = type.getQualifiers();
    261     qs.setObjCGCAttr(Context.getObjCGCAttrKind(type));
    262 
    263     LValue R;
    264     R.LVType = Simple;
    265     R.V = address;
    266     R.Initialize(type, qs, alignment, TBAAInfo);
    267     return R;
    268   }
    269 
    270   static LValue MakeVectorElt(llvm::Value *Vec, llvm::Value *Idx,
    271                               QualType type, CharUnits Alignment) {
    272     LValue R;
    273     R.LVType = VectorElt;
    274     R.V = Vec;
    275     R.VectorIdx = Idx;
    276     R.Initialize(type, type.getQualifiers(), Alignment);
    277     return R;
    278   }
    279 
    280   static LValue MakeExtVectorElt(llvm::Value *Vec, llvm::Constant *Elts,
    281                                  QualType type, CharUnits Alignment) {
    282     LValue R;
    283     R.LVType = ExtVectorElt;
    284     R.V = Vec;
    285     R.VectorElts = Elts;
    286     R.Initialize(type, type.getQualifiers(), Alignment);
    287     return R;
    288   }
    289 
    290   /// \brief Create a new object to represent a bit-field access.
    291   ///
    292   /// \param BaseValue - The base address of the structure containing the
    293   /// bit-field.
    294   /// \param Info - The information describing how to perform the bit-field
    295   /// access.
    296   static LValue MakeBitfield(llvm::Value *BaseValue,
    297                              const CGBitFieldInfo &Info,
    298                              QualType type) {
    299     LValue R;
    300     R.LVType = BitField;
    301     R.V = BaseValue;
    302     R.BitFieldInfo = &Info;
    303     R.Initialize(type, type.getQualifiers());
    304     return R;
    305   }
    306 
    307   RValue asAggregateRValue() const {
    308     // FIMXE: Alignment
    309     return RValue::getAggregate(getAddress(), isVolatileQualified());
    310   }
    311 };
    312 
    313 /// An aggregate value slot.
    314 class AggValueSlot {
    315   /// The address.
    316   llvm::Value *Addr;
    317 
    318   // Qualifiers
    319   Qualifiers Quals;
    320 
    321   unsigned short Alignment;
    322 
    323   /// DestructedFlag - This is set to true if some external code is
    324   /// responsible for setting up a destructor for the slot.  Otherwise
    325   /// the code which constructs it should push the appropriate cleanup.
    326   bool DestructedFlag : 1;
    327 
    328   /// ObjCGCFlag - This is set to true if writing to the memory in the
    329   /// slot might require calling an appropriate Objective-C GC
    330   /// barrier.  The exact interaction here is unnecessarily mysterious.
    331   bool ObjCGCFlag : 1;
    332 
    333   /// ZeroedFlag - This is set to true if the memory in the slot is
    334   /// known to be zero before the assignment into it.  This means that
    335   /// zero fields don't need to be set.
    336   bool ZeroedFlag : 1;
    337 
    338   /// AliasedFlag - This is set to true if the slot might be aliased
    339   /// and it's not undefined behavior to access it through such an
    340   /// alias.  Note that it's always undefined behavior to access a C++
    341   /// object that's under construction through an alias derived from
    342   /// outside the construction process.
    343   ///
    344   /// This flag controls whether calls that produce the aggregate
    345   /// value may be evaluated directly into the slot, or whether they
    346   /// must be evaluated into an unaliased temporary and then memcpy'ed
    347   /// over.  Since it's invalid in general to memcpy a non-POD C++
    348   /// object, it's important that this flag never be set when
    349   /// evaluating an expression which constructs such an object.
    350   bool AliasedFlag : 1;
    351 
    352 public:
    353   enum IsAliased_t { IsNotAliased, IsAliased };
    354   enum IsDestructed_t { IsNotDestructed, IsDestructed };
    355   enum IsZeroed_t { IsNotZeroed, IsZeroed };
    356   enum NeedsGCBarriers_t { DoesNotNeedGCBarriers, NeedsGCBarriers };
    357 
    358   /// ignored - Returns an aggregate value slot indicating that the
    359   /// aggregate value is being ignored.
    360   static AggValueSlot ignored() {
    361     return forAddr(0, CharUnits(), Qualifiers(), IsNotDestructed,
    362                    DoesNotNeedGCBarriers, IsNotAliased);
    363   }
    364 
    365   /// forAddr - Make a slot for an aggregate value.
    366   ///
    367   /// \param quals - The qualifiers that dictate how the slot should
    368   /// be initialied. Only 'volatile' and the Objective-C lifetime
    369   /// qualifiers matter.
    370   ///
    371   /// \param isDestructed - true if something else is responsible
    372   ///   for calling destructors on this object
    373   /// \param needsGC - true if the slot is potentially located
    374   ///   somewhere that ObjC GC calls should be emitted for
    375   static AggValueSlot forAddr(llvm::Value *addr, CharUnits align,
    376                               Qualifiers quals,
    377                               IsDestructed_t isDestructed,
    378                               NeedsGCBarriers_t needsGC,
    379                               IsAliased_t isAliased,
    380                               IsZeroed_t isZeroed = IsNotZeroed) {
    381     AggValueSlot AV;
    382     AV.Addr = addr;
    383     AV.Alignment = align.getQuantity();
    384     AV.Quals = quals;
    385     AV.DestructedFlag = isDestructed;
    386     AV.ObjCGCFlag = needsGC;
    387     AV.ZeroedFlag = isZeroed;
    388     AV.AliasedFlag = isAliased;
    389     return AV;
    390   }
    391 
    392   static AggValueSlot forLValue(LValue LV, IsDestructed_t isDestructed,
    393                                 NeedsGCBarriers_t needsGC,
    394                                 IsAliased_t isAliased,
    395                                 IsZeroed_t isZeroed = IsNotZeroed) {
    396     return forAddr(LV.getAddress(), LV.getAlignment(),
    397                    LV.getQuals(), isDestructed, needsGC, isAliased, isZeroed);
    398   }
    399 
    400   IsDestructed_t isExternallyDestructed() const {
    401     return IsDestructed_t(DestructedFlag);
    402   }
    403   void setExternallyDestructed(bool destructed = true) {
    404     DestructedFlag = destructed;
    405   }
    406 
    407   Qualifiers getQualifiers() const { return Quals; }
    408 
    409   bool isVolatile() const {
    410     return Quals.hasVolatile();
    411   }
    412 
    413   Qualifiers::ObjCLifetime getObjCLifetime() const {
    414     return Quals.getObjCLifetime();
    415   }
    416 
    417   NeedsGCBarriers_t requiresGCollection() const {
    418     return NeedsGCBarriers_t(ObjCGCFlag);
    419   }
    420 
    421   llvm::Value *getAddr() const {
    422     return Addr;
    423   }
    424 
    425   bool isIgnored() const {
    426     return Addr == 0;
    427   }
    428 
    429   CharUnits getAlignment() const {
    430     return CharUnits::fromQuantity(Alignment);
    431   }
    432 
    433   IsAliased_t isPotentiallyAliased() const {
    434     return IsAliased_t(AliasedFlag);
    435   }
    436 
    437   // FIXME: Alignment?
    438   RValue asRValue() const {
    439     return RValue::getAggregate(getAddr(), isVolatile());
    440   }
    441 
    442   void setZeroed(bool V = true) { ZeroedFlag = V; }
    443   IsZeroed_t isZeroed() const {
    444     return IsZeroed_t(ZeroedFlag);
    445   }
    446 };
    447 
    448 }  // end namespace CodeGen
    449 }  // end namespace clang
    450 
    451 #endif
    452