Fix windows iree+tensorflow build and verify tests.

* Switches us to MSVC for the supported windows compiler.
* Uses a couple of magic flags that keep the TF kernels from taking a lot of time to compile and inlining the world to bloat the binary size.
* The whole shebang builds for me now in a few minutes and produces a ~76MB compiler binary. While large, this is manageable for now.
* We still have a fragile relationship with which TF kernels are compiled in and what we can subsequently handle (relying on constant folding to paper over op support issues). We'll need to triage these one by one.
* There are a couple of bugs that seem MSVC/Windows specific -- will need to track down.

Closes https://github.com/google/iree/pull/2035

COPYBARA_INTEGRATE_REVIEW=https://github.com/google/iree/pull/2035 from stellaraccident:winfix2 e0d823367c968e1c08f1a18155cf4eb26cae069f
PiperOrigin-RevId: 313693187
diff --git a/.bazelrc b/.bazelrc
index be9debd..3487c50 100644
--- a/.bazelrc
+++ b/.bazelrc
@@ -12,38 +12,51 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-# Disable warnings we don't care about.
-build --copt=-Wno-unused-local-typedef
-build --copt=-Wno-unused-private-field
-build --copt=-Wno-unused-const-variable
-# Matches upstream. Cannot impact due to extern C inclusion method.
-build --copt=-Wno-extern-c-compat
-# Technically UB but needed for intrusive ptrs
-build --copt=-Wno-invalid-offsetof
-build --copt=-Wno-unused-function
-
-# C++14 standard version is required.
-build --cxxopt=-std=c++14 --host_cxxopt=-std=c++14
-
-# Default to an optimized build with asserts.
-# This is a good compromise between runtime and debugability.
-# Override via: "-c dbg" or --compilation_mode=dbg
-build --compilation_mode=opt
-build --copt=-UNDEBUG
-
+###############################################################################
+# Common flags that apply to all configurations.
+# Use sparingly for things common to all compilers and platforms.
+###############################################################################
+# Prevent invalid caching if input files are modified during a build.
+build --experimental_guard_against_concurrent_changes
 # Disable visibility checks (works around some private deps in TensorFlow that
 # are being unbundled soon anyway).
 build --nocheck_visibility
+# Override via: "-c dbg" or --compilation_mode=dbg
+build --compilation_mode=opt
+# Used in TensorFlow, so we have to enable it here as well.
+common --experimental_repo_remote_exec
+# Actually printing output on errors is... a useful default
+test --test_output=errors
+
+###############################################################################
+# Options for "generic_clang" builds: these options should generally apply to 
+# either clang or gcc and are curated based on need.
+###############################################################################
+
+# Disable warnings we don't care about.
+build:generic_clang --copt=-Wno-unused-local-typedef
+build:generic_clang --copt=-Wno-unused-private-field
+build:generic_clang --copt=-Wno-unused-const-variable
+# Matches upstream. Cannot impact due to extern C inclusion method.
+build:generic_clang --copt=-Wno-extern-c-compat
+# Technically UB but needed for intrusive ptrs
+build:generic_clang --copt=-Wno-invalid-offsetof
+build:generic_clang --copt=-Wno-unused-function
+
+# C++14 standard version is required.
+build:generic_clang --cxxopt=-std=c++14 --host_cxxopt=-std=c++14
+
+# Default to an optimized build with asserts.
+# This is a good compromise between runtime and debugability.
+build:generic_clang --copt=-UNDEBUG
+
+###############################################################################
+# Architecture specific options
+###############################################################################
 
 # Enable some default cpu flags for x86 optimization.
 build:x86opt --copt=-mavx2
 
-###############################################################################
-
-# Not strictly required, but generally good flags.
-
-# Prevent invalid caching if input files are modified during a build.
-build --experimental_guard_against_concurrent_changes
 
 ###############################################################################
 
@@ -118,37 +131,26 @@
 build:rs --project_id=iree-oss
 
 ###############################################################################
+# Windows specific flags for building with VC.
+###############################################################################
 
-# Experimental config for building on Windows via clang-cl.
-# As an aspiration, it may eventually not be required to manually
-# activate this config, but for now, it is a place to store the
-# set of flags and tweaks needed to get the Windows build working.
-# Note that this is intended to work with clang-cl, not the Visual
-# Studio compiler. The following must be performed prior to invoking
-# Bazel:
-#   * Install Visual Studio Build Tools
-#   * export USE_CLANG_CL=1
-#   * export BAZEL_LLVM=C:/Users/$USER/scoop/apps/llvm/current
-#     (or actual LLVM install location)
-# Then one can build with:
-#   bazel build --config=windows {targets...}
+build:windows --define=iree_is_msvc=true
+build:windows --copt=/wd4624 # destructor was implicitly defined as deleted
+build:windows --copt=/wd4244 # possible loss of data
+build:windows --copt=/wd4005 # macro redefinition
+build:windows --copt=/wd4267 # initializing: possible loss of data
+build:windows --copt=/wd4141 # inline used more than once
+build:windows --per_file_copt=mkl_dnn@/wd4551 # missing argument list
+build:windows --per_file_copt=mkl_dnn@/wd4068 # unknown pragma
+build:windows --per_file_copt=farmhash@/wd4319 # zero extending to T of greater size
 
