Changeset View
Changeset View
Standalone View
Standalone View
include/llvm/IR/InstrTypes.h
Show First 20 Lines • Show All 1,085 Lines • ▼ Show 20 Lines | |||||
// FIXME: these are redundant if CmpInst < BinaryOperator | // FIXME: these are redundant if CmpInst < BinaryOperator | ||||
template <> | template <> | ||||
struct OperandTraits<CmpInst> : public FixedNumOperandTraits<CmpInst, 2> { | struct OperandTraits<CmpInst> : public FixedNumOperandTraits<CmpInst, 2> { | ||||
}; | }; | ||||
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CmpInst, Value) | DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CmpInst, Value) | ||||
/// A lightweight accessor for a set of operand bundles meant to be passed | |||||
/// around by value. | |||||
/// | |||||
/// There are two distinct views of a set of operand bundles: a "use" view | |||||
/// (OperandBundleSetUse) and a "def" view (OperandBundleSetDef). The former is | |||||
/// more useful when viewing or editing the operand bundle set of an existing | |||||
/// instruction, while the latter is useful when viewing an operand bundle as a | |||||
/// distinct entity. | |||||
template <typename InputTy> struct OperandBundleSetT { | |||||
StringRef Tag; | |||||
ArrayRef<InputTy> Inputs; | |||||
OperandBundleSetT() {} | |||||
explicit OperandBundleSetT(StringRef Tag, ArrayRef<InputTy> Inputs) | |||||
JosephTremoulet: nit: Why `explicit`, when we have two parameters? | |||||
sanjoyAuthorUnsubmitted Not Done ReplyInline ActionsC++11 allows implicit multi-arg constructors -- like X x = {1, 2}. sanjoy: C++11 allows implicit multi-arg constructors -- like `X x = {1, 2}`. | |||||
: Tag(Tag), Inputs(Inputs) {} | |||||
}; | |||||
typedef OperandBundleSetT<Use> OperandBundleSetUse; | |||||
typedef OperandBundleSetT<const Use> ConstOperandBundleSetUse; | |||||
typedef OperandBundleSetT<Value *> OperandBundleSetDef; | |||||
typedef OperandBundleSetT<const Value *> ConstOperandBundleSetDef; | |||||
template <typename InstrTy> class OperandBundleUser { | |||||
public: | |||||
unsigned getNumOperandBundles() const { | |||||
return std::distance(bundle_op_info_begin(), bundle_op_info_end()); | |||||
} | |||||
bool hasOperandBundles() const { return getNumOperandBundles() != 0; } | |||||
unsigned getNumTotalBundleOperands() const { | |||||
if (!hasOperandBundles()) | |||||
return 0; | |||||
auto *Begin = bundle_op_info_begin(); | |||||
auto *InclusiveEnd = bundle_op_info_end() - 1; | |||||
JosephTremouletUnsubmitted super-nit: I think Back would be a more common name for this than InclusiveEnd JosephTremoulet: super-nit: I think `Back` would be a more common name for this than `InclusiveEnd` | |||||
sanjoyAuthorUnsubmitted Not Done ReplyInline ActionsWill fix. sanjoy: Will fix. | |||||
assert(Begin <= InclusiveEnd && "hasOperandBundles() returned true!"); | |||||
return InclusiveEnd->End - Begin->Begin; | |||||
} | |||||
ConstOperandBundleSetUse getOperandBundle(unsigned Index) const { | |||||
assert(Index < getNumOperandBundles() && "Index out of bounds!"); | |||||
auto *BOI = bundle_op_info_begin() + Index; | |||||
auto op_begin = static_cast<const InstrTy *>(this)->op_begin(); | |||||
ArrayRef<const Use> Inputs(op_begin + BOI->Begin, op_begin + BOI->End); | |||||
return ConstOperandBundleSetUse(BOI->Tag->getKey(), Inputs); | |||||
} | |||||
OperandBundleSetUse getOperandBundle(unsigned Index) { | |||||
assert(Index < getNumOperandBundles() && "Index out of bounds!"); | |||||
auto *BOI = bundle_op_info_begin() + Index; | |||||
auto op_begin = static_cast<InstrTy *>(this)->op_begin(); | |||||
ArrayRef<Use> Inputs(op_begin + BOI->Begin, op_begin + BOI->End); | |||||
return OperandBundleSetUse(BOI->Tag->getKey(), Inputs); | |||||
} | |||||
protected: | |||||
struct BundleOpInfo { | |||||
StringMapEntry<uint32_t> *Tag; | |||||
uint32_t Begin; | |||||
uint32_t End; | |||||
}; | |||||
typedef BundleOpInfo *bundle_op_iterator; | |||||
typedef const BundleOpInfo *const_bundle_op_iterator; | |||||
bundle_op_iterator bundle_op_info_begin() { | |||||
if (!static_cast<InstrTy *>(this)->hasDescriptor()) | |||||
return nullptr; | |||||
uint8_t *Begin, *End; | |||||
std::tie(Begin, End) = static_cast<InstrTy *>(this)->getDescriptor(); | |||||
return reinterpret_cast<bundle_op_iterator>(Begin); | |||||
} | |||||
const_bundle_op_iterator bundle_op_info_begin() const { | |||||
if (!static_cast<const InstrTy *>(this)->hasDescriptor()) | |||||
return nullptr; | |||||
const uint8_t *Begin, *End; | |||||
std::tie(Begin, End) = static_cast<const InstrTy *>(this)->getDescriptor(); | |||||
return reinterpret_cast<const_bundle_op_iterator>(Begin); | |||||
} | |||||
bundle_op_iterator bundle_op_info_end() { | |||||
if (!static_cast<InstrTy *>(this)->hasDescriptor()) | |||||
return nullptr; | |||||
uint8_t *Begin, *End; | |||||
std::tie(Begin, End) = static_cast<InstrTy *>(this)->getDescriptor(); | |||||
return reinterpret_cast<bundle_op_iterator>(End); | |||||
} | |||||
const_bundle_op_iterator bundle_op_info_end() const { | |||||
if (!static_cast<const InstrTy *>(this)->hasDescriptor()) | |||||
return nullptr; | |||||
const uint8_t *Begin, *End; | |||||
std::tie(Begin, End) = static_cast<const InstrTy *>(this)->getDescriptor(); | |||||
return reinterpret_cast<const_bundle_op_iterator>(End); | |||||
} | |||||
iterator_range<bundle_op_iterator> bundle_op_infos() { | |||||
return iterator_range<bundle_op_iterator>(bundle_op_info_begin(), | |||||
bundle_op_info_end()); | |||||
} | |||||
iterator_range<const_bundle_op_iterator> bundle_op_infos() const { | |||||
return iterator_range<const_bundle_op_iterator>(bundle_op_info_begin(), | |||||
bundle_op_info_end()); | |||||
} | |||||
void populateBundleOperandInfos(ArrayRef<OperandBundleSetDef> Bundles, | |||||
const unsigned BeginIndex) { | |||||
auto *ContextImpl = static_cast<InstrTy *>(this)->getContext().pImpl; | |||||
auto BI = Bundles.begin(); | |||||
unsigned CurrentIndex = BeginIndex; | |||||
for (auto &BOI : bundle_op_infos()) { | |||||
assert(BI != Bundles.end() && "Incorrect allocation?"); | |||||
BOI.Tag = ContextImpl->internBundleTag(BI->Tag); | |||||
BOI.Begin = CurrentIndex; | |||||
BOI.End = CurrentIndex + BI->Inputs.size(); | |||||
CurrentIndex = BOI.End; | |||||
BI++; | |||||
} | |||||
assert(BI == Bundles.end() && "Incorrect allocation?"); | |||||
} | |||||
static unsigned CountBundleInputs(ArrayRef<OperandBundleSetDef> Bundles) { | |||||
unsigned Total = 0; | |||||
for (auto &B : Bundles) | |||||
Total += B.Inputs.size(); | |||||
return Total; | |||||
} | |||||
}; | |||||
} // End llvm namespace | } // End llvm namespace | ||||
#endif | #endif |
nit: Why explicit, when we have two parameters?