/// Unlike OperandBundleUse, OperandBundleDefT owns the memory it carries, and
/// so it is possible to create and pass around "self-contained" instances of
/// OperandBundleDef and ConstOperandBundleDef.
-template <typename InputTy> struct OperandBundleDefT {
+template <typename InputTy> class OperandBundleDefT {
std::string Tag;
std::vector<InputTy> Inputs;
- OperandBundleDefT() {}
- explicit OperandBundleDefT(StringRef Tag, const std::vector<InputTy> &Inputs)
+public:
+ explicit OperandBundleDefT(StringRef Tag, std::vector<InputTy> &&Inputs)
: Tag(Tag), Inputs(Inputs) {}
- explicit OperandBundleDefT(StringRef Tag, std::vector<InputTy> &&Inputs)
+ explicit OperandBundleDefT(std::string &&Tag, std::vector<InputTy> &&Inputs)
: Tag(Tag), Inputs(Inputs) {}
explicit OperandBundleDefT(const OperandBundleUse &OBU) {
Tag = OBU.getTagName();
Inputs.insert(Inputs.end(), OBU.Inputs.begin(), OBU.Inputs.end());
}
+
+ ArrayRef<InputTy> getInputs() const { return Inputs; }
+
+ typedef typename std::vector<InputTy>::const_iterator input_iterator;
+ size_t input_size() const { return Inputs.size(); }
+ input_iterator input_begin() const { return Inputs.begin(); }
+ input_iterator input_end() const { return Inputs.end(); }
+
+ StringRef getTag() const { return Tag; }
};
typedef OperandBundleDefT<Value *> OperandBundleDef;
const unsigned BeginIndex) {
auto It = static_cast<InstrTy *>(this)->op_begin() + BeginIndex;
for (auto &B : Bundles)
- It = std::copy(B.Inputs.begin(), B.Inputs.end(), It);
+ It = std::copy(B.input_begin(), B.input_end(), It);
auto *ContextImpl = static_cast<InstrTy *>(this)->getContext().pImpl;
auto BI = Bundles.begin();
for (auto &BOI : bundle_op_infos()) {
assert(BI != Bundles.end() && "Incorrect allocation?");
- BOI.Tag = ContextImpl->getOrInsertBundleTag(BI->Tag);
+ BOI.Tag = ContextImpl->getOrInsertBundleTag(BI->getTag());
BOI.Begin = CurrentIndex;
- BOI.End = CurrentIndex + BI->Inputs.size();
+ BOI.End = CurrentIndex + BI->input_size();
CurrentIndex = BOI.End;
BI++;
}
static unsigned CountBundleInputs(ArrayRef<OperandBundleDef> Bundles) {
unsigned Total = 0;
for (auto &B : Bundles)
- Total += B.Inputs.size();
+ Total += B.input_size();
return Total;
}
};
if (ParseStringConstant(Tag))
return true;
- BundleList.emplace_back();
- auto &OBI = BundleList.back();
-
- OBI.Tag = std::move(Tag);
-
if (ParseToken(lltok::lparen, "expected '(' in operand bundle"))
return true;
+ std::vector<Value *> Inputs;
while (Lex.getKind() != lltok::rparen) {
// If this isn't the first input, we need a comma.
- if (!OBI.Inputs.empty() &&
+ if (!Inputs.empty() &&
ParseToken(lltok::comma, "expected ',' in input list"))
return true;
Value *Input = nullptr;
if (ParseType(Ty) || ParseValue(Ty, Input, PFS))
return true;
- OBI.Inputs.push_back(Input);
+ Inputs.push_back(Input);
}
+ BundleList.emplace_back(std::move(Tag), std::move(Inputs));
+
Lex.Lex(); // Lex the ')'.
}
if (Record.size() < 1 || Record[0] >= BundleTags.size())
return error("Invalid record");
- OperandBundles.emplace_back();
- OperandBundles.back().Tag = BundleTags[Record[0]];
-
- std::vector<Value *> &Inputs = OperandBundles.back().Inputs;
+ std::vector<Value *> Inputs;
unsigned OpNum = 1;
while (OpNum != Record.size()) {
Inputs.push_back(Op);
}
+ OperandBundles.emplace_back(BundleTags[Record[0]], std::move(Inputs));
continue;
}
}