-# Works around __TIME__ __DATE__, etc redefinitions and -std=c++14
-# warnings.
-build:windows --copt=-Wno-builtin-macro-redefined --host_copt=-Wno-builtin-macro-redefined
-build:windows --copt=-Wno-unknown-argument --host_copt=-Wno-unknown-argument
-
-# Avoid warnings for WIN32_LEAN_AND_MEAN being defined multiple times.
-build:windows --copt=-Wno-macro-redefined
+build:windows --linkopt=/IGNORE:4217 # mismatch import/export declspec
 
 # Enables unix-style runfiles link trees (requires symlink permission).
 # See: https://blogs.windows.com/windowsdeveloper/2016/12/02/symlinks-windows-10/
 # Generally: Enable Developer Mode in the Developer Settings page of the
 # system settings.
 build:windows --experimental_enable_runfiles
-
-###############################################################################
-
 # Flags to make tensorflow build.
 # Some of these are also of general use and fine to enable globally for windows.
 build:windows --copt=/arch:AVX
@@ -159,24 +161,14 @@
 # That is one way to have less warnings :(
 build:windows --per_file_copt=tensorflow@-w
 build:windows --per_file_copt=protobuf@-w
-# This is used a lot and shouldn't be an error.
-build:windows --per_file_copt=tensorflow@-Wno-microsoft-unqualified-friend
-build:windows --per_file_copt=protobuf@-Wno-microsoft-unqualified-friend
 # Why are min/max macros? No one knows.
 build:windows --copt=/DNOMINMAX --host_copt=/DNOMINMAX
 # Yay for security warnings. Boo for non-standard.
 build:windows --copt=/D_CRT_SECURE_NO_WARNINGS --host_copt=/D_CRT_SECURE_NO_WARNINGS
 # TensorFlow requires the "monolithic" build mode for now on Windows.
 build:windows --define framework_shared_object=false
-# TODO(laurenzo): Clang uses runtime functions for 128bit math that require the
-# rt library and there is not a convenient way to link it. Figure out how to
-# do the following:
-# See: http://clang-developers.42468.n3.nabble.com/Issue-with-Clang-on-Windows-and-compiler-rt-builtins-td4059230.html
-build:windows --linkopt=/DEFAULTLIB:clang_rt.builtins-x86_64.lib
-build:windows --linkopt=/DEFAULTLIB:ws2_32.lib
 # Necessary for M_* math constants.
-build:windows --copt=/D_USE_MATH_DEFINES
-build:windows --host_copt=/D_USE_MATH_DEFINES
+build:windows --copt=/D_USE_MATH_DEFINES --host_copt=/D_USE_MATH_DEFINES
 
 # Workaround WinGDI.h defining `ERROR`, which conflicts with logging macros.
 # Note that IREE and TensorFlow both `#undef ERROR` and define their own
@@ -184,11 +176,17 @@
 # "graphics device interface" (GDI) for certain GUI sample projects.
 build:windows --per_file_copt=tensorflow@-DNOGDI
 
-# Used in TensorFlow, so we have to enable it here as well.
-common --experimental_repo_remote_exec
+# Disables TensorFlow eigen bloat and reduces compile times.
+build:windows --define=override_eigen_strong_inline=true
+
+# Another TensorFlow flag from their config script.
+build:windows --define with_default_optimizations=true
 
 ###############################################################################
 
+# Run the configure_bazel.py script to generate.
+try-import %workspace%/configured.bazelrc
+
 # The user.bazelrc file is not checked in but available for local mods.
 # Always keep this at the end of the file so that user flags override.
 try-import %workspace%/user.bazelrc
diff --git a/.github/workflows/bazel_build_bindings.yml b/.github/workflows/bazel_build_bindings.yml
index 2bc1d37..cfadbe2 100644
--- a/.github/workflows/bazel_build_bindings.yml
+++ b/.github/workflows/bazel_build_bindings.yml
@@ -52,6 +52,7 @@
           # excluded with "noga".
           bazel query '//bindings/...' \
             | xargs bazel test \
+              --config=generic_clang \            
               --build_tag_filters="-noga" \
               --test_tag_filters="-noga,-driver=vulkan" \
               --test_env=IREE_VULKAN_DISABLE=1 \
