003 File Manager
Current Path:
/usr/src/contrib/llvm-project/llvm/include/llvm/IR
usr
/
src
/
contrib
/
llvm-project
/
llvm
/
include
/
llvm
/
IR
/
📁
..
📄
AbstractCallSite.h
(9.5 KB)
📄
Argument.h
(5.03 KB)
📄
AssemblyAnnotationWriter.h
(2.2 KB)
📄
Attributes.h
(35.5 KB)
📄
Attributes.td
(8.96 KB)
📄
AutoUpgrade.h
(3.96 KB)
📄
BasicBlock.h
(21.91 KB)
📄
CFG.h
(13.84 KB)
📄
CallingConv.h
(9.27 KB)
📄
Comdat.h
(2.16 KB)
📄
Constant.h
(8.33 KB)
📄
ConstantFolder.h
(10.01 KB)
📄
ConstantRange.h
(21.6 KB)
📄
Constants.h
(53.03 KB)
📄
ConstrainedOps.def
(5.4 KB)
📄
DIBuilder.h
(44.36 KB)
📄
DataLayout.h
(24.11 KB)
📄
DebugInfo.h
(5.42 KB)
📄
DebugInfoFlags.def
(3.62 KB)
📄
DebugInfoMetadata.h
(132.91 KB)
📄
DebugLoc.h
(4.57 KB)
📄
DerivedTypes.h
(26.81 KB)
📄
DerivedUser.h
(1.32 KB)
📄
DiagnosticHandler.h
(2.89 KB)
📄
DiagnosticInfo.h
(41.02 KB)
📄
DiagnosticPrinter.h
(3.46 KB)
📄
Dominators.h
(9.94 KB)
📄
FPEnv.h
(1.97 KB)
📄
FixedMetadataKinds.def
(2.05 KB)
📄
Function.h
(31.39 KB)
📄
GVMaterializer.h
(1.45 KB)
📄
GetElementPtrTypeIterator.h
(5.54 KB)
📄
GlobalAlias.h
(3.16 KB)
📄
GlobalIFunc.h
(2.51 KB)
📄
GlobalIndirectSymbol.h
(3.11 KB)
📄
GlobalObject.h
(7.39 KB)
📄
GlobalValue.h
(21.2 KB)
📄
GlobalVariable.h
(9.6 KB)
📄
IRBuilder.h
(105.58 KB)
📄
IRBuilderFolder.h
(7.1 KB)
📄
IRPrintingPasses.h
(3.57 KB)
📄
InlineAsm.h
(15.84 KB)
📄
InstIterator.h
(5.06 KB)
📄
InstVisitor.h
(13.95 KB)
📄
InstrTypes.h
(86.25 KB)
📄
Instruction.def
(8.53 KB)
📄
Instruction.h
(30.74 KB)
📄
Instructions.h
(195.68 KB)
📄
IntrinsicInst.h
(29.03 KB)
📄
Intrinsics.h
(8.21 KB)
📄
Intrinsics.td
(78.88 KB)
📄
IntrinsicsAArch64.td
(100.59 KB)
📄
IntrinsicsAMDGPU.td
(80.43 KB)
📄
IntrinsicsARM.td
(65.15 KB)
📄
IntrinsicsBPF.td
(1.54 KB)
📄
IntrinsicsHexagon.td
(11.53 KB)
📄
IntrinsicsHexagonDep.td
(197.38 KB)
📄
IntrinsicsMips.td
(94.94 KB)
📄
IntrinsicsNVVM.td
(193.97 KB)
📄
IntrinsicsPowerPC.td
(68.23 KB)
📄
IntrinsicsRISCV.td
(3.24 KB)
📄
IntrinsicsSystemZ.td
(18.56 KB)
📄
IntrinsicsWebAssembly.td
(9.38 KB)
📄
IntrinsicsX86.td
(242.99 KB)
📄
IntrinsicsXCore.td
(6.83 KB)
📄
LLVMContext.h
(14.18 KB)
📄
LLVMRemarkStreamer.h
(3.36 KB)
📄
LegacyPassManager.h
(3.11 KB)
📄
LegacyPassManagers.h
(18.17 KB)
📄
LegacyPassNameParser.h
(3.73 KB)
📄
MDBuilder.h
(8.65 KB)
📄
Mangler.h
(2.06 KB)
📄
MatrixBuilder.h
(8.81 KB)
📄
Metadata.def
(5.07 KB)
📄
Metadata.h
(45.24 KB)
📄
Module.h
(34.6 KB)
📄
ModuleSlotTracker.h
(2.56 KB)
📄
ModuleSummaryIndex.h
(58.12 KB)
📄
ModuleSummaryIndexYAML.h
(10.93 KB)
📄
NoFolder.h
(11.32 KB)
📄
OperandTraits.h
(5.78 KB)
📄
Operator.h
(19.58 KB)
📄
OptBisect.h
(2.79 KB)
📄
PassInstrumentation.h
(8.05 KB)
📄
PassManager.h
(54.18 KB)
📄
PassManagerImpl.h
(5.76 KB)
📄
PassManagerInternal.h
(11.9 KB)
📄
PassTimingInfo.h
(3.65 KB)
📄
PatternMatch.h
(73.41 KB)
📄
PredIteratorCache.h
(2.59 KB)
📄
ProfileSummary.h
(4.34 KB)
📄
RuntimeLibcalls.def
(24.52 KB)
📄
SafepointIRVerifier.h
(1.63 KB)
📄
Statepoint.h
(13.61 KB)
📄
SymbolTableListTraits.h
(4.45 KB)
📄
TrackingMDRef.h
(4.5 KB)
📄
Type.h
(18.98 KB)
📄
TypeFinder.h
(2.57 KB)
📄
Use.h
(3.75 KB)
📄
UseListOrder.h
(1.18 KB)
📄
User.h
(11.75 KB)
📄
VPIntrinsics.def
(2.34 KB)
📄
Value.def
(3.62 KB)
📄
Value.h
(32.16 KB)
📄
ValueHandle.h
(18.11 KB)
📄
ValueMap.h
(14.09 KB)
📄
ValueSymbolTable.h
(4.22 KB)
📄
Verifier.h
(5.47 KB)
Editing: Operator.h
//===-- llvm/Operator.h - Operator utility subclass -------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // This file defines various classes for working with Instructions and // ConstantExprs. // //===----------------------------------------------------------------------===// #ifndef LLVM_IR_OPERATOR_H #define LLVM_IR_OPERATOR_H #include "llvm/ADT/None.h" #include "llvm/ADT/Optional.h" #include "llvm/IR/Constants.h" #include "llvm/IR/Instruction.h" #include "llvm/IR/Type.h" #include "llvm/IR/Value.h" #include "llvm/Support/Casting.h" #include <cstddef> namespace llvm { /// This is a utility class that provides an abstraction for the common /// functionality between Instructions and ConstantExprs. class Operator : public User { public: // The Operator class is intended to be used as a utility, and is never itself // instantiated. Operator() = delete; ~Operator() = delete; void *operator new(size_t s) = delete; /// Return the opcode for this Instruction or ConstantExpr. unsigned getOpcode() const { if (const Instruction *I = dyn_cast<Instruction>(this)) return I->getOpcode(); return cast<ConstantExpr>(this)->getOpcode(); } /// If V is an Instruction or ConstantExpr, return its opcode. /// Otherwise return UserOp1. static unsigned getOpcode(const Value *V) { if (const Instruction *I = dyn_cast<Instruction>(V)) return I->getOpcode(); if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) return CE->getOpcode(); return Instruction::UserOp1; } static bool classof(const Instruction *) { return true; } static bool classof(const ConstantExpr *) { return true; } static bool classof(const Value *V) { return isa<Instruction>(V) || isa<ConstantExpr>(V); } }; /// Utility class for integer operators which may exhibit overflow - Add, Sub, /// Mul, and Shl. It does not include SDiv, despite that operator having the /// potential for overflow. class OverflowingBinaryOperator : public Operator { public: enum { AnyWrap = 0, NoUnsignedWrap = (1 << 0), NoSignedWrap = (1 << 1) }; private: friend class Instruction; friend class ConstantExpr; void setHasNoUnsignedWrap(bool B) { SubclassOptionalData = (SubclassOptionalData & ~NoUnsignedWrap) | (B * NoUnsignedWrap); } void setHasNoSignedWrap(bool B) { SubclassOptionalData = (SubclassOptionalData & ~NoSignedWrap) | (B * NoSignedWrap); } public: /// Test whether this operation is known to never /// undergo unsigned overflow, aka the nuw property. bool hasNoUnsignedWrap() const { return SubclassOptionalData & NoUnsignedWrap; } /// Test whether this operation is known to never /// undergo signed overflow, aka the nsw property. bool hasNoSignedWrap() const { return (SubclassOptionalData & NoSignedWrap) != 0; } static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::Add || I->getOpcode() == Instruction::Sub || I->getOpcode() == Instruction::Mul || I->getOpcode() == Instruction::Shl; } static bool classof(const ConstantExpr *CE) { return CE->getOpcode() == Instruction::Add || CE->getOpcode() == Instruction::Sub || CE->getOpcode() == Instruction::Mul || CE->getOpcode() == Instruction::Shl; } static bool classof(const Value *V) { return (isa<Instruction>(V) && classof(cast<Instruction>(V))) || (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V))); } }; /// A udiv or sdiv instruction, which can be marked as "exact", /// indicating that no bits are destroyed. class PossiblyExactOperator : public Operator { public: enum { IsExact = (1 << 0) }; private: friend class Instruction; friend class ConstantExpr; void setIsExact(bool B) { SubclassOptionalData = (SubclassOptionalData & ~IsExact) | (B * IsExact); } public: /// Test whether this division is known to be exact, with zero remainder. bool isExact() const { return SubclassOptionalData & IsExact; } static bool isPossiblyExactOpcode(unsigned OpC) { return OpC == Instruction::SDiv || OpC == Instruction::UDiv || OpC == Instruction::AShr || OpC == Instruction::LShr; } static bool classof(const ConstantExpr *CE) { return isPossiblyExactOpcode(CE->getOpcode()); } static bool classof(const Instruction *I) { return isPossiblyExactOpcode(I->getOpcode()); } static bool classof(const Value *V) { return (isa<Instruction>(V) && classof(cast<Instruction>(V))) || (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V))); } }; /// Convenience struct for specifying and reasoning about fast-math flags. class FastMathFlags { private: friend class FPMathOperator; unsigned Flags = 0; FastMathFlags(unsigned F) { // If all 7 bits are set, turn this into -1. If the number of bits grows, // this must be updated. This is intended to provide some forward binary // compatibility insurance for the meaning of 'fast' in case bits are added. if (F == 0x7F) Flags = ~0U; else Flags = F; } public: // This is how the bits are used in Value::SubclassOptionalData so they // should fit there too. // WARNING: We're out of space. SubclassOptionalData only has 7 bits. New // functionality will require a change in how this information is stored. enum { AllowReassoc = (1 << 0), NoNaNs = (1 << 1), NoInfs = (1 << 2), NoSignedZeros = (1 << 3), AllowReciprocal = (1 << 4), AllowContract = (1 << 5), ApproxFunc = (1 << 6) }; FastMathFlags() = default; static FastMathFlags getFast() { FastMathFlags FMF; FMF.setFast(); return FMF; } bool any() const { return Flags != 0; } bool none() const { return Flags == 0; } bool all() const { return Flags == ~0U; } void clear() { Flags = 0; } void set() { Flags = ~0U; } /// Flag queries bool allowReassoc() const { return 0 != (Flags & AllowReassoc); } bool noNaNs() const { return 0 != (Flags & NoNaNs); } bool noInfs() const { return 0 != (Flags & NoInfs); } bool noSignedZeros() const { return 0 != (Flags & NoSignedZeros); } bool allowReciprocal() const { return 0 != (Flags & AllowReciprocal); } bool allowContract() const { return 0 != (Flags & AllowContract); } bool approxFunc() const { return 0 != (Flags & ApproxFunc); } /// 'Fast' means all bits are set. bool isFast() const { return all(); } /// Flag setters void setAllowReassoc(bool B = true) { Flags = (Flags & ~AllowReassoc) | B * AllowReassoc; } void setNoNaNs(bool B = true) { Flags = (Flags & ~NoNaNs) | B * NoNaNs; } void setNoInfs(bool B = true) { Flags = (Flags & ~NoInfs) | B * NoInfs; } void setNoSignedZeros(bool B = true) { Flags = (Flags & ~NoSignedZeros) | B * NoSignedZeros; } void setAllowReciprocal(bool B = true) { Flags = (Flags & ~AllowReciprocal) | B * AllowReciprocal; } void setAllowContract(bool B = true) { Flags = (Flags & ~AllowContract) | B * AllowContract; } void setApproxFunc(bool B = true) { Flags = (Flags & ~ApproxFunc) | B * ApproxFunc; } void setFast(bool B = true) { B ? set() : clear(); } void operator&=(const FastMathFlags &OtherFlags) { Flags &= OtherFlags.Flags; } }; /// Utility class for floating point operations which can have /// information about relaxed accuracy requirements attached to them. class FPMathOperator : public Operator { private: friend class Instruction; /// 'Fast' means all bits are set. void setFast(bool B) { setHasAllowReassoc(B); setHasNoNaNs(B); setHasNoInfs(B); setHasNoSignedZeros(B); setHasAllowReciprocal(B); setHasAllowContract(B); setHasApproxFunc(B); } void setHasAllowReassoc(bool B) { SubclassOptionalData = (SubclassOptionalData & ~FastMathFlags::AllowReassoc) | (B * FastMathFlags::AllowReassoc); } void setHasNoNaNs(bool B) { SubclassOptionalData = (SubclassOptionalData & ~FastMathFlags::NoNaNs) | (B * FastMathFlags::NoNaNs); } void setHasNoInfs(bool B) { SubclassOptionalData = (SubclassOptionalData & ~FastMathFlags::NoInfs) | (B * FastMathFlags::NoInfs); } void setHasNoSignedZeros(bool B) { SubclassOptionalData = (SubclassOptionalData & ~FastMathFlags::NoSignedZeros) | (B * FastMathFlags::NoSignedZeros); } void setHasAllowReciprocal(bool B) { SubclassOptionalData = (SubclassOptionalData & ~FastMathFlags::AllowReciprocal) | (B * FastMathFlags::AllowReciprocal); } void setHasAllowContract(bool B) { SubclassOptionalData = (SubclassOptionalData & ~FastMathFlags::AllowContract) | (B * FastMathFlags::AllowContract); } void setHasApproxFunc(bool B) { SubclassOptionalData = (SubclassOptionalData & ~FastMathFlags::ApproxFunc) | (B * FastMathFlags::ApproxFunc); } /// Convenience function for setting multiple fast-math flags. /// FMF is a mask of the bits to set. void setFastMathFlags(FastMathFlags FMF) { SubclassOptionalData |= FMF.Flags; } /// Convenience function for copying all fast-math flags. /// All values in FMF are transferred to this operator. void copyFastMathFlags(FastMathFlags FMF) { SubclassOptionalData = FMF.Flags; } public: /// Test if this operation allows all non-strict floating-point transforms. bool isFast() const { return ((SubclassOptionalData & FastMathFlags::AllowReassoc) != 0 && (SubclassOptionalData & FastMathFlags::NoNaNs) != 0 && (SubclassOptionalData & FastMathFlags::NoInfs) != 0 && (SubclassOptionalData & FastMathFlags::NoSignedZeros) != 0 && (SubclassOptionalData & FastMathFlags::AllowReciprocal) != 0 && (SubclassOptionalData & FastMathFlags::AllowContract) != 0 && (SubclassOptionalData & FastMathFlags::ApproxFunc) != 0); } /// Test if this operation may be simplified with reassociative transforms. bool hasAllowReassoc() const { return (SubclassOptionalData & FastMathFlags::AllowReassoc) != 0; } /// Test if this operation's arguments and results are assumed not-NaN. bool hasNoNaNs() const { return (SubclassOptionalData & FastMathFlags::NoNaNs) != 0; } /// Test if this operation's arguments and results are assumed not-infinite. bool hasNoInfs() const { return (SubclassOptionalData & FastMathFlags::NoInfs) != 0; } /// Test if this operation can ignore the sign of zero. bool hasNoSignedZeros() const { return (SubclassOptionalData & FastMathFlags::NoSignedZeros) != 0; } /// Test if this operation can use reciprocal multiply instead of division. bool hasAllowReciprocal() const { return (SubclassOptionalData & FastMathFlags::AllowReciprocal) != 0; } /// Test if this operation can be floating-point contracted (FMA). bool hasAllowContract() const { return (SubclassOptionalData & FastMathFlags::AllowContract) != 0; } /// Test if this operation allows approximations of math library functions or /// intrinsics. bool hasApproxFunc() const { return (SubclassOptionalData & FastMathFlags::ApproxFunc) != 0; } /// Convenience function for getting all the fast-math flags FastMathFlags getFastMathFlags() const { return FastMathFlags(SubclassOptionalData); } /// Get the maximum error permitted by this operation in ULPs. An accuracy of /// 0.0 means that the operation should be performed with the default /// precision. float getFPAccuracy() const; static bool classof(const Value *V) { unsigned Opcode; if (auto *I = dyn_cast<Instruction>(V)) Opcode = I->getOpcode(); else if (auto *CE = dyn_cast<ConstantExpr>(V)) Opcode = CE->getOpcode(); else return false; switch (Opcode) { case Instruction::FNeg: case Instruction::FAdd: case Instruction::FSub: case Instruction::FMul: case Instruction::FDiv: case Instruction::FRem: // FIXME: To clean up and correct the semantics of fast-math-flags, FCmp // should not be treated as a math op, but the other opcodes should. // This would make things consistent with Select/PHI (FP value type // determines whether they are math ops and, therefore, capable of // having fast-math-flags). case Instruction::FCmp: return true; case Instruction::PHI: case Instruction::Select: case Instruction::Call: { Type *Ty = V->getType(); while (ArrayType *ArrTy = dyn_cast<ArrayType>(Ty)) Ty = ArrTy->getElementType(); return Ty->isFPOrFPVectorTy(); } default: return false; } } }; /// A helper template for defining operators for individual opcodes. template<typename SuperClass, unsigned Opc> class ConcreteOperator : public SuperClass { public: static bool classof(const Instruction *I) { return I->getOpcode() == Opc; } static bool classof(const ConstantExpr *CE) { return CE->getOpcode() == Opc; } static bool classof(const Value *V) { return (isa<Instruction>(V) && classof(cast<Instruction>(V))) || (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V))); } }; class AddOperator : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Add> { }; class SubOperator : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Sub> { }; class MulOperator : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Mul> { }; class ShlOperator : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Shl> { }; class SDivOperator : public ConcreteOperator<PossiblyExactOperator, Instruction::SDiv> { }; class UDivOperator : public ConcreteOperator<PossiblyExactOperator, Instruction::UDiv> { }; class AShrOperator : public ConcreteOperator<PossiblyExactOperator, Instruction::AShr> { }; class LShrOperator : public ConcreteOperator<PossiblyExactOperator, Instruction::LShr> { }; class ZExtOperator : public ConcreteOperator<Operator, Instruction::ZExt> {}; class GEPOperator : public ConcreteOperator<Operator, Instruction::GetElementPtr> { friend class GetElementPtrInst; friend class ConstantExpr; enum { IsInBounds = (1 << 0), // InRangeIndex: bits 1-6 }; void setIsInBounds(bool B) { SubclassOptionalData = (SubclassOptionalData & ~IsInBounds) | (B * IsInBounds); } public: /// Test whether this is an inbounds GEP, as defined by LangRef.html. bool isInBounds() const { return SubclassOptionalData & IsInBounds; } /// Returns the offset of the index with an inrange attachment, or None if /// none. Optional<unsigned> getInRangeIndex() const { if (SubclassOptionalData >> 1 == 0) return None; return (SubclassOptionalData >> 1) - 1; } inline op_iterator idx_begin() { return op_begin()+1; } inline const_op_iterator idx_begin() const { return op_begin()+1; } inline op_iterator idx_end() { return op_end(); } inline const_op_iterator idx_end() const { return op_end(); } Value *getPointerOperand() { return getOperand(0); } const Value *getPointerOperand() const { return getOperand(0); } static unsigned getPointerOperandIndex() { return 0U; // get index for modifying correct operand } /// Method to return the pointer operand as a PointerType. Type *getPointerOperandType() const { return getPointerOperand()->getType(); } Type *getSourceElementType() const; Type *getResultElementType() const; /// Method to return the address space of the pointer operand. unsigned getPointerAddressSpace() const { return getPointerOperandType()->getPointerAddressSpace(); } unsigned getNumIndices() const { // Note: always non-negative return getNumOperands() - 1; } bool hasIndices() const { return getNumOperands() > 1; } /// Return true if all of the indices of this GEP are zeros. /// If so, the result pointer and the first operand have the same /// value, just potentially different types. bool hasAllZeroIndices() const { for (const_op_iterator I = idx_begin(), E = idx_end(); I != E; ++I) { if (ConstantInt *C = dyn_cast<ConstantInt>(I)) if (C->isZero()) continue; return false; } return true; } /// Return true if all of the indices of this GEP are constant integers. /// If so, the result pointer and the first operand have /// a constant offset between them. bool hasAllConstantIndices() const { for (const_op_iterator I = idx_begin(), E = idx_end(); I != E; ++I) { if (!isa<ConstantInt>(I)) return false; } return true; } unsigned countNonConstantIndices() const { return count_if(make_range(idx_begin(), idx_end()), [](const Use& use) { return !isa<ConstantInt>(*use); }); } /// Compute the maximum alignment that this GEP is garranteed to preserve. Align getMaxPreservedAlignment(const DataLayout &DL) const; /// Accumulate the constant address offset of this GEP if possible. /// /// This routine accepts an APInt into which it will try to accumulate the /// constant offset of this GEP. /// /// If \p ExternalAnalysis is provided it will be used to calculate a offset /// when a operand of GEP is not constant. /// For example, for a value \p ExternalAnalysis might try to calculate a /// lower bound. If \p ExternalAnalysis is successful, it should return true. /// /// If the \p ExternalAnalysis returns false or the value returned by \p /// ExternalAnalysis results in a overflow/underflow, this routine returns /// false and the value of the offset APInt is undefined (it is *not* /// preserved!). /// /// The APInt passed into this routine must be at exactly as wide as the /// IntPtr type for the address space of the base GEP pointer. bool accumulateConstantOffset( const DataLayout &DL, APInt &Offset, function_ref<bool(Value &, APInt &)> ExternalAnalysis = nullptr) const; }; class PtrToIntOperator : public ConcreteOperator<Operator, Instruction::PtrToInt> { friend class PtrToInt; friend class ConstantExpr; public: Value *getPointerOperand() { return getOperand(0); } const Value *getPointerOperand() const { return getOperand(0); } static unsigned getPointerOperandIndex() { return 0U; // get index for modifying correct operand } /// Method to return the pointer operand as a PointerType. Type *getPointerOperandType() const { return getPointerOperand()->getType(); } /// Method to return the address space of the pointer operand. unsigned getPointerAddressSpace() const { return cast<PointerType>(getPointerOperandType())->getAddressSpace(); } }; class BitCastOperator : public ConcreteOperator<Operator, Instruction::BitCast> { friend class BitCastInst; friend class ConstantExpr; public: Type *getSrcTy() const { return getOperand(0)->getType(); } Type *getDestTy() const { return getType(); } }; class AddrSpaceCastOperator : public ConcreteOperator<Operator, Instruction::AddrSpaceCast> { friend class AddrSpaceCastInst; friend class ConstantExpr; public: Value *getPointerOperand() { return getOperand(0); } const Value *getPointerOperand() const { return getOperand(0); } unsigned getSrcAddressSpace() const { return getPointerOperand()->getType()->getPointerAddressSpace(); } unsigned getDestAddressSpace() const { return getType()->getPointerAddressSpace(); } }; } // end namespace llvm #endif // LLVM_IR_OPERATOR_H
Upload File
Create Folder