Skip to content

Commit c2b76ef

Browse files
Quentin Colombetqcolombet
Quentin Colombet
authored andcommitted
[InstrGen] Teach inplaceOperand how to deal with several results
Prior to this commit, it was impossible to describe more than one inplace property. This would limit our ability to set the inplace property on instruction with more than one result. With this patch, it is now possible to define one inplace property list for each output of an instruction. To use this feature simply invoke inplaceOperand method for each output on the declaration of the instruction.
1 parent e2c54d8 commit c2b76ef

File tree

2 files changed

+24
-11
lines changed

2 files changed

+24
-11
lines changed

tools/ClassGen/InstrBuilder.cpp

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -101,13 +101,15 @@ void InstrBuilder::emitIRBuilderMethods(std::ostream &osH,
101101
void InstrBuilder::emitInplaceMethod(std::ostream &os) const {
102102
os << "\n bool isInplaceOp(unsigned dstIdx, unsigned srcIdx) const {\n";
103103
if (!inplaceOperands_.empty()) {
104-
assert(inplaceOperands_.size() > 1 &&
105-
"We don't have a pair of inplace args");
106-
for (int i = 1, e = inplaceOperands_.size(); i < e; i++) {
107-
auto F0 = getOperandIndexByName(inplaceOperands_[0]);
108-
auto F1 = getOperandIndexByName(inplaceOperands_[i]);
109-
os << " if (" << F0 << " == dstIdx && " << F1
110-
<< " == srcIdx) { return true; }\n";
104+
for (const std::vector<std::string> curInplaceOperands : inplaceOperands_) {
105+
assert(curInplaceOperands.size() > 1 &&
106+
"We don't have a pair of inplace args");
107+
for (int i = 1, e = curInplaceOperands.size(); i < e; i++) {
108+
auto F0 = getOperandIndexByName(curInplaceOperands[0]);
109+
auto F1 = getOperandIndexByName(curInplaceOperands[i]);
110+
os << " if (" << F0 << " == dstIdx && " << F1
111+
<< " == srcIdx) { return true; }\n";
112+
}
111113
}
112114
}
113115
os << " return false;\n }\n";

tools/ClassGen/InstrBuilder.h

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <cassert>
2323
#include <fstream>
2424
#include <iostream>
25+
#include <list>
2526
#include <string>
2627
#include <unordered_map>
2728
#include <vector>
@@ -70,8 +71,10 @@ class InstrBuilder {
7071
/// Stores the decl and body of a new public method that will be added to the
7172
/// class.
7273
std::vector<std::pair<std::string, std::string>> extraMethods_;
73-
/// A list of operands that are declared as 'inplace' operands.
74-
std::vector<std::string> inplaceOperands_;
74+
/// A list of list of operands that are declared as 'inplace' operands.
75+
/// Each list depicts the 'inplace' operands for one output.
76+
/// The output is the first element of the related list.
77+
std::list<std::vector<std::string>> inplaceOperands_;
7578
/// A list of (VerifyKind, {op1, op2, ...}) pairs. Each pair represents a
7679
/// specific kind of verification to apply on the list of operands.
7780
std::vector<std::pair<VerifyKind, std::vector<std::string>>>
@@ -150,8 +153,16 @@ class InstrBuilder {
150153
/// the operand \p lst[0].
151154
InstrBuilder &inplaceOperand(llvm::ArrayRef<llvm::StringRef> lst) {
152155
assert(lst.size() > 1 && "Not enough operands");
153-
assert(!inplaceOperands_.size() && "Initializing field twice");
154-
inplaceOperands_.insert(inplaceOperands_.begin(), lst.begin(), lst.end());
156+
inplaceOperands_.emplace_back(lst.begin(), lst.end());
157+
// Check that the output parameter is described at most once.
158+
for (auto it = inplaceOperands_.begin(), end = inplaceOperands_.end();
159+
it != end; ++it) {
160+
for (auto secondIt = std::next(it); secondIt != end; ++secondIt) {
161+
assert(getOperandIndexByName((*it)[0]) !=
162+
getOperandIndexByName((*secondIt)[0]) &&
163+
"Inplace operands for output appears more than once");
164+
}
165+
}
155166
return *this;
156167
}
157168

0 commit comments

Comments
 (0)