693 lines · c
1//===-- CGValue.h - LLVM CodeGen wrappers for llvm::Value* ------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// These classes implement wrappers around llvm::Value in order to10// fully represent the range of values for C L- and R- values.11//12//===----------------------------------------------------------------------===//13 14#ifndef LLVM_CLANG_LIB_CODEGEN_CGVALUE_H15#define LLVM_CLANG_LIB_CODEGEN_CGVALUE_H16 17#include "Address.h"18#include "CGPointerAuthInfo.h"19#include "CodeGenTBAA.h"20#include "EHScopeStack.h"21#include "clang/AST/ASTContext.h"22#include "clang/AST/Type.h"23#include "llvm/IR/Type.h"24#include "llvm/IR/Value.h"25 26namespace llvm {27 class Constant;28 class MDNode;29}30 31namespace clang {32namespace CodeGen {33class AggValueSlot;34class CGBuilderTy;35class CodeGenFunction;36struct CGBitFieldInfo;37 38/// RValue - This trivial value class is used to represent the result of an39/// expression that is evaluated. It can be one of three things: either a40/// simple LLVM SSA value, a pair of SSA values for complex numbers, or the41/// address of an aggregate value in memory.42class RValue {43 friend struct DominatingValue<RValue>;44 45 enum FlavorEnum { Scalar, Complex, Aggregate };46 47 union {48 // Stores first and second value.49 struct {50 llvm::Value *first;51 llvm::Value *second;52 } Vals;53 54 // Stores aggregate address.55 Address AggregateAddr;56 };57 58 unsigned IsVolatile : 1;59 unsigned Flavor : 2;60 61public:62 RValue() : Vals{nullptr, nullptr}, Flavor(Scalar) {}63 64 bool isScalar() const { return Flavor == Scalar; }65 bool isComplex() const { return Flavor == Complex; }66 bool isAggregate() const { return Flavor == Aggregate; }67 bool isIgnored() const { return isScalar() && !getScalarVal(); }68 69 bool isVolatileQualified() const { return IsVolatile; }70 71 /// getScalarVal() - Return the Value* of this scalar value.72 llvm::Value *getScalarVal() const {73 assert(isScalar() && "Not a scalar!");74 return Vals.first;75 }76 77 /// getComplexVal - Return the real/imag components of this complex value.78 ///79 std::pair<llvm::Value *, llvm::Value *> getComplexVal() const {80 return std::make_pair(Vals.first, Vals.second);81 }82 83 /// getAggregateAddr() - Return the Value* of the address of the aggregate.84 Address getAggregateAddress() const {85 assert(isAggregate() && "Not an aggregate!");86 return AggregateAddr;87 }88 89 llvm::Value *getAggregatePointer(QualType PointeeType,90 CodeGenFunction &CGF) const {91 return getAggregateAddress().getBasePointer();92 }93 94 static RValue getIgnored() {95 // FIXME: should we make this a more explicit state?96 return get(nullptr);97 }98 99 static RValue get(llvm::Value *V) {100 RValue ER;101 ER.Vals.first = V;102 ER.Flavor = Scalar;103 ER.IsVolatile = false;104 return ER;105 }106 static RValue get(Address Addr, CodeGenFunction &CGF) {107 return RValue::get(Addr.emitRawPointer(CGF));108 }109 static RValue getComplex(llvm::Value *V1, llvm::Value *V2) {110 RValue ER;111 ER.Vals = {V1, V2};112 ER.Flavor = Complex;113 ER.IsVolatile = false;114 return ER;115 }116 static RValue getComplex(const std::pair<llvm::Value *, llvm::Value *> &C) {117 return getComplex(C.first, C.second);118 }119 // FIXME: Aggregate rvalues need to retain information about whether they are120 // volatile or not. Remove default to find all places that probably get this121 // wrong.122 123 /// Convert an Address to an RValue. If the Address is not124 /// signed, create an RValue using the unsigned address. Otherwise, resign the125 /// address using the provided type.126 static RValue getAggregate(Address addr, bool isVolatile = false) {127 RValue ER;128 ER.AggregateAddr = addr;129 ER.Flavor = Aggregate;130 ER.IsVolatile = isVolatile;131 return ER;132 }133};134 135/// Does an ARC strong l-value have precise lifetime?136enum ARCPreciseLifetime_t {137 ARCImpreciseLifetime, ARCPreciseLifetime138};139 140/// The source of the alignment of an l-value; an expression of141/// confidence in the alignment actually matching the estimate.142enum class AlignmentSource {143 /// The l-value was an access to a declared entity or something144 /// equivalently strong, like the address of an array allocated by a145 /// language runtime.146 Decl,147 148 /// The l-value was considered opaque, so the alignment was149 /// determined from a type, but that type was an explicitly-aligned150 /// typedef.151 AttributedType,152 153 /// The l-value was considered opaque, so the alignment was154 /// determined from a type.155 Type156};157 158/// Given that the base address has the given alignment source, what's159/// our confidence in the alignment of the field?160static inline AlignmentSource getFieldAlignmentSource(AlignmentSource Source) {161 // For now, we don't distinguish fields of opaque pointers from162 // top-level declarations, but maybe we should.163 return AlignmentSource::Decl;164}165 166class LValueBaseInfo {167 AlignmentSource AlignSource;168 169public:170 explicit LValueBaseInfo(AlignmentSource Source = AlignmentSource::Type)171 : AlignSource(Source) {}172 AlignmentSource getAlignmentSource() const { return AlignSource; }173 void setAlignmentSource(AlignmentSource Source) { AlignSource = Source; }174 175 void mergeForCast(const LValueBaseInfo &Info) {176 setAlignmentSource(Info.getAlignmentSource());177 }178};179 180/// LValue - This represents an lvalue references. Because C/C++ allow181/// bitfields, this is not a simple LLVM pointer, it may be a pointer plus a182/// bitrange.183class LValue {184 enum {185 Simple, // This is a normal l-value, use getAddress().186 VectorElt, // This is a vector element l-value (V[i]), use getVector*187 BitField, // This is a bitfield l-value, use getBitfield*.188 ExtVectorElt, // This is an extended vector subset, use getExtVectorComp189 GlobalReg, // This is a register l-value, use getGlobalReg()190 MatrixElt // This is a matrix element, use getVector*191 } LVType;192 193 union {194 Address Addr = Address::invalid();195 llvm::Value *V;196 };197 198 union {199 // Index into a vector subscript: V[i]200 llvm::Value *VectorIdx;201 202 // ExtVector element subset: V.xyx203 llvm::Constant *VectorElts;204 205 // BitField start bit and size206 const CGBitFieldInfo *BitFieldInfo;207 };208 209 QualType Type;210 211 // 'const' is unused here212 Qualifiers Quals;213 214 // objective-c's ivar215 bool Ivar:1;216 217 // objective-c's ivar is an array218 bool ObjIsArray:1;219 220 // LValue is non-gc'able for any reason, including being a parameter or local221 // variable.222 bool NonGC: 1;223 224 // Lvalue is a global reference of an objective-c object225 bool GlobalObjCRef : 1;226 227 // Lvalue is a thread local reference228 bool ThreadLocalRef : 1;229 230 // Lvalue has ARC imprecise lifetime. We store this inverted to try231 // to make the default bitfield pattern all-zeroes.232 bool ImpreciseLifetime : 1;233 234 // This flag shows if a nontemporal load/stores should be used when accessing235 // this lvalue.236 bool Nontemporal : 1;237 238 LValueBaseInfo BaseInfo;239 TBAAAccessInfo TBAAInfo;240 241 Expr *BaseIvarExp;242 243private:244 void Initialize(QualType Type, Qualifiers Quals, Address Addr,245 LValueBaseInfo BaseInfo, TBAAAccessInfo TBAAInfo) {246 this->Type = Type;247 this->Quals = Quals;248 const unsigned MaxAlign = 1U << 31;249 CharUnits Alignment = Addr.getAlignment();250 assert((isGlobalReg() || !Alignment.isZero() || Type->isIncompleteType()) &&251 "initializing l-value with zero alignment!");252 if (Alignment.getQuantity() > MaxAlign) {253 assert(false && "Alignment exceeds allowed max!");254 Alignment = CharUnits::fromQuantity(MaxAlign);255 }256 this->Addr = Addr;257 this->BaseInfo = BaseInfo;258 this->TBAAInfo = TBAAInfo;259 260 // Initialize Objective-C flags.261 this->Ivar = this->ObjIsArray = this->NonGC = this->GlobalObjCRef = false;262 this->ImpreciseLifetime = false;263 this->Nontemporal = false;264 this->ThreadLocalRef = false;265 this->BaseIvarExp = nullptr;266 }267 268 void initializeSimpleLValue(Address Addr, QualType Type,269 LValueBaseInfo BaseInfo, TBAAAccessInfo TBAAInfo,270 ASTContext &Context) {271 Qualifiers QS = Type.getQualifiers();272 QS.setObjCGCAttr(Context.getObjCGCAttrKind(Type));273 LVType = Simple;274 Initialize(Type, QS, Addr, BaseInfo, TBAAInfo);275 assert(Addr.getBasePointer()->getType()->isPointerTy());276 }277 278public:279 bool isSimple() const { return LVType == Simple; }280 bool isVectorElt() const { return LVType == VectorElt; }281 bool isBitField() const { return LVType == BitField; }282 bool isExtVectorElt() const { return LVType == ExtVectorElt; }283 bool isGlobalReg() const { return LVType == GlobalReg; }284 bool isMatrixElt() const { return LVType == MatrixElt; }285 286 bool isVolatileQualified() const { return Quals.hasVolatile(); }287 bool isRestrictQualified() const { return Quals.hasRestrict(); }288 unsigned getVRQualifiers() const {289 return Quals.getCVRQualifiers() & ~Qualifiers::Const;290 }291 292 QualType getType() const { return Type; }293 294 Qualifiers::ObjCLifetime getObjCLifetime() const {295 return Quals.getObjCLifetime();296 }297 298 bool isObjCIvar() const { return Ivar; }299 void setObjCIvar(bool Value) { Ivar = Value; }300 301 bool isObjCArray() const { return ObjIsArray; }302 void setObjCArray(bool Value) { ObjIsArray = Value; }303 304 bool isNonGC () const { return NonGC; }305 void setNonGC(bool Value) { NonGC = Value; }306 307 bool isGlobalObjCRef() const { return GlobalObjCRef; }308 void setGlobalObjCRef(bool Value) { GlobalObjCRef = Value; }309 310 bool isThreadLocalRef() const { return ThreadLocalRef; }311 void setThreadLocalRef(bool Value) { ThreadLocalRef = Value;}312 313 ARCPreciseLifetime_t isARCPreciseLifetime() const {314 return ARCPreciseLifetime_t(!ImpreciseLifetime);315 }316 void setARCPreciseLifetime(ARCPreciseLifetime_t value) {317 ImpreciseLifetime = (value == ARCImpreciseLifetime);318 }319 bool isNontemporal() const { return Nontemporal; }320 void setNontemporal(bool Value) { Nontemporal = Value; }321 322 bool isObjCWeak() const {323 return Quals.getObjCGCAttr() == Qualifiers::Weak;324 }325 bool isObjCStrong() const {326 return Quals.getObjCGCAttr() == Qualifiers::Strong;327 }328 329 bool isVolatile() const {330 return Quals.hasVolatile();331 }332 333 Expr *getBaseIvarExp() const { return BaseIvarExp; }334 void setBaseIvarExp(Expr *V) { BaseIvarExp = V; }335 336 TBAAAccessInfo getTBAAInfo() const { return TBAAInfo; }337 void setTBAAInfo(TBAAAccessInfo Info) { TBAAInfo = Info; }338 339 const Qualifiers &getQuals() const { return Quals; }340 Qualifiers &getQuals() { return Quals; }341 342 LangAS getAddressSpace() const { return Quals.getAddressSpace(); }343 344 CharUnits getAlignment() const { return Addr.getAlignment(); }345 void setAlignment(CharUnits A) { Addr.setAlignment(A); }346 347 LValueBaseInfo getBaseInfo() const { return BaseInfo; }348 void setBaseInfo(LValueBaseInfo Info) { BaseInfo = Info; }349 350 KnownNonNull_t isKnownNonNull() const { return Addr.isKnownNonNull(); }351 LValue setKnownNonNull() {352 Addr.setKnownNonNull();353 return *this;354 }355 356 // simple lvalue357 llvm::Value *getPointer(CodeGenFunction &CGF) const;358 llvm::Value *emitResignedPointer(QualType PointeeTy,359 CodeGenFunction &CGF) const;360 llvm::Value *emitRawPointer(CodeGenFunction &CGF) const;361 362 Address getAddress() const { return Addr; }363 364 void setAddress(Address address) { Addr = address; }365 366 CGPointerAuthInfo getPointerAuthInfo() const {367 return Addr.getPointerAuthInfo();368 }369 370 // vector elt lvalue371 Address getVectorAddress() const {372 assert(isVectorElt());373 return Addr;374 }375 llvm::Value *getRawVectorPointer(CodeGenFunction &CGF) const {376 assert(isVectorElt());377 return Addr.emitRawPointer(CGF);378 }379 llvm::Value *getVectorPointer() const {380 assert(isVectorElt());381 return Addr.getBasePointer();382 }383 llvm::Value *getVectorIdx() const {384 assert(isVectorElt());385 return VectorIdx;386 }387 388 Address getMatrixAddress() const {389 assert(isMatrixElt());390 return Addr;391 }392 llvm::Value *getMatrixPointer() const {393 assert(isMatrixElt());394 return Addr.getBasePointer();395 }396 llvm::Value *getMatrixIdx() const {397 assert(isMatrixElt());398 return VectorIdx;399 }400 401 // extended vector elements.402 Address getExtVectorAddress() const {403 assert(isExtVectorElt());404 return Addr;405 }406 llvm::Value *getRawExtVectorPointer(CodeGenFunction &CGF) const {407 assert(isExtVectorElt());408 return Addr.emitRawPointer(CGF);409 }410 llvm::Constant *getExtVectorElts() const {411 assert(isExtVectorElt());412 return VectorElts;413 }414 415 // bitfield lvalue416 Address getBitFieldAddress() const {417 assert(isBitField());418 return Addr;419 }420 llvm::Value *getRawBitFieldPointer(CodeGenFunction &CGF) const {421 assert(isBitField());422 return Addr.emitRawPointer(CGF);423 }424 425 const CGBitFieldInfo &getBitFieldInfo() const {426 assert(isBitField());427 return *BitFieldInfo;428 }429 430 // global register lvalue431 llvm::Value *getGlobalReg() const { assert(isGlobalReg()); return V; }432 433 static LValue MakeAddr(Address Addr, QualType type, ASTContext &Context,434 LValueBaseInfo BaseInfo, TBAAAccessInfo TBAAInfo) {435 LValue R;436 R.LVType = Simple;437 R.initializeSimpleLValue(Addr, type, BaseInfo, TBAAInfo, Context);438 R.Addr = Addr;439 assert(Addr.getType()->isPointerTy());440 return R;441 }442 443 static LValue MakeVectorElt(Address vecAddress, llvm::Value *Idx,444 QualType type, LValueBaseInfo BaseInfo,445 TBAAAccessInfo TBAAInfo) {446 LValue R;447 R.LVType = VectorElt;448 R.VectorIdx = Idx;449 R.Initialize(type, type.getQualifiers(), vecAddress, BaseInfo, TBAAInfo);450 return R;451 }452 453 static LValue MakeExtVectorElt(Address Addr, llvm::Constant *Elts,454 QualType type, LValueBaseInfo BaseInfo,455 TBAAAccessInfo TBAAInfo) {456 LValue R;457 R.LVType = ExtVectorElt;458 R.VectorElts = Elts;459 R.Initialize(type, type.getQualifiers(), Addr, BaseInfo, TBAAInfo);460 return R;461 }462 463 /// Create a new object to represent a bit-field access.464 ///465 /// \param Addr - The base address of the bit-field sequence this466 /// bit-field refers to.467 /// \param Info - The information describing how to perform the bit-field468 /// access.469 static LValue MakeBitfield(Address Addr, const CGBitFieldInfo &Info,470 QualType type, LValueBaseInfo BaseInfo,471 TBAAAccessInfo TBAAInfo) {472 LValue R;473 R.LVType = BitField;474 R.BitFieldInfo = &Info;475 R.Initialize(type, type.getQualifiers(), Addr, BaseInfo, TBAAInfo);476 return R;477 }478 479 static LValue MakeGlobalReg(llvm::Value *V, CharUnits alignment,480 QualType type) {481 LValue R;482 R.LVType = GlobalReg;483 R.Initialize(type, type.getQualifiers(), Address::invalid(),484 LValueBaseInfo(AlignmentSource::Decl), TBAAAccessInfo());485 R.V = V;486 return R;487 }488 489 static LValue MakeMatrixElt(Address matAddress, llvm::Value *Idx,490 QualType type, LValueBaseInfo BaseInfo,491 TBAAAccessInfo TBAAInfo) {492 LValue R;493 R.LVType = MatrixElt;494 R.VectorIdx = Idx;495 R.Initialize(type, type.getQualifiers(), matAddress, BaseInfo, TBAAInfo);496 return R;497 }498 499 RValue asAggregateRValue() const {500 return RValue::getAggregate(getAddress(), isVolatileQualified());501 }502};503 504/// An aggregate value slot.505class AggValueSlot {506 /// The address.507 Address Addr;508 509 // Qualifiers510 Qualifiers Quals;511 512 /// DestructedFlag - This is set to true if some external code is513 /// responsible for setting up a destructor for the slot. Otherwise514 /// the code which constructs it should push the appropriate cleanup.515 bool DestructedFlag : 1;516 517 /// ObjCGCFlag - This is set to true if writing to the memory in the518 /// slot might require calling an appropriate Objective-C GC519 /// barrier. The exact interaction here is unnecessarily mysterious.520 bool ObjCGCFlag : 1;521 522 /// ZeroedFlag - This is set to true if the memory in the slot is523 /// known to be zero before the assignment into it. This means that524 /// zero fields don't need to be set.525 bool ZeroedFlag : 1;526 527 /// AliasedFlag - This is set to true if the slot might be aliased528 /// and it's not undefined behavior to access it through such an529 /// alias. Note that it's always undefined behavior to access a C++530 /// object that's under construction through an alias derived from531 /// outside the construction process.532 ///533 /// This flag controls whether calls that produce the aggregate534 /// value may be evaluated directly into the slot, or whether they535 /// must be evaluated into an unaliased temporary and then memcpy'ed536 /// over. Since it's invalid in general to memcpy a non-POD C++537 /// object, it's important that this flag never be set when538 /// evaluating an expression which constructs such an object.539 bool AliasedFlag : 1;540 541 /// This is set to true if the tail padding of this slot might overlap542 /// another object that may have already been initialized (and whose543 /// value must be preserved by this initialization). If so, we may only544 /// store up to the dsize of the type. Otherwise we can widen stores to545 /// the size of the type.546 bool OverlapFlag : 1;547 548 /// If is set to true, sanitizer checks are already generated for this address549 /// or not required. For instance, if this address represents an object550 /// created in 'new' expression, sanitizer checks for memory is made as a part551 /// of 'operator new' emission and object constructor should not generate552 /// them.553 bool SanitizerCheckedFlag : 1;554 555 AggValueSlot(Address Addr, Qualifiers Quals, bool DestructedFlag,556 bool ObjCGCFlag, bool ZeroedFlag, bool AliasedFlag,557 bool OverlapFlag, bool SanitizerCheckedFlag)558 : Addr(Addr), Quals(Quals), DestructedFlag(DestructedFlag),559 ObjCGCFlag(ObjCGCFlag), ZeroedFlag(ZeroedFlag),560 AliasedFlag(AliasedFlag), OverlapFlag(OverlapFlag),561 SanitizerCheckedFlag(SanitizerCheckedFlag) {}562 563public:564 enum IsAliased_t { IsNotAliased, IsAliased };565 enum IsDestructed_t { IsNotDestructed, IsDestructed };566 enum IsZeroed_t { IsNotZeroed, IsZeroed };567 enum Overlap_t { DoesNotOverlap, MayOverlap };568 enum NeedsGCBarriers_t { DoesNotNeedGCBarriers, NeedsGCBarriers };569 enum IsSanitizerChecked_t { IsNotSanitizerChecked, IsSanitizerChecked };570 571 /// ignored - Returns an aggregate value slot indicating that the572 /// aggregate value is being ignored.573 static AggValueSlot ignored() {574 return forAddr(Address::invalid(), Qualifiers(), IsNotDestructed,575 DoesNotNeedGCBarriers, IsNotAliased, DoesNotOverlap);576 }577 578 /// forAddr - Make a slot for an aggregate value.579 ///580 /// \param quals - The qualifiers that dictate how the slot should581 /// be initialied. Only 'volatile' and the Objective-C lifetime582 /// qualifiers matter.583 ///584 /// \param isDestructed - true if something else is responsible585 /// for calling destructors on this object586 /// \param needsGC - true if the slot is potentially located587 /// somewhere that ObjC GC calls should be emitted for588 static AggValueSlot forAddr(Address addr,589 Qualifiers quals,590 IsDestructed_t isDestructed,591 NeedsGCBarriers_t needsGC,592 IsAliased_t isAliased,593 Overlap_t mayOverlap,594 IsZeroed_t isZeroed = IsNotZeroed,595 IsSanitizerChecked_t isChecked = IsNotSanitizerChecked) {596 if (addr.isValid())597 addr.setKnownNonNull();598 return AggValueSlot(addr, quals, isDestructed, needsGC, isZeroed, isAliased,599 mayOverlap, isChecked);600 }601 602 static AggValueSlot603 forLValue(const LValue &LV, IsDestructed_t isDestructed,604 NeedsGCBarriers_t needsGC, IsAliased_t isAliased,605 Overlap_t mayOverlap, IsZeroed_t isZeroed = IsNotZeroed,606 IsSanitizerChecked_t isChecked = IsNotSanitizerChecked) {607 return forAddr(LV.getAddress(), LV.getQuals(), isDestructed, needsGC,608 isAliased, mayOverlap, isZeroed, isChecked);609 }610 611 IsDestructed_t isExternallyDestructed() const {612 return IsDestructed_t(DestructedFlag);613 }614 void setExternallyDestructed(bool destructed = true) {615 DestructedFlag = destructed;616 }617 618 Qualifiers getQualifiers() const { return Quals; }619 620 bool isVolatile() const {621 return Quals.hasVolatile();622 }623 624 void setVolatile(bool flag) {625 if (flag)626 Quals.addVolatile();627 else628 Quals.removeVolatile();629 }630 631 Qualifiers::ObjCLifetime getObjCLifetime() const {632 return Quals.getObjCLifetime();633 }634 635 NeedsGCBarriers_t requiresGCollection() const {636 return NeedsGCBarriers_t(ObjCGCFlag);637 }638 639 llvm::Value *getPointer(QualType PointeeTy, CodeGenFunction &CGF) const;640 641 llvm::Value *emitRawPointer(CodeGenFunction &CGF) const {642 return Addr.isValid() ? Addr.emitRawPointer(CGF) : nullptr;643 }644 645 Address getAddress() const {646 return Addr;647 }648 649 bool isIgnored() const { return !Addr.isValid(); }650 651 CharUnits getAlignment() const {652 return Addr.getAlignment();653 }654 655 IsAliased_t isPotentiallyAliased() const {656 return IsAliased_t(AliasedFlag);657 }658 659 Overlap_t mayOverlap() const {660 return Overlap_t(OverlapFlag);661 }662 663 bool isSanitizerChecked() const {664 return SanitizerCheckedFlag;665 }666 667 RValue asRValue() const {668 if (isIgnored()) {669 return RValue::getIgnored();670 } else {671 return RValue::getAggregate(getAddress(), isVolatile());672 }673 }674 675 void setZeroed(bool V = true) { ZeroedFlag = V; }676 IsZeroed_t isZeroed() const {677 return IsZeroed_t(ZeroedFlag);678 }679 680 /// Get the preferred size to use when storing a value to this slot. This681 /// is the type size unless that might overlap another object, in which682 /// case it's the dsize.683 CharUnits getPreferredSize(ASTContext &Ctx, QualType Type) const {684 return mayOverlap() ? Ctx.getTypeInfoDataSizeInChars(Type).Width685 : Ctx.getTypeSizeInChars(Type);686 }687};688 689} // end namespace CodeGen690} // end namespace clang691 692#endif693