Introduce the ability for "isolated from above" ops to introduce shadowing
names for the basic block arguments in their body. PiperOrigin-RevId: 265084627
This commit is contained in:
parent
00177962ed
commit
31a003dc3c
|
@ -85,6 +85,13 @@ public:
|
||||||
virtual void printRegion(Region &blocks, bool printEntryBlockArgs = true,
|
virtual void printRegion(Region &blocks, bool printEntryBlockArgs = true,
|
||||||
bool printBlockTerminators = true) = 0;
|
bool printBlockTerminators = true) = 0;
|
||||||
|
|
||||||
|
/// Renumber the arguments for the specified region to the same names as the
|
||||||
|
/// SSA values in namesToUse. This may only be used for IsolatedFromAbove
|
||||||
|
/// operations. If any entry in namesToUse is null, the corresponding
|
||||||
|
/// argument name is left alone.
|
||||||
|
virtual void shadowRegionArgs(Region ®ion,
|
||||||
|
ArrayRef<Value *> namesToUse) = 0;
|
||||||
|
|
||||||
/// Prints an affine map of SSA ids, where SSA id names are used in place
|
/// Prints an affine map of SSA ids, where SSA id names are used in place
|
||||||
/// of dims/symbols.
|
/// of dims/symbols.
|
||||||
/// Operand values must come from single-result sources, and be valid
|
/// Operand values must come from single-result sources, and be valid
|
||||||
|
|
|
@ -1244,6 +1244,12 @@ public:
|
||||||
os.indent(currentIndent) << "}";
|
os.indent(currentIndent) << "}";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Renumber the arguments for the specified region to the same names as the
|
||||||
|
/// SSA values in namesToUse. This may only be used for IsolatedFromAbove
|
||||||
|
/// operations. If any entry in namesToUse is null, the corresponding
|
||||||
|
/// argument name is left alone.
|
||||||
|
void shadowRegionArgs(Region ®ion, ArrayRef<Value *> namesToUse) override;
|
||||||
|
|
||||||
void printAffineMapOfSSAIds(AffineMapAttr mapAttr,
|
void printAffineMapOfSSAIds(AffineMapAttr mapAttr,
|
||||||
ArrayRef<Value *> operands) override {
|
ArrayRef<Value *> operands) override {
|
||||||
AffineMap map = mapAttr.getValue();
|
AffineMap map = mapAttr.getValue();
|
||||||
|
@ -1270,9 +1276,14 @@ protected:
|
||||||
void numberValueID(Value *value);
|
void numberValueID(Value *value);
|
||||||
void numberValuesInRegion(Region ®ion);
|
void numberValuesInRegion(Region ®ion);
|
||||||
void numberValuesInBlock(Block &block);
|
void numberValuesInBlock(Block &block);
|
||||||
void printValueID(Value *value, bool printResultNo = true) const;
|
void printValueID(Value *value, bool printResultNo = true) const {
|
||||||
|
printValueIDImpl(value, printResultNo, os);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void printValueIDImpl(Value *value, bool printResultNo,
|
||||||
|
raw_ostream &stream) const;
|
||||||
|
|
||||||
/// Uniques the given value name within the printer. If the given name
|
/// Uniques the given value name within the printer. If the given name
|
||||||
/// conflicts, it is automatically renamed.
|
/// conflicts, it is automatically renamed.
|
||||||
StringRef uniqueValueName(StringRef name);
|
StringRef uniqueValueName(StringRef name);
|
||||||
|
@ -1491,7 +1502,8 @@ void OperationPrinter::print(Operation *op) {
|
||||||
printTrailingLocation(op->getLoc());
|
printTrailingLocation(op->getLoc());
|
||||||
}
|
}
|
||||||
|
|
||||||
void OperationPrinter::printValueID(Value *value, bool printResultNo) const {
|
void OperationPrinter::printValueIDImpl(Value *value, bool printResultNo,
|
||||||
|
raw_ostream &stream) const {
|
||||||
int resultNo = -1;
|
int resultNo = -1;
|
||||||
auto lookupValue = value;
|
auto lookupValue = value;
|
||||||
|
|
||||||
|
@ -1507,21 +1519,56 @@ void OperationPrinter::printValueID(Value *value, bool printResultNo) const {
|
||||||
|
|
||||||
auto it = valueIDs.find(lookupValue);
|
auto it = valueIDs.find(lookupValue);
|
||||||
if (it == valueIDs.end()) {
|
if (it == valueIDs.end()) {
|
||||||
os << "<<INVALID SSA VALUE>>";
|
stream << "<<INVALID SSA VALUE>>";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
os << '%';
|
stream << '%';
|
||||||
if (it->second != nameSentinel) {
|
if (it->second != nameSentinel) {
|
||||||
os << it->second;
|
stream << it->second;
|
||||||
} else {
|
} else {
|
||||||
auto nameIt = valueNames.find(lookupValue);
|
auto nameIt = valueNames.find(lookupValue);
|
||||||
assert(nameIt != valueNames.end() && "Didn't have a name entry?");
|
assert(nameIt != valueNames.end() && "Didn't have a name entry?");
|
||||||
os << nameIt->second;
|
stream << nameIt->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resultNo != -1 && printResultNo)
|
if (resultNo != -1 && printResultNo)
|
||||||
os << '#' << resultNo;
|
stream << '#' << resultNo;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Renumber the arguments for the specified region to the same names as the
|
||||||
|
/// SSA values in namesToUse. This may only be used for IsolatedFromAbove
|
||||||
|
/// operations. If any entry in namesToUse is null, the corresponding
|
||||||
|
/// argument name is left alone.
|
||||||
|
void OperationPrinter::shadowRegionArgs(Region ®ion,
|
||||||
|
ArrayRef<Value *> namesToUse) {
|
||||||
|
assert(!region.empty() && "cannot shadow arguments of an empty region");
|
||||||
|
assert(region.front().getNumArguments() == namesToUse.size() &&
|
||||||
|
"incorrect number of names passed in");
|
||||||
|
assert(region.getParentOp()->isKnownIsolatedFromAbove() &&
|
||||||
|
"only KnownIsolatedFromAbove ops can shadow names");
|
||||||
|
|
||||||
|
SmallVector<char, 16> nameStr;
|
||||||
|
for (unsigned i = 0, e = namesToUse.size(); i != e; ++i) {
|
||||||
|
auto *nameToUse = namesToUse[i];
|
||||||
|
if (nameToUse == nullptr)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
auto *nameToReplace = region.front().getArgument(i);
|
||||||
|
|
||||||
|
nameStr.clear();
|
||||||
|
llvm::raw_svector_ostream nameStream(nameStr);
|
||||||
|
printValueIDImpl(nameToUse, /*printResultNo=*/true, nameStream);
|
||||||
|
|
||||||
|
// Entry block arguments should already have a pretty "arg" name.
|
||||||
|
assert(valueIDs[nameToReplace] == nameSentinel);
|
||||||
|
|
||||||
|
// Use the name without the leading %.
|
||||||
|
auto name = StringRef(nameStream.str()).drop_front();
|
||||||
|
|
||||||
|
// Overwrite the name.
|
||||||
|
valueNames[nameToReplace] = name.copy(usedNameAllocator);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OperationPrinter::printOperation(Operation *op) {
|
void OperationPrinter::printOperation(Operation *op) {
|
||||||
|
|
|
@ -1055,13 +1055,25 @@ func @op_with_region_args() {
|
||||||
// CHECK-LABEL: func @op_with_passthrough_region_args
|
// CHECK-LABEL: func @op_with_passthrough_region_args
|
||||||
func @op_with_passthrough_region_args() {
|
func @op_with_passthrough_region_args() {
|
||||||
// CHECK: [[VAL:%.*]] = constant
|
// CHECK: [[VAL:%.*]] = constant
|
||||||
// CHECK: "test.isolated_region"([[VAL]])
|
|
||||||
// CHECK-NEXT: ^{{.*}}([[ARG:%.*]]: index)
|
|
||||||
// CHECK-NEXT: "foo.consumer"([[ARG]]) : (index)
|
|
||||||
|
|
||||||
%0 = constant 10 : index
|
%0 = constant 10 : index
|
||||||
|
|
||||||
|
// CHECK: test.isolated_region [[VAL]] {
|
||||||
|
// CHECK-NEXT: "foo.consumer"([[VAL]]) : (index)
|
||||||
|
// CHECK-NEXT: }
|
||||||
test.isolated_region %0 {
|
test.isolated_region %0 {
|
||||||
"foo.consumer"(%0) : (index) -> ()
|
"foo.consumer"(%0) : (index) -> ()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CHECK: [[VAL:%.*]]:2 = "foo.op"
|
||||||
|
%result:2 = "foo.op"() : () -> (index, index)
|
||||||
|
|
||||||
|
// CHECK: test.isolated_region [[VAL]]#1 {
|
||||||
|
// CHECK-NEXT: "foo.consumer"([[VAL]]#1) : (index)
|
||||||
|
// CHECK-NEXT: }
|
||||||
|
test.isolated_region %result#1 {
|
||||||
|
"foo.consumer"(%result#1) : (index) -> ()
|
||||||
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,6 +54,13 @@ static ParseResult parseIsolatedRegionOp(OpAsmParser *parser,
|
||||||
/*enableNameShadowing=*/true);
|
/*enableNameShadowing=*/true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void print(OpAsmPrinter *p, IsolatedRegionOp op) {
|
||||||
|
*p << "test.isolated_region ";
|
||||||
|
p->printOperand(op.getOperand());
|
||||||
|
p->shadowRegionArgs(op.region(), op.getOperand());
|
||||||
|
p->printRegion(op.region(), /*printEntryBlockArgs=*/false);
|
||||||
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Test PolyForOp - parse list of region arguments.
|
// Test PolyForOp - parse list of region arguments.
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
|
@ -704,6 +704,7 @@ def IsolatedRegionOp : TEST_Op<"isolated_region", [IsolatedFromAbove]> {
|
||||||
let arguments = (ins Index:$input);
|
let arguments = (ins Index:$input);
|
||||||
let regions = (region SizedRegion<1>:$region);
|
let regions = (region SizedRegion<1>:$region);
|
||||||
let parser = [{ return ::parse$cppClass(parser, result); }];
|
let parser = [{ return ::parse$cppClass(parser, result); }];
|
||||||
|
let printer = [{ return ::print(p, *this); }];
|
||||||
}
|
}
|
||||||
|
|
||||||
def PolyForOp : TEST_Op<"polyfor">
|
def PolyForOp : TEST_Op<"polyfor">
|
||||||
|
|
Loading…
Reference in New Issue