Add glslc support for -O.
diff --git a/glslc/README.asciidoc b/glslc/README.asciidoc
index 9709227..1922ed8 100644
--- a/glslc/README.asciidoc
+++ b/glslc/README.asciidoc
@@ -11,14 +11,16 @@
 
 ----
 glslc [-c|-S|-E]
-      [-Dmacroname[=value]...]
-      [-Idirectory...]
-      [-std=standard] [-x glsl]
+      [-x glsl] [-std=standard]
       [-fshader-stage=...]
       [--target-env=...]
       [-g]
+      [-O0|-Os]
+      [-Idirectory...]
+      [-Dmacroname[=value]...]
       [-w] [-Werror]
-      [-o outfile] shader...
+      [-o outfile]
+      shader...
 ----
 
 == Description
@@ -238,7 +240,7 @@
 
 ==== `-I`
 
-`-Idirectory' or `-I directory` adds the specified directory to the search path
+`-Idirectory` or `-I directory` adds the specified directory to the search path
 for include files.  The directory may be an absolute path or a relative path to
 the current working directory.
 
@@ -249,9 +251,29 @@
 Requests that the compiler place source-level debug information into the object
 code, such as identifier names and line numbers.
 
+This option restrains `-O` from turning on the strip-debug-info optimization
+pass.
+
 NOTE: Currently this option has no effect.  Full functionality depends on
 glslang support for generating debug info.
 
+==== `-O0`, `-Os`
+
+`-O` specifies which optimization level to use:
+
+* `-O0` means "no optimization". This level compiles the fastest and generates
+  the most debuggable code.
+* `-Os` enables optimizations to reduce code size. This level runs the
+  following optimization passes one by one:
+  - strip-debug-info: removes all debug instructions. (This pass will be turned
+    off if `-g` is specified.)
+  - unify-constant: unifies constants of identical type and bit pattern.
+
+For detailed explanation and implementation status of the passes mentioned
+in the above, please refer to the
+https://github.com/KhronosGroup/SPIRV-Tools/blob/master/include/spirv-tools/optimizer.hpp[SPIRV-Tools] project.
+
+
 ==== `-mfmt=<format>`
 
 `-mfmt=<format>` selects output format for compilation output in SPIR-V binary
diff --git a/glslc/src/main.cc b/glslc/src/main.cc
index 900b8f2..782e3ce 100644
--- a/glslc/src/main.cc
+++ b/glslc/src/main.cc
@@ -297,6 +297,19 @@
       }
     } else if (arg == "-g") {
       compiler.options().SetGenerateDebugInfo();
+    } else if (arg.starts_with("-O")) {
+      if (arg == "-Os") {
+        compiler.options().SetOptimizationLevel(
+            shaderc_optimization_level_size);
+      } else if (arg == "-O0") {
+        compiler.options().SetOptimizationLevel(
+            shaderc_optimization_level_zero);
+      } else {
+        std::cerr << "glslc: error: invalid value '"
+                  << arg.substr(std::strlen("-O")) << "' in '" << arg << "'"
+                  << std::endl;
+        return 1;
+      }
     } else if (arg == "-w") {
       compiler.options().SetSuppressWarnings();
     } else if (arg == "-Werror") {
diff --git a/glslc/test/option_dash_cap_O.py b/glslc/test/option_dash_cap_O.py
new file mode 100644
index 0000000..8a7f234
--- /dev/null
+++ b/glslc/test/option_dash_cap_O.py
@@ -0,0 +1,118 @@
+# Copyright 2016 The Shaderc Authors. All rights reserved.
+#
+# 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
+#
+#     http://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 expect
+from environment import File, Directory
+from glslc_test_framework import inside_glslc_testsuite
+from placeholder import FileShader
+
+MINIMAL_SHADER = '#version 310 es\nvoid main() {}'
+EMPTY_SHADER_IN_CWD = Directory('.', [File('shader.vert', MINIMAL_SHADER)])
+
+ASSEMBLY_WITH_DEBUG = [
+    '; SPIR-V\n',
+    '; Version: 1.0\n',
+    '; Generator: Khronos Glslang Reference Front End; 1\n',
+    '; Bound: 6\n',
+    '; Schema: 0\n',
+    '               OpCapability Shader\n',
+    '          %1 = OpExtInstImport "GLSL.std.450"\n',
+    '               OpMemoryModel Logical GLSL450\n',
+    '               OpEntryPoint Vertex %main "main"\n',
+    '               OpSource ESSL 310\n',
+    '               OpSourceExtension "GL_GOOGLE_cpp_style_line_directive"\n',
+    '               OpSourceExtension "GL_GOOGLE_include_directive"\n',
+    '               OpName %main "main"\n',
+    '       %void = OpTypeVoid\n',
+    '          %3 = OpTypeFunction %void\n',
+    '       %main = OpFunction %void None %3\n',
+    '          %5 = OpLabel\n',
+    '               OpReturn\n',
+    '               OpFunctionEnd\n']
+
+ASSEMBLY_WITHOUT_DEBUG = [
+    '; SPIR-V\n',
+    '; Version: 1.0\n',
+    '; Generator: Khronos Glslang Reference Front End; 1\n',
+    '; Bound: 6\n',
+    '; Schema: 0\n',
+    '               OpCapability Shader\n',
+    '          %1 = OpExtInstImport "GLSL.std.450"\n',
+    '               OpMemoryModel Logical GLSL450\n',
+    '               OpEntryPoint Vertex %4 "main"\n',
+    '       %void = OpTypeVoid\n',
+    '          %3 = OpTypeFunction %void\n',
+    '          %4 = OpFunction %void None %3\n',  # %4 vs. %main
+    '          %5 = OpLabel\n',
+    '               OpReturn\n',
+    '               OpFunctionEnd\n']
+
+
+@inside_glslc_testsuite('OptionDashCapO')
+class TestDashCapO0(expect.ValidFileContents):
+    """Tests that -O0 works."""
+
+    environment = EMPTY_SHADER_IN_CWD
+    glslc_args = ['-S', '-O0', 'shader.vert']
+    target_filename = 'shader.vert.spvasm'
+    expected_file_contents = ASSEMBLY_WITH_DEBUG
+
+
+@inside_glslc_testsuite('OptionDashCapO')
+class TestDashCapOs(expect.ValidFileContents):
+    """Tests that -Os works."""
+
+    environment = EMPTY_SHADER_IN_CWD
+    glslc_args = ['-S', '-Os', 'shader.vert']
+    target_filename = 'shader.vert.spvasm'
+    expected_file_contents = ASSEMBLY_WITHOUT_DEBUG
+
+
+@inside_glslc_testsuite('OptionDashCapO')
+class TestDashCapOOverriding(expect.ValidFileContents):
+    """Tests that if there are multiple -O's, only the last one takes effect."""
+
+    environment = EMPTY_SHADER_IN_CWD
+    glslc_args = ['-S', '-Os', '-O0', '-Os', '-O0', 'shader.vert']
+    target_filename = 'shader.vert.spvasm'
+    expected_file_contents = ASSEMBLY_WITH_DEBUG
+
+
+@inside_glslc_testsuite('OptionDashCapO')
+class TestDashCapOWithDashG(expect.ValidFileContents):
+    """Tests that -g restrains -O from turning on strip debug info."""
+
+    environment = EMPTY_SHADER_IN_CWD
+    glslc_args = ['-S', '-Os', '-g', 'shader.vert']
+    target_filename = 'shader.vert.spvasm'
+    expected_file_contents = ASSEMBLY_WITH_DEBUG
+
+
+@inside_glslc_testsuite('OptionDashCapO')
+class TestDashGWithDashCapO(expect.ValidFileContents):
+    """Tests that -g restrains -O from turning on strip debug info."""
+
+    environment = EMPTY_SHADER_IN_CWD
+    glslc_args = ['-S', '-g', '-Os', 'shader.vert']
+    target_filename = 'shader.vert.spvasm'
+    expected_file_contents = ASSEMBLY_WITH_DEBUG
+
+
+@inside_glslc_testsuite('OptionDashCapO')
+class TestWrongOptLevel(expect.NoGeneratedFiles, expect.ErrorMessage):
+    """Tests erroring out with wrong optimization level."""
+
+    shader = FileShader(MINIMAL_SHADER, '.vert')
+    glslc_args = ['-c', '-O2', shader]
+    expected_error = "glslc: error: invalid value '2' in '-O2'\n"