Skip to content

Commit a837d29

Browse files
update print function, test and doc.
1 parent 42cf136 commit a837d29

File tree

5 files changed

+64
-56
lines changed

5 files changed

+64
-56
lines changed

mlir/docs/Tutorials/DataFlowAnalysis.md

Lines changed: 35 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ constructs, of which MLIR has many (Block-based branches, Region-based branches,
77
CallGraph, etc), and it isn't always clear how best to go about performing the
88
propagation. To help writing these types of analyses in MLIR, this document
99
details several utilities that simplify the process and make it a bit more
10-
approachable. The code from that tutorial can be found in `mlir/examples/dataflow`.
10+
approachable. The code from this tutorial can be found in `mlir/examples/dataflow`.
1111

1212
## Forward Dataflow Analysis
1313

@@ -79,60 +79,54 @@ struct MetadataLatticeValue {
7979
}
8080
}
8181

82-
/// This method conservatively joins the information held by `lhs` and `rhs`
83-
/// into a new value. This method is required to be monotonic. `monotonicity`
84-
/// is implied by the satisfaction of the following axioms:
85-
/// * idempotence: join(x,x) == x
86-
/// * commutativity: join(x,y) == join(y,x)
87-
/// * associativity: join(x,join(y,z)) == join(join(x,y),z)
88-
///
89-
/// When the above axioms are satisfied, we achieve `monotonicity`:
90-
/// * monotonicity: join(x, join(x,y)) == join(x,y)
9182
static MetadataLatticeValue join(const MetadataLatticeValue &lhs,
9283
const MetadataLatticeValue &rhs) {
93-
// To join `lhs` and `rhs` we will define a simple policy, which is that we
94-
// directly insert the metadata of rhs into the metadata of lhs.If lhs and rhs
95-
// have overlapping attributes, keep the attribute value in lhs unchanged.
96-
MetadataLatticeValue result;
97-
for (auto &&lhsIt : lhs.metadata) {
98-
result.metadata.insert(
99-
std::pair<StringRef, Attribute>(lhsIt.getKey(), lhsIt.getValue()));
100-
}
84+
// To join `lhs` and `rhs` we will define a simple policy, which is that we
85+
// directly insert the metadata of rhs into the metadata of lhs.If lhs and rhs
86+
// have overlapping attributes, keep the attribute value in lhs unchanged.
87+
MetadataLatticeValue result;
88+
for (auto &&lhsIt : lhs.metadata) {
89+
result.metadata.insert(
90+
std::pair<StringAttr, Attribute>(lhsIt.first, lhsIt.second));
91+
}
10192

102-
for (auto &&rhsIt : rhs.metadata) {
103-
result.metadata.insert(
104-
std::pair<StringRef, Attribute>(rhsIt.getKey(), rhsIt.getValue()));
105-
}
106-
return result;
93+
for (auto &&rhsIt : rhs.metadata) {
94+
result.metadata.insert(
95+
std::pair<StringAttr, Attribute>(rhsIt.first, rhsIt.second));
10796
}
97+
return result;
98+
}
10899

109100
/// A simple comparator that checks to see if this value is equal to the one
110101
/// provided.
111102
bool operator==(const MetadataLatticeValue &rhs) const {
112-
if (metadata.size() != rhs.metadata.size())
113-
return false;
103+
if (metadata.size() != rhs.metadata.size())
104+
return false;
114105

115-
// Check that `rhs` contains the same metadata.
116-
for (auto &&it : metadata) {
117-
auto rhsIt = rhs.metadata.find(it.getKey());
118-
if (rhsIt == rhs.metadata.end() || it.second != rhsIt->second)
119-
return false;
120-
}
121-
return true;
106+
// Check that `rhs` contains the same metadata.
107+
for (auto &&it : metadata) {
108+
auto rhsIt = rhs.metadata.find(it.first);
109+
if (rhsIt == rhs.metadata.end() || it.second != rhsIt->second)
110+
return false;
122111
}
112+
return true;
113+
}
123114

124115
/// Print data in metadata.
125-
void print(llvm::raw_ostream &os) const {
126-
os << "{";
127-
for (auto&& iter : metadata) {
128-
os << iter.getKey() << ": " << iter.getValue() << ", ";
129-
}
130-
os << "\b\b}\n";
116+
void print(llvm::raw_ostream &os) const {
117+
SmallVector<StringAttr> metadataKey(metadata.keys());
118+
std::sort(metadataKey.begin(), metadataKey.end(),
119+
[&](StringAttr a, StringAttr b) { return a < b; });
120+
os << "{";
121+
for (StringAttr key : metadataKey) {
122+
os << key << ": " << metadata.at(key) << ", ";
131123
}
124+
os << "\b\b}\n";
125+
}
132126

133127
/// Our value represents the combined metadata, which is originally a
134128
/// DictionaryAttr, so we use a map.
135-
llvm::StringMap<Attribute> metadata;
129+
DenseMap<StringAttr, Attribute> metadata;
136130
};
137131
```
138132
@@ -314,6 +308,6 @@ func.func @single_join(%arg0 : index, %arg1 : index) -> index {
314308
The above IR will print the following after running pass.
315309

316310
```
317-
{likes_pizza: true}
318-
{likes_pizza: true}
311+
%0 = arith.addi %arg0, %arg1 {metadata = {likes_pizza = true}} : index : {"likes_pizza": true}
312+
%1 = arith.addi %0, %arg1 : index : {"likes_pizza": true}
319313
```

mlir/examples/dataflow/include/MetadataAnalysis.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ struct MetadataLatticeValue {
4141

4242
/// Our value represents the combined metadata, which is originally a
4343
/// DictionaryAttr, so we use a map.
44-
llvm::StringMap<Attribute> metadata;
44+
DenseMap<StringAttr, Attribute> metadata;
4545
};
4646

4747
namespace dataflow {

mlir/examples/dataflow/lib/Analysis/MetadataAnalysis.cpp

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,14 @@ MetadataLatticeValue::join(const MetadataLatticeValue &lhs,
3434
// directly insert the metadata of rhs into the metadata of lhs.If lhs and rhs
3535
// have overlapping attributes, keep the attribute value in lhs unchanged.
3636
MetadataLatticeValue result;
37-
for (const llvm::StringMapEntry<mlir::Attribute> &lhsIt : lhs.metadata) {
37+
for (auto &&lhsIt : lhs.metadata) {
3838
result.metadata.insert(
39-
std::pair<StringRef, Attribute>(lhsIt.getKey(), lhsIt.getValue()));
39+
std::pair<StringAttr, Attribute>(lhsIt.first, lhsIt.second));
4040
}
4141

4242
for (auto &&rhsIt : rhs.metadata) {
4343
result.metadata.insert(
44-
std::pair<StringRef, Attribute>(rhsIt.getKey(), rhsIt.getValue()));
44+
std::pair<StringAttr, Attribute>(rhsIt.first, rhsIt.second));
4545
}
4646
return result;
4747
}
@@ -54,17 +54,20 @@ bool MetadataLatticeValue::operator==(const MetadataLatticeValue &rhs) const {
5454

5555
// Check that `rhs` contains the same metadata.
5656
for (auto &&it : metadata) {
57-
auto rhsIt = rhs.metadata.find(it.getKey());
57+
auto rhsIt = rhs.metadata.find(it.first);
5858
if (rhsIt == rhs.metadata.end() || it.second != rhsIt->second)
5959
return false;
6060
}
6161
return true;
6262
}
6363

6464
void MetadataLatticeValue::print(llvm::raw_ostream &os) const {
65+
SmallVector<StringAttr> metadataKey(metadata.keys());
66+
std::sort(metadataKey.begin(), metadataKey.end(),
67+
[&](StringAttr a, StringAttr b) { return a < b; });
6568
os << "{";
66-
for (auto &&iter : metadata) {
67-
os << iter.getKey() << ": " << iter.getValue() << ", ";
69+
for (StringAttr key : metadataKey) {
70+
os << key << ": " << metadata.at(key) << ", ";
6871
}
6972
os << "\b\b}\n";
7073
}

mlir/examples/dataflow/lib/Pass/TestMetadataAnalsys.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ class TestMetadataAnalysisPass
4242
if (op->getNumResults()) {
4343
Value result = op->getResult(0);
4444
auto lattice = solver.lookupState<MetadataLatticeValueLattice>(result);
45+
llvm::outs() << OpWithFlags(op, OpPrintingFlags().skipRegions())
46+
<< " : ";
4547
lattice->print(llvm::outs());
4648
}
4749
});

mlir/test/Examples/dataflow/join.mlir

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
// RUN: dataflow-opt %s -test-metadata-analysis -split-input-file | FileCheck %s
22

3-
// CHECK: {{likes_pizza: true}}
4-
// CHECK-NEXT: {{likes_pizza: true}}
3+
// CHECK: {{.*}} = arith.addi {{.*}}, {{.*}} {metadata = {likes_pizza = true}} : index
4+
// CHECK: {{"likes_pizza": true}}
5+
// CHECK-NEXT: {{.*}} = arith.addi {{.*}}, {{.*}} : index
6+
// CHECK: {{"likes_pizza": true}}
57
func.func @single_join(%arg0 : index, %arg1 : index) -> index {
68
%1 = arith.addi %arg0, %arg1 {metadata = { likes_pizza = true }} : index
79
%2 = arith.addi %1, %arg1 : index
@@ -10,9 +12,12 @@ func.func @single_join(%arg0 : index, %arg1 : index) -> index {
1012

1113
// -----
1214

13-
// CHECK: {{likes_pizza: true}}
14-
// CHECK-NEXT: {{likes_hotdog: true}}
15-
// CHECK-NEXT: {{likes_pizza: true, likes_hotdog: true}}
15+
// CHECK: {{.*}} = arith.addi {{.*}}, {{.*}} {metadata = {likes_pizza = true}} : index
16+
// CHECK: {{"likes_pizza": true}}
17+
// CHECK-NEXT: {{.*}} = arith.addi {{.*}}, {{.*}} {metadata = {likes_hotdog = true}} : index
18+
// CHECK: {{"likes_hotdog": true}}
19+
// CHECK-NEXT: {{.*}} = arith.addi {{.*}}, {{.*}} : index
20+
// CHECK: {{"likes_hotdog": true, "likes_pizza": true}}
1621
func.func @muti_join(%arg0 : index, %arg1 : index) -> index {
1722
%1 = arith.addi %arg0, %arg1 {metadata = { likes_pizza = true }} : index
1823
%2 = arith.addi %arg0, %arg1 {metadata = { likes_hotdog = true }} : index
@@ -22,9 +27,13 @@ func.func @muti_join(%arg0 : index, %arg1 : index) -> index {
2227

2328
// -----
2429

25-
// CHECK: {{likes_pizza: true}}
26-
// CHECK-NEXT: {{likes_pizza: false}}
27-
// CHECK-NEXT: {{likes_pizza: true}}
30+
// CHECK: {{.*}} = arith.addi {{.*}}, {{.*}} {metadata = {likes_pizza = true}} : index
31+
// CHECK: {{"likes_pizza": true}}
32+
// CHECK-NEXT: {{.*}} = arith.addi {{.*}}, {{.*}} {metadata = {likes_pizza = false}} : index
33+
// CHECK: {{"likes_pizza": false}}
34+
// CHECK-NEXT: {{.*}} = arith.addi {{.*}}, {{.*}} : index
35+
// CHECK: {{"likes_pizza": true}}
36+
2837
func.func @conflict_join(%arg0 : index, %arg1 : index) -> index {
2938
%1 = arith.addi %arg0, %arg1 {metadata = { likes_pizza = true }} : index
3039
%2 = arith.addi %arg0, %arg1 {metadata = { likes_pizza = false }} : index

0 commit comments

Comments
 (0)