================ @@ -63,80 +113,140 @@ static OpBuilder::InsertPoint computeInsertPoint(Value value) { return OpBuilder::InsertPoint(insertBlock, insertPt); } +/// Helper function that computes an insertion point where the given values are +/// defined and can be used without a dominance violation. +static OpBuilder::InsertPoint computeInsertPoint(ArrayRef<Value> vals) { + assert(!vals.empty() && "expected at least one value"); + OpBuilder::InsertPoint pt = computeInsertPoint(vals.front()); + for (Value v : vals.drop_front()) + pt = chooseLaterInsertPoint(pt, computeInsertPoint(v)); + return pt; +} + //===----------------------------------------------------------------------===// // ConversionValueMapping //===----------------------------------------------------------------------===// +/// A vector of SSA values, optimized for the most common case of a single +/// value. +using ValueVector = SmallVector<Value, 1>; + namespace { + +/// Helper class to make it possible to use `ValueVector` as a key in DenseMap. +struct ValueVectorMapInfo { + static ValueVector getEmptyKey() { return ValueVector{}; } + static ValueVector getTombstoneKey() { return ValueVector{}; } + static ::llvm::hash_code getHashValue(ValueVector val) { + return ::llvm::hash_combine_range(val.begin(), val.end()); + } + static bool isEqual(ValueVector LHS, ValueVector RHS) { return LHS == RHS; } +}; + /// This class wraps a IRMapping to provide recursive lookup /// functionality, i.e. we will traverse if the mapped value also has a mapping. struct ConversionValueMapping { /// Return "true" if an SSA value is mapped to the given value. May return /// false positives. bool isMappedTo(Value value) const { return mappedTo.contains(value); } - /// Lookup the most recently mapped value with the desired type in the + /// Lookup the most recently mapped values with the desired types in the /// mapping. /// /// Special cases: - /// - If the desired type is "null", simply return the most recently mapped - /// value. - /// - If there is no mapping to the desired type, also return the most - /// recently mapped value. - /// - If there is no mapping for the given value at all, return the given - /// value. - Value lookupOrDefault(Value from, Type desiredType = nullptr) const; - - /// Lookup a mapped value within the map, or return null if a mapping does not - /// exist. If a mapping exists, this follows the same behavior of - /// `lookupOrDefault`. - Value lookupOrNull(Value from, Type desiredType = nullptr) const; + /// - If the desired type range is empty, simply return the most recently + /// mapped values. + /// - If there is no mapping to the desired types, also return the most + /// recently mapped values. + /// - If there is no mapping for the given values at all, return the given + /// values. + ValueVector lookupOrDefault(ValueVector from, + TypeRange desiredTypes = {}) const; + + /// Lookup the given values within the map, or return an empty vector if the + /// values are not mapped. If they are mapped, this follows the same behavior + /// as `lookupOrDefault`. + ValueVector lookupOrNull(const ValueVector &from, + TypeRange desiredTypes = {}) const; /// Map a value to the one provided. - void map(Value oldVal, Value newVal) { + void map(const ValueVector &oldVal, const ValueVector &newVal) { LLVM_DEBUG({ - for (Value it = newVal; it; it = mapping.lookupOrNull(it)) - assert(it != oldVal && "inserting cyclic mapping"); + ValueVector next = newVal; + while (true) { + assert(next != oldVal && "inserting cyclic mapping"); + auto it = mapping.find(next); + if (it == mapping.end()) + break; + next = it->second; + } }); - mapping.map(oldVal, newVal); - mappedTo.insert(newVal); + mapping[oldVal] = newVal; + for (Value v : newVal) + mappedTo.insert(v); } - /// Drop the last mapping for the given value. - void erase(Value value) { mapping.erase(value); } + /// Drop the last mapping for the given values. + void erase(ValueVector value) { mapping.erase(value); } private: /// Current value mappings. - IRMapping mapping; + DenseMap<ValueVector, ValueVector, ValueVectorMapInfo> mapping; /// All SSA values that are mapped to. May contain false positives. DenseSet<Value> mappedTo; }; } // namespace -Value ConversionValueMapping::lookupOrDefault(Value from, - Type desiredType) const { - // Try to find the deepest value that has the desired type. If there is no - // such value, simply return the deepest value. - Value desiredValue; +ValueVector +ConversionValueMapping::lookupOrDefault(ValueVector from, + TypeRange desiredTypes) const { + // Try to find the deepest values that have the desired types. If there is no + // such mapping, simply return the deepest values. + ValueVector desiredValue; do { - if (!desiredType || from.getType() == desiredType) + // Store the current value if the types match. + if (desiredTypes.empty() || TypeRange(from) == desiredTypes) desiredValue = from; - Value mappedValue = mapping.lookupOrNull(from); - if (!mappedValue) + // If possible, Replace each value with (one or multiple) mapped values. + ValueVector next; + for (Value v : from) { + auto it = mapping.find({v}); + if (it != mapping.end()) { + llvm::append_range(next, it->second); + } else { + next.push_back(v); + } + } + if (next != from) { + // If at least one value was replaced, continue the lookup from there. + from = next; ---------------- zero9178 wrote:
```suggestion from = std::move(next); ``` https://github.com/llvm/llvm-project/pull/116524 _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits