diff options
Diffstat (limited to 'include/llvm/IR/Instructions.h')
-rw-r--r-- | include/llvm/IR/Instructions.h | 99 |
1 files changed, 55 insertions, 44 deletions
diff --git a/include/llvm/IR/Instructions.h b/include/llvm/IR/Instructions.h index 215ce45c7b75..fa980df03ef0 100644 --- a/include/llvm/IR/Instructions.h +++ b/include/llvm/IR/Instructions.h @@ -110,9 +110,11 @@ public: /// Return the alignment of the memory that is being allocated by the /// instruction. unsigned getAlignment() const { - return (1u << (getSubclassDataFromInstruction() & 31)) >> 1; + if (const auto MA = decodeMaybeAlign(getSubclassDataFromInstruction() & 31)) + return MA->value(); + return 0; } - void setAlignment(unsigned Align); + void setAlignment(MaybeAlign Align); /// Return true if this alloca is in the entry block of the function and is a /// constant size. If so, the code generator will fold it into the @@ -182,15 +184,15 @@ public: LoadInst(Type *Ty, Value *Ptr, const Twine &NameStr, bool isVolatile, BasicBlock *InsertAtEnd); LoadInst(Type *Ty, Value *Ptr, const Twine &NameStr, bool isVolatile, - unsigned Align, Instruction *InsertBefore = nullptr); + MaybeAlign Align, Instruction *InsertBefore = nullptr); LoadInst(Type *Ty, Value *Ptr, const Twine &NameStr, bool isVolatile, - unsigned Align, BasicBlock *InsertAtEnd); + MaybeAlign Align, BasicBlock *InsertAtEnd); LoadInst(Type *Ty, Value *Ptr, const Twine &NameStr, bool isVolatile, - unsigned Align, AtomicOrdering Order, + MaybeAlign Align, AtomicOrdering Order, SyncScope::ID SSID = SyncScope::System, Instruction *InsertBefore = nullptr); LoadInst(Type *Ty, Value *Ptr, const Twine &NameStr, bool isVolatile, - unsigned Align, AtomicOrdering Order, SyncScope::ID SSID, + MaybeAlign Align, AtomicOrdering Order, SyncScope::ID SSID, BasicBlock *InsertAtEnd); // Deprecated [opaque pointer types] @@ -209,20 +211,20 @@ public: BasicBlock *InsertAtEnd) : LoadInst(Ptr->getType()->getPointerElementType(), Ptr, NameStr, isVolatile, InsertAtEnd) {} - LoadInst(Value *Ptr, const Twine &NameStr, bool isVolatile, unsigned Align, + LoadInst(Value *Ptr, const Twine &NameStr, bool isVolatile, MaybeAlign Align, Instruction *InsertBefore = nullptr) : LoadInst(Ptr->getType()->getPointerElementType(), Ptr, NameStr, isVolatile, Align, InsertBefore) {} - LoadInst(Value *Ptr, const Twine &NameStr, bool isVolatile, unsigned Align, + LoadInst(Value *Ptr, const Twine &NameStr, bool isVolatile, MaybeAlign Align, BasicBlock *InsertAtEnd) : LoadInst(Ptr->getType()->getPointerElementType(), Ptr, NameStr, isVolatile, Align, InsertAtEnd) {} - LoadInst(Value *Ptr, const Twine &NameStr, bool isVolatile, unsigned Align, + LoadInst(Value *Ptr, const Twine &NameStr, bool isVolatile, MaybeAlign Align, AtomicOrdering Order, SyncScope::ID SSID = SyncScope::System, Instruction *InsertBefore = nullptr) : LoadInst(Ptr->getType()->getPointerElementType(), Ptr, NameStr, isVolatile, Align, Order, SSID, InsertBefore) {} - LoadInst(Value *Ptr, const Twine &NameStr, bool isVolatile, unsigned Align, + LoadInst(Value *Ptr, const Twine &NameStr, bool isVolatile, MaybeAlign Align, AtomicOrdering Order, SyncScope::ID SSID, BasicBlock *InsertAtEnd) : LoadInst(Ptr->getType()->getPointerElementType(), Ptr, NameStr, isVolatile, Align, Order, SSID, InsertAtEnd) {} @@ -238,10 +240,13 @@ public: /// Return the alignment of the access that is being performed. unsigned getAlignment() const { - return (1 << ((getSubclassDataFromInstruction() >> 1) & 31)) >> 1; + if (const auto MA = + decodeMaybeAlign((getSubclassDataFromInstruction() >> 1) & 31)) + return MA->value(); + return 0; } - void setAlignment(unsigned Align); + void setAlignment(MaybeAlign Align); /// Returns the ordering constraint of this load instruction. AtomicOrdering getOrdering() const { @@ -332,17 +337,15 @@ public: StoreInst(Value *Val, Value *Ptr, bool isVolatile = false, Instruction *InsertBefore = nullptr); StoreInst(Value *Val, Value *Ptr, bool isVolatile, BasicBlock *InsertAtEnd); - StoreInst(Value *Val, Value *Ptr, bool isVolatile, - unsigned Align, Instruction *InsertBefore = nullptr); - StoreInst(Value *Val, Value *Ptr, bool isVolatile, - unsigned Align, BasicBlock *InsertAtEnd); - StoreInst(Value *Val, Value *Ptr, bool isVolatile, - unsigned Align, AtomicOrdering Order, - SyncScope::ID SSID = SyncScope::System, + StoreInst(Value *Val, Value *Ptr, bool isVolatile, MaybeAlign Align, Instruction *InsertBefore = nullptr); - StoreInst(Value *Val, Value *Ptr, bool isVolatile, - unsigned Align, AtomicOrdering Order, SyncScope::ID SSID, + StoreInst(Value *Val, Value *Ptr, bool isVolatile, MaybeAlign Align, BasicBlock *InsertAtEnd); + StoreInst(Value *Val, Value *Ptr, bool isVolatile, MaybeAlign Align, + AtomicOrdering Order, SyncScope::ID SSID = SyncScope::System, + Instruction *InsertBefore = nullptr); + StoreInst(Value *Val, Value *Ptr, bool isVolatile, MaybeAlign Align, + AtomicOrdering Order, SyncScope::ID SSID, BasicBlock *InsertAtEnd); // allocate space for exactly two operands void *operator new(size_t s) { @@ -363,10 +366,13 @@ public: /// Return the alignment of the access that is being performed unsigned getAlignment() const { - return (1 << ((getSubclassDataFromInstruction() >> 1) & 31)) >> 1; + if (const auto MA = + decodeMaybeAlign((getSubclassDataFromInstruction() >> 1) & 31)) + return MA->value(); + return 0; } - void setAlignment(unsigned Align); + void setAlignment(MaybeAlign Align); /// Returns the ordering constraint of this store instruction. AtomicOrdering getOrdering() const { @@ -1764,6 +1770,10 @@ public: void setTrueValue(Value *V) { Op<1>() = V; } void setFalseValue(Value *V) { Op<2>() = V; } + /// Swap the true and false values of the select instruction. + /// This doesn't swap prof metadata. + void swapValues() { Op<1>().swap(Op<2>()); } + /// Return a string if the specified operands are invalid /// for a select operation, otherwise return null. static const char *areInvalidOperands(Value *Cond, Value *True, Value *False); @@ -3455,16 +3465,7 @@ public: class SwitchInstProfUpdateWrapper { SwitchInst &SI; Optional<SmallVector<uint32_t, 8> > Weights = None; - - // Sticky invalid state is needed to safely ignore operations with prof data - // in cases where SwitchInstProfUpdateWrapper is created from SwitchInst - // with inconsistent prof data. TODO: once we fix all prof data - // inconsistencies we can turn invalid state to assertions. - enum { - Invalid, - Initialized, - Changed - } State = Invalid; + bool Changed = false; protected: static MDNode *getProfBranchWeightsMD(const SwitchInst &SI); @@ -3482,7 +3483,7 @@ public: SwitchInstProfUpdateWrapper(SwitchInst &SI) : SI(SI) { init(); } ~SwitchInstProfUpdateWrapper() { - if (State == Changed) + if (Changed) SI.setMetadata(LLVMContext::MD_prof, buildProfBranchWeightsMD()); } @@ -3938,6 +3939,9 @@ class CallBrInst : public CallBase { ArrayRef<BasicBlock *> IndirectDests, ArrayRef<Value *> Args, ArrayRef<OperandBundleDef> Bundles, const Twine &NameStr); + /// Should the Indirect Destinations change, scan + update the Arg list. + void updateArgBlockAddresses(unsigned i, BasicBlock *B); + /// Compute the number of operands to allocate. static int ComputeNumOperands(int NumArgs, int NumIndirectDests, int NumBundleInputs = 0) { @@ -4075,7 +4079,7 @@ public: return cast<BasicBlock>(*(&Op<-1>() - getNumIndirectDests() - 1)); } BasicBlock *getIndirectDest(unsigned i) const { - return cast<BasicBlock>(*(&Op<-1>() - getNumIndirectDests() + i)); + return cast_or_null<BasicBlock>(*(&Op<-1>() - getNumIndirectDests() + i)); } SmallVector<BasicBlock *, 16> getIndirectDests() const { SmallVector<BasicBlock *, 16> IndirectDests; @@ -4087,6 +4091,7 @@ public: *(&Op<-1>() - getNumIndirectDests() - 1) = reinterpret_cast<Value *>(B); } void setIndirectDest(unsigned i, BasicBlock *B) { + updateArgBlockAddresses(i, B); *(&Op<-1>() - getNumIndirectDests() + i) = reinterpret_cast<Value *>(B); } @@ -4096,11 +4101,10 @@ public: return i == 0 ? getDefaultDest() : getIndirectDest(i - 1); } - void setSuccessor(unsigned idx, BasicBlock *NewSucc) { - assert(idx < getNumIndirectDests() + 1 && + void setSuccessor(unsigned i, BasicBlock *NewSucc) { + assert(i < getNumIndirectDests() + 1 && "Successor # out of range for callbr!"); - *(&Op<-1>() - getNumIndirectDests() -1 + idx) = - reinterpret_cast<Value *>(NewSucc); + return i == 0 ? setDefaultDest(NewSucc) : setIndirectDest(i - 1, NewSucc); } unsigned getNumSuccessors() const { return getNumIndirectDests() + 1; } @@ -5251,31 +5255,38 @@ public: /// A helper function that returns the pointer operand of a load or store /// instruction. Returns nullptr if not load or store. -inline Value *getLoadStorePointerOperand(Value *V) { +inline const Value *getLoadStorePointerOperand(const Value *V) { if (auto *Load = dyn_cast<LoadInst>(V)) return Load->getPointerOperand(); if (auto *Store = dyn_cast<StoreInst>(V)) return Store->getPointerOperand(); return nullptr; } +inline Value *getLoadStorePointerOperand(Value *V) { + return const_cast<Value *>( + getLoadStorePointerOperand(static_cast<const Value *>(V))); +} /// A helper function that returns the pointer operand of a load, store /// or GEP instruction. Returns nullptr if not load, store, or GEP. -inline Value *getPointerOperand(Value *V) { +inline const Value *getPointerOperand(const Value *V) { if (auto *Ptr = getLoadStorePointerOperand(V)) return Ptr; if (auto *Gep = dyn_cast<GetElementPtrInst>(V)) return Gep->getPointerOperand(); return nullptr; } +inline Value *getPointerOperand(Value *V) { + return const_cast<Value *>(getPointerOperand(static_cast<const Value *>(V))); +} /// A helper function that returns the alignment of load or store instruction. -inline unsigned getLoadStoreAlignment(Value *I) { +inline MaybeAlign getLoadStoreAlignment(Value *I) { assert((isa<LoadInst>(I) || isa<StoreInst>(I)) && "Expected Load or Store instruction"); if (auto *LI = dyn_cast<LoadInst>(I)) - return LI->getAlignment(); - return cast<StoreInst>(I)->getAlignment(); + return MaybeAlign(LI->getAlignment()); + return MaybeAlign(cast<StoreInst>(I)->getAlignment()); } /// A helper function that returns the address space of the pointer operand of |