diff --git a/.github/workflows/bazel_build_core.yml b/.github/workflows/bazel_build_core.yml
index 31e08db..9fdbf3d 100644
--- a/.github/workflows/bazel_build_core.yml
+++ b/.github/workflows/bazel_build_core.yml
@@ -52,6 +52,7 @@
           # excluded with "noga".
           bazel query '//iree/...' \
             | xargs bazel test \
+              --config=generic_clang \
               --build_tag_filters="-noga" \
               --test_tag_filters="-noga,-driver=vulkan" \
               --test_env=IREE_VULKAN_DISABLE=1 \
diff --git a/.github/workflows/bazel_build_fallthrough.yml b/.github/workflows/bazel_build_fallthrough.yml
index 1d807ac..a3f4e85 100644
--- a/.github/workflows/bazel_build_fallthrough.yml
+++ b/.github/workflows/bazel_build_fallthrough.yml
@@ -52,6 +52,7 @@
           # excluded with "noga".
           bazel query '//... -//iree/... -//bindings/... -//integrations/...' \
             | xargs bazel test \
+              --config=generic_clang \            
               --build_tag_filters="-noga" \
               --test_tag_filters="-noga,-driver=vulkan" \
               --test_env=IREE_VULKAN_DISABLE=1 \
diff --git a/.github/workflows/bazel_build_integrations.yml b/.github/workflows/bazel_build_integrations.yml
index 459ec71..9a7c3e0 100644
--- a/.github/workflows/bazel_build_integrations.yml
+++ b/.github/workflows/bazel_build_integrations.yml
@@ -52,6 +52,7 @@
           # excluded with "noga".
           bazel query '//integrations/...' \
             | xargs bazel test \
+              --config=generic_clang \            
               --build_tag_filters="-noga" \
               --test_tag_filters="-noga,-driver=vulkan" \
               --test_env=IREE_VULKAN_DISABLE=1 \
diff --git a/.gitignore b/.gitignore
index b6979f8..cb9d239 100644
--- a/.gitignore
+++ b/.gitignore
@@ -22,6 +22,7 @@
 /bazel-*
 
 # Local-only config options
+configured.bazelrc
 user.bazelrc
 
 # Dear ImGui Ini files
diff --git a/build_tools/bazel/build.sh b/build_tools/bazel/build.sh
index 0d68e6f..df68412 100755
--- a/build_tools/bazel/build.sh
+++ b/build_tools/bazel/build.sh
@@ -68,6 +68,7 @@
 # want them built by CI unless they are excluded with "nokokoro".
 bazel query //iree/... + //bindings/... | \
   xargs bazel test ${test_env_args[@]} \
+    --config=generic_clang \
     --build_tag_filters="${BUILD_TAG_FILTERS?}" \
     --test_tag_filters="${TEST_TAG_FILTERS?}" \
     --keep_going \
diff --git a/configure_bazel.py b/configure_bazel.py
new file mode 100644
index 0000000..34d0f6a
--- /dev/null
+++ b/configure_bazel.py
@@ -0,0 +1,66 @@
+# Copyright 2020 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import platform
+import os
+import subprocess
+import sys
+
+
+def normalize_path(p):
+  if platform.system() == "Windows":
+    # Sure. Good idea, bazel.
+    return p.replace("\\", "/")
+
+
+def write_platform(bazelrc):
+  platform_config = "generic_clang"
+  if platform.system() == "Windows":
+    platform_config = "windows"
+  print("build --config={}".format(platform_config), file=bazelrc)
+
+
+def write_python_bin(bazelrc):
+  python_bin = normalize_path(sys.executable)
+  print("build --python_path=\"{}\"".format(python_bin), file=bazelrc)
+  # IREE extension compilation requires PYTHON_BIN
+  print("build --action_env PYTHON_BIN=\"{}\"".format(python_bin), file=bazelrc)
+  # TensorFlow defines this one. No idea why.
+  print(
+      "build --action_env PYTHON_BIN_PATH=\"{}\"".format(python_bin),
+      file=bazelrc)
+
+
+def write_python_path(bazelrc):
+  # For some reason, bazel doesn't always find the user site path, which
+  # is typically where "pip install --user" libraries end up. Inject it.
+  try:
+    user_site = subprocess.check_output(
+        [sys.executable, "-m", "site", "--user-site"]).decode("utf-8").strip()
+    print("Found user site directory:", user_site)
+  except OSError:
+    print("Could not resolve user site directory")
+    return
+  print(
+      "build --action_env PYTHONPATH=\"{}\"".format(normalize_path(user_site)),
+      file=bazelrc)
+
+
+local_bazelrc = os.path.join(os.path.dirname(__file__), "configured.bazelrc")
+with open(local_bazelrc, "wt") as bazelrc:
+  write_platform(bazelrc)
+  write_python_bin(bazelrc)
+  write_python_path(bazelrc)
+
+print("Wrote", local_bazelrc)
diff --git a/docs/GetStarted/getting_started_linux_bazel.md b/docs/GetStarted/getting_started_linux_bazel.md
index 2e42b3a..9ab3688 100644
--- a/docs/GetStarted/getting_started_linux_bazel.md
+++ b/docs/GetStarted/getting_started_linux_bazel.md
@@ -42,12 +42,13 @@
 
 ### Clone
 
