Continue pushing const out of the core IR types - in this case, remove const
from Function.

PiperOrigin-RevId: 239638635
diff --git a/bindings/python/pybind.cpp b/bindings/python/pybind.cpp
index e83b4dd..0184f8f 100644
--- a/bindings/python/pybind.cpp
+++ b/bindings/python/pybind.cpp
@@ -945,7 +945,7 @@
     return ValueHandle::create<ConstantFloatOp>(value, floatType);
   });
   m.def("constant_function", [](PythonFunction func) -> PythonValueHandle {
-    auto *function = reinterpret_cast<const Function *>(func.function);
+    auto *function = reinterpret_cast<Function *>(func.function);
     auto attr = FunctionAttr::get(function, function->getContext());
     return ValueHandle::create<ConstantOp>(function->getType(), attr);
   });
diff --git a/include/mlir/ExecutionEngine/MemRefUtils.h b/include/mlir/ExecutionEngine/MemRefUtils.h
index 95e8686..a2d982d 100644
--- a/include/mlir/ExecutionEngine/MemRefUtils.h
+++ b/include/mlir/ExecutionEngine/MemRefUtils.h
@@ -44,7 +44,7 @@
 /// each of the arguments, initialize the storage with `initialValue`, and
 /// return a list of type-erased descriptor pointers.
 llvm::Expected<SmallVector<void *, 8>>
-allocateMemRefArguments(const Function *func, float initialValue = 0.0);
+allocateMemRefArguments(Function *func, float initialValue = 0.0);
 
 /// Free a list of type-erased descriptors to statically-shaped memrefs with
 /// element type f32.
diff --git a/include/mlir/IR/Attributes.h b/include/mlir/IR/Attributes.h
index 3169364..132105e 100644
--- a/include/mlir/IR/Attributes.h
+++ b/include/mlir/IR/Attributes.h
@@ -323,7 +323,7 @@
   using ImplType = detail::FunctionAttributeStorage;
   using ValueType = Function *;
 
-  static FunctionAttr get(const Function *value, MLIRContext *context);
+  static FunctionAttr get(Function *value, MLIRContext *context);
 
   Function *getValue() const;
 
diff --git a/include/mlir/IR/Block.h b/include/mlir/IR/Block.h
index babc150..9269c25 100644
--- a/include/mlir/IR/Block.h
+++ b/include/mlir/IR/Block.h
@@ -109,10 +109,7 @@
 
   /// Returns the function that this block is part of, even if the block is
   /// nested under an operation region.
-  Function *getFunction();
-  const Function *getFunction() const {
-    return const_cast<Block *>(this)->getFunction();
-  }
+  Function *getFunction() const;
 
   /// Insert this block (which must not already be in a function) right before
   /// the specified block.
@@ -428,10 +425,7 @@
 
   /// A Region is either a function body or a part of an operation.  If it is
   /// a Function body, then return this function, otherwise return null.
-  Function *getContainingFunction();
-  const Function *getContainingFunction() const {
-    return const_cast<Region *>(this)->getContainingFunction();
-  }
+  Function *getContainingFunction() const;
 
   /// Clone the internal blocks from this region into dest. Any
   /// cloned blocks are appended to the back of dest. If the mapper
diff --git a/include/mlir/IR/Builders.h b/include/mlir/IR/Builders.h
index b3aba25..44df05f 100644
--- a/include/mlir/IR/Builders.h
+++ b/include/mlir/IR/Builders.h
@@ -108,7 +108,7 @@
   AffineMapAttr getAffineMapAttr(AffineMap map);
   IntegerSetAttr getIntegerSetAttr(IntegerSet set);
   TypeAttr getTypeAttr(Type type);
-  FunctionAttr getFunctionAttr(const Function *value);
+  FunctionAttr getFunctionAttr(Function *value);
   ElementsAttr getSplatElementsAttr(VectorOrTensorType type, Attribute elt);
   ElementsAttr getDenseElementsAttr(VectorOrTensorType type,
                                     ArrayRef<char> data);
diff --git a/include/mlir/IR/Dialect.h b/include/mlir/IR/Dialect.h
index 1994c11..cf1a6e5 100644
--- a/include/mlir/IR/Dialect.h
+++ b/include/mlir/IR/Dialect.h
@@ -103,14 +103,14 @@
 
   /// Verify an attribute from this dialect on the given function. Returns true
   /// if the verification failed, false otherwise.
