Adding constant table declaration to CPU executable libraries.
diff --git a/iree/compiler/Dialect/HAL/Target/LLVM/LibraryBuilder.cpp b/iree/compiler/Dialect/HAL/Target/LLVM/LibraryBuilder.cpp
index f92986a..661254c 100644
--- a/iree/compiler/Dialect/HAL/Target/LLVM/LibraryBuilder.cpp
+++ b/iree/compiler/Dialect/HAL/Target/LLVM/LibraryBuilder.cpp
@@ -163,6 +163,25 @@
   return type;
 }
 
+// %struct.iree_hal_executable_constant_table_v0_t = type {
+//   i32
+// }
+static llvm::StructType *makeConstantTableType(llvm::LLVMContext &context) {
+  if (auto *existingType = llvm::StructType::getTypeByName(
+          context, "iree_hal_executable_constant_table_v0_t")) {
+    return existingType;
+  }
+  auto *i32Type = llvm::IntegerType::getInt32Ty(context);
+  auto *type =
+      llvm::StructType::create(context,
+                               {
+                                   i32Type,
+                               },
+                               "iree_hal_executable_constant_table_v0_t",
+                               /*isPacked=*/false);
+  return type;
+}
+
 // %struct.iree_hal_executable_library_header_t = type {
 //   i32,
 //   i8*,
@@ -201,11 +220,13 @@
   }
   auto *importTableType = makeImportTableType(context);
   auto *exportTableType = makeExportTableType(context);
+  auto *constantTableType = makeConstantTableType(context);
   auto *type = llvm::StructType::create(context,
                                         {
                                             libraryHeaderType->getPointerTo(),
                                             importTableType,
                                             exportTableType,
+                                            constantTableType,
                                         },
                                         "iree_hal_executable_library_v0_t",
                                         /*isPacked=*/false);
@@ -430,6 +451,19 @@
                        });
 }
 
+llvm::Constant *LibraryBuilder::buildLibraryV0ConstantTable(
+    std::string libraryName) {
+  auto &context = module->getContext();
+  auto *constantTableType = makeConstantTableType(context);
+  auto *i32Type = llvm::IntegerType::getInt32Ty(context);
+
+  return llvm::ConstantStruct::get(
+      constantTableType, {
+                             // count=
+                             llvm::ConstantInt::get(i32Type, constantCount),
+                         });
+}
+
 llvm::Constant *LibraryBuilder::buildLibraryV0(std::string libraryName) {
   auto &context = module->getContext();
   auto *libraryHeaderType = makeLibraryHeaderType(context);
@@ -471,6 +505,8 @@
                                     buildLibraryV0ImportTable(libraryName),
                                     // exports=
                                     buildLibraryV0ExportTable(libraryName),
+                                    // constants=
+                                    buildLibraryV0ConstantTable(libraryName),
                                 }),
       /*Name=*/libraryName);
   // TODO(benvanik): force alignment (8? natural pointer width?)
diff --git a/iree/compiler/Dialect/HAL/Target/LLVM/LibraryBuilder.h b/iree/compiler/Dialect/HAL/Target/LLVM/LibraryBuilder.h
index c49da0e..2a742f3 100644
--- a/iree/compiler/Dialect/HAL/Target/LLVM/LibraryBuilder.h
+++ b/iree/compiler/Dialect/HAL/Target/LLVM/LibraryBuilder.h
@@ -111,6 +111,8 @@
     exports.push_back({name.str(), tag.str(), attrs, func});
   }
 
+  // TODO(benvanik): addConstant for registering constant values.
+
   // Builds a `iree_hal_executable_library_query_fn_t` with the given
   // |queryFuncName| that will return the current library metadata.
   //
@@ -126,6 +128,7 @@
   llvm::Constant *buildLibraryV0(std::string libraryName);
   llvm::Constant *buildLibraryV0ImportTable(std::string libraryName);
   llvm::Constant *buildLibraryV0ExportTable(std::string libraryName);
+  llvm::Constant *buildLibraryV0ConstantTable(std::string libraryName);
 
   llvm::Module *module = nullptr;
   Mode mode = Mode::INCLUDE_REFLECTION_ATTRS;
@@ -146,6 +149,8 @@
     llvm::Function *func;
   };
   SmallVector<Dispatch> exports;
+
+  size_t constantCount = 0;
 };
 
 }  // namespace HAL
diff --git a/iree/hal/local/executable_library.h b/iree/hal/local/executable_library.h
index bc82857..edfc005 100644
--- a/iree/hal/local/executable_library.h
+++ b/iree/hal/local/executable_library.h
@@ -363,6 +363,14 @@
   const char* const* tags;
 } iree_hal_executable_export_table_v0_t;
 
+// A table declaring the executable-level constants that can be used to
+// specialize the executable behavior.
+typedef struct iree_hal_executable_constant_table_v0_t {
+  // Total number of constants in the table.
+  uint32_t count;
+  // We could add more metadata here if we wanted to enable reflection.
+} iree_hal_executable_constant_table_v0_t;
+
 // Structure used for v0 library interfaces.
 // The entire structure is designed to be read-only and able to live embedded in
 // the binary .rdata section.
@@ -383,6 +391,9 @@
 
   // Table of exported functions from the executable.
   iree_hal_executable_export_table_v0_t exports;
+
+  // Table of executable-level constants.
+  iree_hal_executable_constant_table_v0_t constants;
 } iree_hal_executable_library_v0_t;
 
 #endif  // IREE_HAL_LOCAL_EXECUTABLE_LIBRARY_H_