1 //===- BlockAndValueMapping.h -----------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file defines a utility class for maintaining a mapping for multiple 10 // value types. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef MLIR_IR_BLOCKANDVALUEMAPPING_H 15 #define MLIR_IR_BLOCKANDVALUEMAPPING_H 16 17 #include "mlir/IR/Block.h" 18 19 namespace mlir { 20 // This is a utility class for mapping one set of values to another. New 21 // mappings can be inserted via 'map'. Existing mappings can be 22 // found via the 'lookup*' functions. There are two variants that differ only in 23 // return value when an existing is not found for the provided key. 24 // 'lookupOrNull' returns nullptr where as 'lookupOrDefault' will return the 25 // lookup key. 26 class BlockAndValueMapping { 27 public: 28 /// Inserts a new mapping for 'from' to 'to'. If there is an existing mapping, 29 /// it is overwritten. map(Block * from,Block * to)30 void map(Block *from, Block *to) { valueMap[from] = to; } map(Value from,Value to)31 void map(Value from, Value to) { 32 valueMap[from.getAsOpaquePointer()] = to.getAsOpaquePointer(); 33 } 34 35 template < 36 typename S, typename T, 37 std::enable_if_t<!std::is_assignable<Value, S>::value && 38 !std::is_assignable<Block *, S>::value> * = nullptr> map(S && from,T && to)39 void map(S &&from, T &&to) { 40 for (auto pair : llvm::zip(from, to)) 41 map(std::get<0>(pair), std::get<1>(pair)); 42 } 43 44 /// Erases a mapping for 'from'. erase(Block * from)45 void erase(Block *from) { valueMap.erase(from); } erase(Value from)46 void erase(Value from) { valueMap.erase(from.getAsOpaquePointer()); } 47 48 /// Checks to see if a mapping for 'from' exists. contains(Block * from)49 bool contains(Block *from) const { return valueMap.count(from); } contains(Value from)50 bool contains(Value from) const { 51 return valueMap.count(from.getAsOpaquePointer()); 52 } 53 54 /// Lookup a mapped value within the map. If a mapping for the provided value 55 /// does not exist then return nullptr. lookupOrNull(Block * from)56 Block *lookupOrNull(Block *from) const { 57 return lookupOrValue(from, (Block *)nullptr); 58 } lookupOrNull(Value from)59 Value lookupOrNull(Value from) const { return lookupOrValue(from, Value()); } 60 61 /// Lookup a mapped value within the map. If a mapping for the provided value 62 /// does not exist then return the provided value. lookupOrDefault(Block * from)63 Block *lookupOrDefault(Block *from) const { 64 return lookupOrValue(from, from); 65 } lookupOrDefault(Value from)66 Value lookupOrDefault(Value from) const { return lookupOrValue(from, from); } 67 68 /// Lookup a mapped value within the map. This asserts the provided value 69 /// exists within the map. lookup(T from)70 template <typename T> T lookup(T from) const { 71 auto result = lookupOrNull(from); 72 assert(result && "expected 'from' to be contained within the map"); 73 return result; 74 } 75 76 /// Clears all mappings held by the mapper. clear()77 void clear() { valueMap.clear(); } 78 79 private: 80 /// Utility lookupOrValue that looks up an existing key or returns the 81 /// provided value. lookupOrValue(Block * from,Block * value)82 Block *lookupOrValue(Block *from, Block *value) const { 83 auto it = valueMap.find(from); 84 return it != valueMap.end() ? reinterpret_cast<Block *>(it->second) : value; 85 } lookupOrValue(Value from,Value value)86 Value lookupOrValue(Value from, Value value) const { 87 auto it = valueMap.find(from.getAsOpaquePointer()); 88 return it != valueMap.end() ? Value::getFromOpaquePointer(it->second) 89 : value; 90 } 91 92 DenseMap<void *, void *> valueMap; 93 }; 94 95 } // end namespace mlir 96 97 #endif // MLIR_IR_BLOCKANDVALUEMAPPING_H 98