-Clone the repository and initialize its submodules:
+Clone the repository, initialize its submodules and configure:
 
 ```shell
 $ git clone https://github.com/google/iree.git
 $ cd iree
-$ git submodule update --init
+$ git submodule update --initss
+$ python3 configure_bazel.py
 ```
 
 > Tip:<br>
diff --git a/docs/GetStarted/getting_started_windows_bazel.md b/docs/GetStarted/getting_started_windows_bazel.md
index 7454c2c..c90223a 100644
--- a/docs/GetStarted/getting_started_windows_bazel.md
+++ b/docs/GetStarted/getting_started_windows_bazel.md
@@ -35,10 +35,6 @@
 Instructions for installation can be found
 [here](https://www.python.org/downloads/windows/).
 
-### Install Clang
-
-Install Clang for `clang-cl.exe` from https://releases.llvm.org/download.html.
-
 ### Install Build Tools For Visual Studio
 
 Install the full Visual Studio or "Build Tools For Visual Studio" from the
@@ -52,7 +48,6 @@
 
 ```powershell
 > $env:BAZEL_VS = "C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools"
-> $env:USE_CLANG_CL = 1
 ```
 
 ## Clone and Build
@@ -60,12 +55,13 @@
 ### Clone
 
 Using your shell of choice (such as PowerShell or [cmder](https://cmder.net/)),
-clone the repository and initialize its submodules:
+clone the repository, initialize its submodules, and configure:
 
 ```powershell
 > git clone https://github.com/google/iree.git
 > cd iree
 > git submodule update --init
+> python configure_bazel.py
 ```
 
 > Tip:<br>
@@ -77,7 +73,7 @@
 Run all core tests:
 
 ```powershell
-> bazel test -k --config=windows iree/...
+> bazel test -k iree/...
 ```
 
 In general, build artifacts will be under the `bazel-bin` directory at the top
@@ -89,7 +85,6 @@
 by git. The recommended contents for Windows are:
 
 ```
-build --config=windows
 build --disk_cache=c:/bazelcache
 build:debug --compilation_mode=dbg --copt=/O2 --per_file_copt=iree@/Od --strip=never
 ```
diff --git a/integrations/tensorflow/bindings/python/pyiree/tf/compiler/BUILD b/integrations/tensorflow/bindings/python/pyiree/tf/compiler/BUILD
index dbcf019..32f70c4 100644
--- a/integrations/tensorflow/bindings/python/pyiree/tf/compiler/BUILD
+++ b/integrations/tensorflow/bindings/python/pyiree/tf/compiler/BUILD
@@ -54,6 +54,7 @@
     ":disable_kernels": [],
     "//conditions:default": [
         "@org_tensorflow//tensorflow/core/kernels:array",
+        "@org_tensorflow//tensorflow/core/kernels:math",
     ],
 })
 
diff --git a/iree/BUILD.bazel b/iree/BUILD.bazel
index 27bd3ec..27141b6 100644
--- a/iree/BUILD.bazel
+++ b/iree/BUILD.bazel
@@ -52,3 +52,14 @@
         "iree_tensorflow": "true",
     },
 )
+
+# Note that the "proper" way to do this is via a query on @bazel_tools,
+# but as with so many things bazel, it doesn't work reliably across versions,
+# variants, etc. So we just define our own since we also own the config
+# setting that activates it.
+config_setting(
+    name = "iree_is_msvc",
+    define_values = {
+        "iree_is_msvc": "true",
+    },
+)
diff --git a/iree/hal/vulkan/BUILD b/iree/hal/vulkan/BUILD
index eec5b00..e315236 100644
--- a/iree/hal/vulkan/BUILD
+++ b/iree/hal/vulkan/BUILD
@@ -351,8 +351,12 @@
     copts = [
         # Only needed in the implementation cc and not by external users.
         "-DVMA_STATIC_VULKAN_FUNCTIONS=0",
-        "-Wno-thread-safety-attributes",  # External code.
-    ],
+    ] + select({
+        "//iree:iree_is_msvc": [],
+        "//conditions:default": [
+            "-Wno-thread-safety-attributes",  # External code.
+        ],
+    }),
     deps = [
         ":dynamic_symbols",
         ":handle_util",