-  virtual bool verifyFunctionAttribute(const Function *, NamedAttribute) {
+  virtual bool verifyFunctionAttribute(Function *, NamedAttribute) {
     return false;
   }
 
   /// Verify an attribute from this dialect on the argument at 'argIndex' for
   /// the given function. Returns true if the verification failed, false
   /// otherwise.
-  virtual bool verifyFunctionArgAttribute(const Function *, unsigned argIndex,
+  virtual bool verifyFunctionArgAttribute(Function *, unsigned argIndex,
                                           NamedAttribute) {
     return false;
   }
diff --git a/include/mlir/IR/Function.h b/include/mlir/IR/Function.h
index 221c5c4..bc36a06 100644
--- a/include/mlir/IR/Function.h
+++ b/include/mlir/IR/Function.h
@@ -36,7 +36,7 @@
 class FunctionType;
 class MLIRContext;
 class Module;
-template <typename ObjectType, typename ElementType> class ArgumentIterator;
+class ArgumentIterator;
 template <typename T> class OpPointer;
 
 /// This is the base class for all of the MLIR function types.
@@ -51,20 +51,19 @@
   ~Function();
 
   /// The source location the function was defined or derived from.
-  Location getLoc() const { return location; }
+  Location getLoc() { return location; }
 
   /// Set the source location this function was defined or derived from.
   void setLoc(Location loc) { location = loc; }
 
   /// Return the name of this function, without the @.
-  Identifier getName() const { return name; }
+  Identifier getName() { return name; }
 
   /// Return the type of this function.
-  FunctionType getType() const { return type; }
+  FunctionType getType() { return type; }
 
-  MLIRContext *getContext() const;
+  MLIRContext *getContext();
   Module *getModule() { return module; }
-  const Module *getModule() const { return module; }
 
   /// Add an entry block to an empty function, and set up the block arguments
   /// to match the signature of the function.
@@ -74,44 +73,33 @@
   void erase();
 
   /// Returns true if this function is external, i.e. it has no body.
-  bool isExternal() const { return empty(); }
+  bool isExternal() { return empty(); }
 
   //===--------------------------------------------------------------------===//
   // Body Handling
   //===--------------------------------------------------------------------===//
 
   Region &getBody() { return body; }
-  const Region &getBody() const { return body; }
 
   /// This is the list of blocks in the function.
   using RegionType = llvm::iplist<Block>;
   RegionType &getBlocks() { return body.getBlocks(); }
-  const RegionType &getBlocks() const { return body.getBlocks(); }
 
   // Iteration over the block in the function.
   using iterator = RegionType::iterator;
-  using const_iterator = RegionType::const_iterator;
   using reverse_iterator = RegionType::reverse_iterator;
-  using const_reverse_iterator = RegionType::const_reverse_iterator;
 
   iterator begin() { return body.begin(); }
   iterator end() { return body.end(); }
-  const_iterator begin() const { return body.begin(); }
-  const_iterator end() const { return body.end(); }
   reverse_iterator rbegin() { return body.rbegin(); }
   reverse_iterator rend() { return body.rend(); }
-  const_reverse_iterator rbegin() const { return body.rbegin(); }
-  const_reverse_iterator rend() const { return body.rend(); }
 
-  bool empty() const { return body.empty(); }
+  bool empty() { return body.empty(); }
   void push_back(Block *block) { body.push_back(block); }
   void push_front(Block *block) { body.push_front(block); }
 
   Block &back() { return body.back(); }
-  const Block &back() const { return const_cast<Function *>(this)->back(); }
-
   Block &front() { return body.front(); }
-  const Block &front() const { return const_cast<Function *>(this)->front(); }
 
   //===--------------------------------------------------------------------===//
   // Instruction Walkers
@@ -148,30 +136,19 @@
   //===--------------------------------------------------------------------===//
 
   /// Returns number of arguments.
-  unsigned getNumArguments() const { return getType().getInputs().size(); }
+  unsigned getNumArguments() { return getType().getInputs().size(); }
 
   /// Gets argument.
   BlockArgument *getArgument(unsigned idx) {
     return getBlocks().front().getArgument(idx);
   }
 
-  const BlockArgument *getArgument(unsigned idx) const {
-    return getBlocks().front().getArgument(idx);
-  }
-
   // Supports non-const operand iteration.
-  using args_iterator = ArgumentIterator<Function, BlockArgument>;
+  using args_iterator = ArgumentIterator;
   args_iterator args_begin();
   args_iterator args_end();
   llvm::iterator_range<args_iterator> getArguments();
 
-  // Supports const operand iteration.
-  using const_args_iterator =
-      ArgumentIterator<const Function, const BlockArgument>;
-  const_args_iterator args_begin() const;
-  const_args_iterator args_end() const;
-  llvm::iterator_range<const_args_iterator> getArguments() const;
-
   //===--------------------------------------------------------------------===//
   // Attributes
   //===--------------------------------------------------------------------===//
@@ -181,10 +158,10 @@
   /// the lifetime of an function.
 
   /// Return all of the attributes on this function.
-  ArrayRef<NamedAttribute> getAttrs() const { return attrs.getAttrs(); }
+  ArrayRef<NamedAttribute> getAttrs() { return attrs.getAttrs(); }
 
   /// Return all of the attributes for the argument at 'index'.
-  ArrayRef<NamedAttribute> getArgAttrs(unsigned index) const {
+  ArrayRef<NamedAttribute> getArgAttrs(unsigned index) {
     assert(index < getNumArguments() && "invalid argument number");
     return argAttrs[index].getAttrs();
   }
@@ -202,38 +179,37 @@
 
   /// Return all argument attributes of this function.
   MutableArrayRef<NamedAttributeList> getAllArgAttrs() { return argAttrs; }
-  ArrayRef<NamedAttributeList> getAllArgAttrs() const { return argAttrs; }
 
   /// Return the specified attribute if present, null otherwise.
-  Attribute getAttr(Identifier name) const { return attrs.get(name); }
-  Attribute getAttr(StringRef name) const { return attrs.get(name); }
+  Attribute getAttr(Identifier name) { return attrs.get(name); }
+  Attribute getAttr(StringRef name) { return attrs.get(name); }
 
   /// Return the specified attribute, if present, for the argument at 'index',
   /// null otherwise.
-  Attribute getArgAttr(unsigned index, Identifier name) const {
+  Attribute getArgAttr(unsigned index, Identifier name) {
     assert(index < getNumArguments() && "invalid argument number");
     return argAttrs[index].get(name);
   }
-  Attribute getArgAttr(unsigned index, StringRef name) const {
+  Attribute getArgAttr(unsigned index, StringRef name) {
     assert(index < getNumArguments() && "invalid argument number");
     return argAttrs[index].get(name);
   }
 
-  template <typename AttrClass> AttrClass getAttrOfType(Identifier name) const {
+  template <typename AttrClass> AttrClass getAttrOfType(Identifier name) {
     return getAttr(name).dyn_cast_or_null<AttrClass>();
   }
 
-  template <typename AttrClass> AttrClass getAttrOfType(StringRef name) const {
+  template <typename AttrClass> AttrClass getAttrOfType(StringRef name) {
     return getAttr(name).dyn_cast_or_null<AttrClass>();
   }
 
   template <typename AttrClass>
-  AttrClass getArgAttrOfType(unsigned index, Identifier name) const {
+  AttrClass getArgAttrOfType(unsigned index, Identifier name) {
     return getArgAttr(index, name).dyn_cast_or_null<AttrClass>();
   }
 
   template <typename AttrClass>
-  AttrClass getArgAttrOfType(unsigned index, StringRef name) const {
+  AttrClass getArgAttrOfType(unsigned index, StringRef name) {
     return getArgAttr(index, name).dyn_cast_or_null<AttrClass>();
   }
 
@@ -271,30 +247,30 @@
   /// Perform (potentially expensive) checks of invariants, used to detect
   /// compiler bugs.  On error, this reports the error through the MLIRContext
   /// and returns true.
-  bool verify() const;
+  bool verify();
 
-  void print(raw_ostream &os) const;
-  void dump() const;
+  void print(raw_ostream &os);
+  void dump();
 
   /// Emit an error about fatal conditions with this operation, reporting up to
   /// any diagnostic handlers that may be listening.  This function always
   /// returns true.  NOTE: This may terminate the containing application, only
   /// use when the IR is in an inconsistent state.
-  bool emitError(const Twine &message) const;
+  bool emitError(const Twine &message);
 
   /// Emit a warning about this operation, reporting up to any diagnostic
   /// handlers that may be listening.
-  void emitWarning(const Twine &message) const;
+  void emitWarning(const Twine &message);
 
   /// Emit a note about this operation, reporting up to any diagnostic
   /// handlers that may be listening.
-  void emitNote(const Twine &message) const;
+  void emitNote(const Twine &message);
 
   /// Displays the CFG in a window. This is for use from the debugger and
   /// depends on Graphviz to generate the graph.
   /// This function is defined in CFGFunctionViewGraph and only works with that
   /// target linked.
-  void viewGraph() const;
+  void viewGraph();
 
   /// Create a deep copy of this function and all of its blocks, remapping
   /// any operands that use values outside of the function using the map that is
@@ -302,13 +278,13 @@
   /// contains entries for function arguments, these arguments are not included
   /// in the new function. Replaces references to cloned sub-values with the
   /// corresponding value that is copied, and adds those mappings to the mapper.
-  Function *clone(BlockAndValueMapping &mapper) const;
-  Function *clone() const;
+  Function *clone(BlockAndValueMapping &mapper);
+  Function *clone();
 
   /// Clone the internal blocks and attributes from this function into dest. Any
   /// cloned blocks are appended to the back of dest. This function asserts that
   /// the attributes of the current function and dest are compatible.
-  void cloneInto(Function *dest, BlockAndValueMapping &mapper) const;
+  void cloneInto(Function *dest, BlockAndValueMapping &mapper);
 
 private:
   /// The name of the function.
@@ -332,7 +308,7 @@
   /// The body of the function.
   Region body;
 
-  void operator=(const Function &) = delete;
+  void operator=(Function &) = delete;
   friend struct llvm::ilist_traits<Function>;
 };
 
@@ -341,24 +317,16 @@
 //===--------------------------------------------------------------------===//
 
 /// This template implements the argument iterator in terms of getArgument(idx).
-template <typename ObjectType, typename ElementType>
 class ArgumentIterator final
-    : public IndexedAccessorIterator<ArgumentIterator<ObjectType, ElementType>,
-                                     ObjectType, ElementType> {
+    : public IndexedAccessorIterator<ArgumentIterator, Function,
+                                     BlockArgument> {
 public:
   /// Initializes the result iterator to the specified index.
-  ArgumentIterator(ObjectType *object, unsigned index)
-      : IndexedAccessorIterator<ArgumentIterator<ObjectType, ElementType>,
-                                ObjectType, ElementType>(object, index) {}
+  ArgumentIterator(Function *object, unsigned index)
+      : IndexedAccessorIterator<ArgumentIterator, Function, BlockArgument>(
+            object, index) {}
 
-  /// Support converting to the const variant. This will be a no-op for const
-  /// variant.
-  operator ArgumentIterator<const ObjectType, const ElementType>() const {
-    return ArgumentIterator<const ObjectType, const ElementType>(this->object,
-                                                                 this->index);
-  }
-
-  ElementType *operator*() const {
+  BlockArgument *operator*() const {
     return this->object->getArgument(this->index);
   }
 };
@@ -379,19 +347,6 @@
   return {args_begin(), args_end()};
 }
 
-inline Function::const_args_iterator Function::args_begin() const {
-  return const_args_iterator(this, 0);
-}
-
-inline Function::const_args_iterator Function::args_end() const {
-  return const_args_iterator(this, getNumArguments());
-}
-
-inline llvm::iterator_range<Function::const_args_iterator>
-Function::getArguments() const {
-  return {args_begin(), args_end()};
-}
-
 } // end namespace mlir
 
 //===----------------------------------------------------------------------===//
diff --git a/include/mlir/IR/FunctionGraphTraits.h b/include/mlir/IR/FunctionGraphTraits.h
index b8a0d7e..a47b97e 100644
--- a/include/mlir/IR/FunctionGraphTraits.h
+++ b/include/mlir/IR/FunctionGraphTraits.h
@@ -102,23 +102,6 @@
 };
 
 template <>
-struct GraphTraits<const mlir::Function *>
-    : public GraphTraits<const mlir::Block *> {
-  using GraphType = const mlir::Function *;
-  using NodeRef = const mlir::Block *;
-
-  static NodeRef getEntryNode(GraphType fn) { return &fn->front(); }
-
-  using nodes_iterator = pointer_iterator<mlir::Function::const_iterator>;
-  static nodes_iterator nodes_begin(GraphType fn) {
-    return nodes_iterator(fn->begin());
-  }
-  static nodes_iterator nodes_end(GraphType fn) {
-    return nodes_iterator(fn->end());
-  }
-};
-
-template <>
 struct GraphTraits<Inverse<mlir::Function *>>
     : public GraphTraits<Inverse<mlir::Block *>> {
   using GraphType = Inverse<mlir::Function *>;
@@ -136,23 +119,6 @@
 };
 
 template <>
-struct GraphTraits<Inverse<const mlir::Function *>>
-    : public GraphTraits<Inverse<const mlir::Block *>> {
-  using GraphType = Inverse<const mlir::Function *>;
-  using NodeRef = NodeRef;
-
-  static NodeRef getEntryNode(GraphType fn) { return &fn.Graph->front(); }
-
-  using nodes_iterator = pointer_iterator<mlir::Function::const_iterator>;
-  static nodes_iterator nodes_begin(GraphType fn) {
-    return nodes_iterator(fn.Graph->begin());
-  }
-  static nodes_iterator nodes_end(GraphType fn) {
-    return nodes_iterator(fn.Graph->end());
-  }
-};
-
-template <>
 struct GraphTraits<mlir::Region *> : public GraphTraits<mlir::Block *> {
   using GraphType = mlir::Region *;
   using NodeRef = mlir::Block *;
@@ -169,23 +135,6 @@
 };
 
 template <>
-struct GraphTraits<const mlir::Region *>
-    : public GraphTraits<const mlir::Block *> {
-  using GraphType = const mlir::Region *;
-  using NodeRef = const mlir::Block *;
-
-  static NodeRef getEntryNode(GraphType fn) { return &fn->front(); }
-
-  using nodes_iterator = pointer_iterator<mlir::Function::const_iterator>;
-  static nodes_iterator nodes_begin(GraphType fn) {
-    return nodes_iterator(fn->begin());
-  }
-  static nodes_iterator nodes_end(GraphType fn) {
-    return nodes_iterator(fn->end());
-  }
-};
-
-template <>
 struct GraphTraits<Inverse<mlir::Region *>>
     : public GraphTraits<Inverse<mlir::Block *>> {
   using GraphType = Inverse<mlir::Region *>;
@@ -202,23 +151,6 @@
   }
 };
 
-template <>
-struct GraphTraits<Inverse<const mlir::Region *>>
-    : public GraphTraits<Inverse<const mlir::Block *>> {
-  using GraphType = Inverse<const mlir::Region *>;
-  using NodeRef = NodeRef;
-
-  static NodeRef getEntryNode(GraphType fn) { return &fn.Graph->front(); }
-
-  using nodes_iterator = pointer_iterator<mlir::Function::const_iterator>;
-  static nodes_iterator nodes_begin(GraphType fn) {
-    return nodes_iterator(fn.Graph->begin());
-  }
-  static nodes_iterator nodes_end(GraphType fn) {
-    return nodes_iterator(fn.Graph->end());
-  }
-};
-
 } // namespace llvm
 
 #endif
diff --git a/include/mlir/IR/Module.h b/include/mlir/IR/Module.h
index d1720a8..fd43b07 100644
--- a/include/mlir/IR/Module.h
+++ b/include/mlir/IR/Module.h
@@ -25,7 +25,6 @@
 #include "mlir/IR/Function.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/ilist.h"
-#include <vector>
 
 namespace mlir {
 
diff --git a/include/mlir/IR/OpImplementation.h b/include/mlir/IR/OpImplementation.h
index fcdf2b6..5ad22e6 100644
--- a/include/mlir/IR/OpImplementation.h
+++ b/include/mlir/IR/OpImplementation.h
@@ -68,7 +68,7 @@
     }
   }
   virtual void printType(Type type) = 0;
-  virtual void printFunctionReference(const Function *func) = 0;
+  virtual void printFunctionReference(Function *func) = 0;
   virtual void printAttribute(Attribute attr) = 0;
   virtual void printAttributeAndType(Attribute attr) = 0;
   virtual void printAffineMap(AffineMap map) = 0;
diff --git a/include/mlir/IR/Value.h b/include/mlir/IR/Value.h
index acc3925..c34474f 100644
--- a/include/mlir/IR/Value.h
+++ b/include/mlir/IR/Value.h
@@ -60,12 +60,7 @@
   }
 
   /// Return the function that this Value is defined in.
-  Function *getFunction();
-
-  /// Return the function that this Value is defined in.
-  const Function *getFunction() const {
-    return const_cast<Value *>(this)->getFunction();
-  }
+  Function *getFunction() const;
 
   /// If this value is the result of an operation, return the instruction
   /// that defines it.
@@ -119,10 +114,7 @@
   }
 
   /// Return the function that this argument is defined in.
-  Function *getFunction();
-  const Function *getFunction() const {
-    return const_cast<BlockArgument *>(this)->getFunction();
-  }
+  Function *getFunction() const;
 
   Block *getOwner() { return owner; }
   const Block *getOwner() const { return owner; }
diff --git a/include/mlir/LLVMIR/LLVMDialect.h b/include/mlir/LLVMIR/LLVMDialect.h
index 7ea4792..e07d496 100644
--- a/include/mlir/LLVMIR/LLVMDialect.h
+++ b/include/mlir/LLVMIR/LLVMDialect.h
@@ -81,7 +81,7 @@
 
   /// Verify a function argument attribute registered to this dialect.
   /// Returns true if the verification failed, false otherwise.
-  bool verifyFunctionArgAttribute(const Function *func, unsigned argIdx,
+  bool verifyFunctionArgAttribute(Function *func, unsigned argIdx,
                                   NamedAttribute argAttr) override;
 
 private:
diff --git a/include/mlir/Transforms/ViewFunctionGraph.h b/include/mlir/Transforms/ViewFunctionGraph.h
index 33b85b6..f56003b 100644
--- a/include/mlir/Transforms/ViewFunctionGraph.h
+++ b/include/mlir/Transforms/ViewFunctionGraph.h
@@ -33,11 +33,11 @@
 
 /// Displays the CFG in a window. This is for use from the debugger and
 /// depends on Graphviz to generate the graph.
-void viewGraph(const Function &function, const Twine &name,
-               bool shortNames = false, const Twine &title = "",
+void viewGraph(Function &function, const Twine &name, bool shortNames = false,
+               const Twine &title = "",
                llvm::GraphProgram::Name program = llvm::GraphProgram::DOT);
 
-llvm::raw_ostream &writeGraph(llvm::raw_ostream &os, const Function *function,
+llvm::raw_ostream &writeGraph(llvm::raw_ostream &os, Function *function,
                               bool shortNames = false, const Twine &title = "");
 
 /// Creates a pass to print CFG graphs.
diff --git a/lib/Analysis/Verifier.cpp b/lib/Analysis/Verifier.cpp
index 8fdda7f..faab0cd 100644
--- a/lib/Analysis/Verifier.cpp
+++ b/lib/Analysis/Verifier.cpp
@@ -56,7 +56,7 @@
     return value.emitError(message);
   }
 
-  bool failure(const Twine &message, const Function &fn) {
+  bool failure(const Twine &message, Function &fn) {
     return fn.emitError(message);
   }
 
@@ -79,7 +79,7 @@
   }
 
   template <typename ErrorContext>
-  bool verifyAttribute(Attribute attr, const ErrorContext &ctx) {
+  bool verifyAttribute(Attribute attr, ErrorContext &ctx) {
     if (!attr.isOrContainsFunction())
       return false;
 
@@ -112,12 +112,12 @@
   bool verifyDominance(const Block &block);
   bool verifyInstDominance(const Instruction &inst);
 
-  explicit FuncVerifier(const Function &fn)
+  explicit FuncVerifier(Function &fn)
       : fn(fn), identifierRegex("^[a-zA-Z_][a-zA-Z_0-9\\.\\$]*$") {}
 
 private:
   /// The function being checked.
-  const Function &fn;
+  Function &fn;
 
   /// Dominance information for this function, when checking dominance.
   DominanceInfo *domInfo = nullptr;
@@ -288,7 +288,7 @@
     if (!identifierRegex.match(attr.first))
       return failure("invalid attribute name '" + attr.first.strref() + "'",
                      op);
-    if (verifyAttribute(attr.second, op))
+    if (verifyAttribute(attr.second, const_cast<Instruction &>(op)))
       return true;
 
     // Check for any optional dialect specific attributes.
@@ -353,7 +353,7 @@
 /// Perform (potentially expensive) checks of invariants, used to detect
 /// compiler bugs.  On error, this reports the error through the MLIRContext and
 /// returns true.
-bool Function::verify() const { return FuncVerifier(*this).verify(); }
+bool Function::verify() { return FuncVerifier(*this).verify(); }
 
 /// Perform (potentially expensive) checks of invariants, used to detect
 /// compiler bugs.  On error, this reports the error through the MLIRContext and
diff --git a/lib/ExecutionEngine/MemRefUtils.cpp b/lib/ExecutionEngine/MemRefUtils.cpp
index b2b301d..b6404bb 100644
--- a/lib/ExecutionEngine/MemRefUtils.cpp
+++ b/lib/ExecutionEngine/MemRefUtils.cpp
@@ -66,7 +66,7 @@
 }
 
 llvm::Expected<SmallVector<void *, 8>>
-mlir::allocateMemRefArguments(const Function *func, float initialValue) {
+mlir::allocateMemRefArguments(Function *func, float initialValue) {
   SmallVector<void *, 8> args;
   args.reserve(func->getNumArguments());
   for (const auto &arg : func->getArguments()) {
diff --git a/lib/IR/AsmPrinter.cpp b/lib/IR/AsmPrinter.cpp
index 78bc456..b93fe0d 100644
--- a/lib/IR/AsmPrinter.cpp
+++ b/lib/IR/AsmPrinter.cpp
@@ -295,7 +295,7 @@
   }
 
   void print(Module *module);
-  void printFunctionReference(const Function *func);
+  void printFunctionReference(Function *func);
   void printAttributeAndType(Attribute attr) {
     printAttributeOptionalType(attr, /*includeType=*/true);
   }
@@ -304,7 +304,7 @@
   }
 
   void printType(Type type);
-  void print(const Function *fn);
+  void print(Function *fn);
   void printLocation(Location loc);
 
   void printAffineMap(AffineMap map);
@@ -489,7 +489,7 @@
     if (!alias.empty())
       os << '!' << alias << " = type " << type << '\n';
   }
-  for (auto const &fn : *module)
+  for (auto &fn : *module)
     print(&fn);
 }
 
@@ -525,7 +525,7 @@
   os << str;
 }
 
-void ModulePrinter::printFunctionReference(const Function *func) {
+void ModulePrinter::printFunctionReference(Function *func) {
   os << '@' << func->getName();
 }
 
@@ -1051,7 +1051,7 @@
 // CFG and ML functions.
 class FunctionPrinter : public ModulePrinter, private OpAsmPrinter {
 public:
-  FunctionPrinter(const Function *function, ModulePrinter &other);
+  FunctionPrinter(Function *function, ModulePrinter &other);
 
   // Prints the function as a whole.
   void print();
@@ -1082,7 +1082,7 @@
   void printAffineExpr(AffineExpr expr) {
     return ModulePrinter::printAffineExpr(expr);
   }
-  void printFunctionReference(const Function *func) {
+  void printFunctionReference(Function *func) {
     return ModulePrinter::printFunctionReference(func);
   }
   void printOperand(const Value *value) { printValueID(value); }
@@ -1132,7 +1132,7 @@
   void printValueID(const Value *value, bool printResultNo = true) const;
 
 private:
-  const Function *function;
+  Function *function;
 
   /// This is the value ID for each SSA value in the current function.  If this
   /// returns ~0, then the valueID has an entry in valueNames.
@@ -1162,7 +1162,7 @@
 };
 } // end anonymous namespace
 
-FunctionPrinter::FunctionPrinter(const Function *function, ModulePrinter &other)
+FunctionPrinter::FunctionPrinter(Function *function, ModulePrinter &other)
     : ModulePrinter(other), function(function) {
 
   for (auto &block : *function)
@@ -1527,9 +1527,7 @@
 }
 
 // Prints function with initialized module state.
-void ModulePrinter::print(const Function *fn) {
-  FunctionPrinter(fn, *this).print();
-}
+void ModulePrinter::print(Function *fn) { FunctionPrinter(fn, *this).print(); }
 
 //===----------------------------------------------------------------------===//
 // print and dump methods
@@ -1642,12 +1640,12 @@
   FunctionPrinter(getFunction(), modulePrinter).printBlockName(this);
 }
 
-void Function::print(raw_ostream &os) const {
+void Function::print(raw_ostream &os) {
   ModuleState state(getContext());
   ModulePrinter(os, state).print(this);
 }
 
-void Function::dump() const { print(llvm::errs()); }
+void Function::dump() { print(llvm::errs()); }
 
 void Module::print(raw_ostream &os) {
   ModuleState state(getContext());
diff --git a/lib/IR/Block.cpp b/lib/IR/Block.cpp
index eddf124..4d407fd 100644
--- a/lib/IR/Block.cpp
+++ b/lib/IR/Block.cpp
@@ -49,8 +49,8 @@
   return getParent() ? getParent()->getContainingInst() : nullptr;
 }
 
-Function *Block::getFunction() {
-  Block *block = this;
+Function *Block::getFunction() const {
+  const Block *block = this;
   while (auto *inst = block->getContainingInst()) {
     block = inst->getBlock();
     if (!block)
@@ -273,7 +273,7 @@
   return container.dyn_cast<Instruction *>();
 }
 
-Function *Region::getContainingFunction() {
+Function *Region::getContainingFunction() const {
   return container.dyn_cast<Function *>();
 }
 
diff --git a/lib/IR/Builders.cpp b/lib/IR/Builders.cpp
index 917bae6..e05739d 100644
--- a/lib/IR/Builders.cpp
+++ b/lib/IR/Builders.cpp
@@ -166,7 +166,7 @@
   return TypeAttr::get(type, context);
 }
 
-FunctionAttr Builder::getFunctionAttr(const Function *value) {
+FunctionAttr Builder::getFunctionAttr(Function *value) {
   return FunctionAttr::get(value, context);
 }
 
diff --git a/lib/IR/Function.cpp b/lib/IR/Function.cpp
index 107f1b5..e21e512 100644
--- a/lib/IR/Function.cpp
+++ b/lib/IR/Function.cpp
@@ -49,7 +49,7 @@
   FunctionAttr::dropFunctionReference(this);
 }
 
-MLIRContext *Function::getContext() const { return getType().getContext(); }
+MLIRContext *Function::getContext() { return getType().getContext(); }
 
 Module *llvm::ilist_traits<Function>::getContainingModule() {
   size_t Offset(
@@ -122,14 +122,14 @@
 
 /// Emit a note about this instruction, reporting up to any diagnostic
 /// handlers that may be listening.
-void Function::emitNote(const Twine &message) const {
+void Function::emitNote(const Twine &message) {
   getContext()->emitDiagnostic(getLoc(), message,
                                MLIRContext::DiagnosticKind::Note);
 }
 
 /// Emit a warning about this operation, reporting up to any diagnostic
 /// handlers that may be listening.
-void Function::emitWarning(const Twine &message) const {
+void Function::emitWarning(const Twine &message) {
   getContext()->emitDiagnostic(getLoc(), message,
                                MLIRContext::DiagnosticKind::Warning);
 }
@@ -138,13 +138,13 @@
 /// any diagnostic handlers that may be listening.  This function always
 /// returns true.  NOTE: This may terminate the containing application, only use
 /// when the IR is in an inconsistent state.
-bool Function::emitError(const Twine &message) const {
+bool Function::emitError(const Twine &message) {
   return getContext()->emitError(getLoc(), message);
 }
 
 /// Clone the internal blocks from this function into dest and all attributes
 /// from this function to dest.
-void Function::cloneInto(Function *dest, BlockAndValueMapping &mapper) const {
+void Function::cloneInto(Function *dest, BlockAndValueMapping &mapper) {
   // Add the attributes of this function to dest.
   llvm::MapVector<Identifier, Attribute> newAttrs;
   for (auto &attr : dest->getAttrs())
@@ -169,7 +169,7 @@
 /// provided (leaving them alone if no entry is present). Replaces references
 /// to cloned sub-values with the corresponding value that is copied, and adds
 /// those mappings to the mapper.
-Function *Function::clone(BlockAndValueMapping &mapper) const {
+Function *Function::clone(BlockAndValueMapping &mapper) {
   FunctionType newType = type;
 
   // If the function has a body, then the user might be deleting arguments to
@@ -196,7 +196,7 @@
   cloneInto(newFunc, mapper);
   return newFunc;
 }
-Function *Function::clone() const {
+Function *Function::clone() {
   BlockAndValueMapping mapper;
   return clone(mapper);
 }
diff --git a/lib/IR/MLIRContext.cpp b/lib/IR/MLIRContext.cpp
index 7ea7572..893090c 100644
--- a/lib/IR/MLIRContext.cpp
+++ b/lib/IR/MLIRContext.cpp
@@ -565,7 +565,7 @@
   using AttributeListSet =
       DenseSet<AttributeListStorage *, AttributeListKeyInfo>;
   AttributeListSet attributeLists;
-  DenseMap<const Function *, FunctionAttributeStorage *> functionAttrs;
+  DenseMap<Function *, FunctionAttributeStorage *> functionAttrs;
   DenseMap<std::pair<Type, Attribute>, SplatElementsAttributeStorage *>
       splatElementsAttrs;
   using DenseElementsAttrSet =
@@ -1160,7 +1160,7 @@
   });
 }
 
-FunctionAttr FunctionAttr::get(const Function *value, MLIRContext *context) {
+FunctionAttr FunctionAttr::get(Function *value, MLIRContext *context) {
   assert(value && "Cannot get FunctionAttr for a null function");
   auto &impl = context->getImpl();
 
diff --git a/lib/IR/Operation.cpp b/lib/IR/Operation.cpp
index 06895b5..011e1d2 100644
--- a/lib/IR/Operation.cpp
+++ b/lib/IR/Operation.cpp
@@ -264,7 +264,7 @@
 
 static bool verifyTerminatorSuccessors(const Instruction *op) {
   // Verify that the operands lines up with the BB arguments in the successor.
-  const Function *fn = op->getFunction();
+  Function *fn = op->getFunction();
   for (unsigned i = 0, e = op->getNumSuccessors(); i != e; ++i) {
     auto *succ = op->getSuccessor(i);
     if (succ->getFunction() != fn)
diff --git a/lib/IR/Value.cpp b/lib/IR/Value.cpp
index fd6957a..2b6eea8 100644
--- a/lib/IR/Value.cpp
+++ b/lib/IR/Value.cpp
@@ -29,7 +29,7 @@
 }
 
 /// Return the function that this Value is defined in.
-Function *Value::getFunction() {
+Function *Value::getFunction() const {
   switch (getKind()) {
   case Value::Kind::BlockArgument:
     return cast<BlockArgument>(this)->getFunction();
@@ -64,7 +64,7 @@
 //===----------------------------------------------------------------------===//
 
 /// Return the function that this argument is defined in.
-Function *BlockArgument::getFunction() {
+Function *BlockArgument::getFunction() const {
   if (auto *owner = getOwner())
     return owner->getFunction();
   return nullptr;
diff --git a/lib/LLVMIR/IR/LLVMDialect.cpp b/lib/LLVMIR/IR/LLVMDialect.cpp
index a08b99c..c70609e 100644
--- a/lib/LLVMIR/IR/LLVMDialect.cpp
+++ b/lib/LLVMIR/IR/LLVMDialect.cpp
@@ -93,8 +93,7 @@
 }
 
 /// Verify LLVMIR function argument attributes.
-bool LLVMDialect::verifyFunctionArgAttribute(const Function *func,
-                                             unsigned argIdx,
+bool LLVMDialect::verifyFunctionArgAttribute(Function *func, unsigned argIdx,
                                              NamedAttribute argAttr) {
   // Check that llvm.noalias is a boolean attribute.
   if (argAttr.first == "llvm.noalias" && !argAttr.second.isa<BoolAttr>())
diff --git a/lib/Pass/PassDetail.h b/lib/Pass/PassDetail.h
index b4c69a3..d387dc0 100644
--- a/lib/Pass/PassDetail.h
+++ b/lib/Pass/PassDetail.h
@@ -47,8 +47,8 @@
   FunctionPassExecutor(FunctionPassExecutor &&) = default;
 
   // TODO(riverriddle) Allow copying.
-  FunctionPassExecutor(const FunctionPassExecutor &) = delete;
-  FunctionPassExecutor &operator=(const FunctionPassExecutor &) = delete;
+  FunctionPassExecutor(FunctionPassExecutor &) = delete;
+  FunctionPassExecutor &operator=(FunctionPassExecutor &) = delete;
 
   /// Run the executor on the given function.
   LogicalResult run(Function *function, FunctionAnalysisManager &fam);
diff --git a/lib/Target/LLVMIR/ConvertToLLVMIR.cpp b/lib/Target/LLVMIR/ConvertToLLVMIR.cpp
index 9bd4fc1..f6bc644 100644
--- a/lib/Target/LLVMIR/ConvertToLLVMIR.cpp
+++ b/lib/Target/LLVMIR/ConvertToLLVMIR.cpp
@@ -56,8 +56,8 @@
   explicit ModuleTranslation(Module &module) : mlirModule(module) {}
 
   bool convertFunctions();
-  bool convertOneFunction(const Function &func);
-  void connectPHINodes(const Function &func);
+  bool convertOneFunction(Function &func);
+  void connectPHINodes(Function &func);
   bool convertBlock(const Block &bb, bool ignoreArguments);
   bool convertInstruction(const Instruction &inst, llvm::IRBuilder<> &builder);
 
@@ -72,7 +72,7 @@
   std::unique_ptr<llvm::Module> llvmModule;
 
   // Mappings between original and translated values, used for lookups.
-  llvm::DenseMap<const Function *, llvm::Function *> functionMapping;
+  llvm::DenseMap<Function *, llvm::Function *> functionMapping;
   llvm::DenseMap<const Value *, llvm::Value *> valueMapping;
   llvm::DenseMap<const Block *, llvm::BasicBlock *> blockMapping;
 };
@@ -316,7 +316,7 @@
              : terminator.getSuccessorOperand(1, index);
 }
 
-void ModuleTranslation::connectPHINodes(const Function &func) {
+void ModuleTranslation::connectPHINodes(Function &func) {
   // Skip the first block, it cannot be branched to and its arguments correspond
   // to the arguments of the LLVM function.
   for (auto it = std::next(func.begin()), eit = func.end(); it != eit; ++it) {
@@ -348,7 +348,7 @@
 }
 
 // Sort function blocks topologically.
-static llvm::SetVector<const Block *> topologicalSort(const Function &f) {
+static llvm::SetVector<const Block *> topologicalSort(Function &f) {
   // For each blocks that has not been visited yet (i.e. that has no
   // predecessors), add it to the list and traverse its successors in DFS
   // preorder.
@@ -362,7 +362,7 @@
   return blocks;
 }
 
-bool ModuleTranslation::convertOneFunction(const Function &func) {
+bool ModuleTranslation::convertOneFunction(Function &func) {
   // Clear the block and value mappings, they are only relevant within one
   // function.
   blockMapping.clear();
@@ -416,8 +416,8 @@
 bool ModuleTranslation::convertFunctions() {
   // Declare all functions first because there may be function calls that form a
   // call graph with cycles.
-  for (const Function &function : mlirModule) {
-    const Function *functionPtr = &function;
+  for (Function &function : mlirModule) {
+    Function *functionPtr = &function;
     llvm::FunctionType *functionType = convertFunctionType(
         llvmModule->getContext(), function.getType(), function.getLoc());
     if (!functionType)
@@ -430,7 +430,7 @@
   }
 
   // Convert functions.
-  for (const Function &function : mlirModule) {
+  for (Function &function : mlirModule) {
     // Ignore external functions.
     if (function.isExternal())
       continue;
diff --git a/lib/Transforms/ViewFunctionGraph.cpp b/lib/Transforms/ViewFunctionGraph.cpp
index d77e96a..f4e8e44 100644
--- a/lib/Transforms/ViewFunctionGraph.cpp
+++ b/lib/Transforms/ViewFunctionGraph.cpp
@@ -25,15 +25,14 @@
 
 // Specialize DOTGraphTraits to produce more readable output.
 template <>
-struct llvm::DOTGraphTraits<const Function *> : public DefaultDOTGraphTraits {
+struct llvm::DOTGraphTraits<Function *> : public DefaultDOTGraphTraits {
   using DefaultDOTGraphTraits::DefaultDOTGraphTraits;
 
-  static std::string getNodeLabel(const Block *Block, const Function *);
+  static std::string getNodeLabel(const Block *Block, Function *);
 };
 
-std::string
-llvm::DOTGraphTraits<const Function *>::getNodeLabel(const Block *Block,
-                                                     const Function *) {
+std::string llvm::DOTGraphTraits<Function *>::getNodeLabel(const Block *Block,
+                                                           Function *) {
   // Reuse the print output for the node labels.
   std::string outStreamStr;
   raw_string_ostream os(outStreamStr);
@@ -56,19 +55,18 @@
 
 } // end namespace llvm
 
-void mlir::viewGraph(const Function &function, const llvm::Twine &name,
+void mlir::viewGraph(Function &function, const llvm::Twine &name,
                      bool shortNames, const llvm::Twine &title,
                      llvm::GraphProgram::Name program) {
   llvm::ViewGraph(&function, name, shortNames, title, program);
 }
 
-llvm::raw_ostream &mlir::writeGraph(llvm::raw_ostream &os,
-                                    const Function *function, bool shortNames,
-                                    const llvm::Twine &title) {
+llvm::raw_ostream &mlir::writeGraph(llvm::raw_ostream &os, Function *function,
+                                    bool shortNames, const llvm::Twine &title) {
   return llvm::WriteGraph(os, function, shortNames, title);
 }
 
-void mlir::Function::viewGraph() const {
+void mlir::Function::viewGraph() {
   ::mlir::viewGraph(*this, llvm::Twine("cfgfunc ") + getName().str());
 }