Move the ir namespace to opt. (#1680)

This CL moves the files in opt/ to consistenly be under the opt::
namespace. This frees up the ir:: namespace so it can be used to make a
shared ir represenation.
diff --git a/source/link/linker.cpp b/source/link/linker.cpp
index 15393ba..16b43a2 100644
--- a/source/link/linker.cpp
+++ b/source/link/linker.cpp
@@ -37,10 +37,10 @@
 
 namespace spvtools {
 
-using ir::Instruction;
-using ir::IRContext;
-using ir::Module;
-using ir::Operand;
+using opt::IRContext;
+using opt::Instruction;
+using opt::Module;
+using opt::Operand;
 using opt::PassManager;
 using opt::RemoveDuplicatesPass;
 using opt::analysis::DecorationManager;
@@ -73,7 +73,7 @@
 // not be empty either. Furthermore |modules| should not contain any null
 // pointers.
 static spv_result_t ShiftIdsInModules(const MessageConsumer& consumer,
-                                      std::vector<ir::Module*>* modules,
+                                      std::vector<opt::Module*>* modules,
                                       uint32_t* max_id_bound);
 
 // Generates the header for the linked module and returns it in |header|.
@@ -85,9 +85,9 @@
 //                     SPIR-V? For now, use the max of all versions found in
 //                     the input modules.
 static spv_result_t GenerateHeader(const MessageConsumer& consumer,
-                                   const std::vector<ir::Module*>& modules,
+                                   const std::vector<opt::Module*>& modules,
                                    uint32_t max_id_bound,
-                                   ir::ModuleHeader* header);
+                                   opt::ModuleHeader* header);
 
 // Merge all the modules from |in_modules| into a single module owned by
 // |linked_context|.
@@ -108,7 +108,7 @@
 // TODO(pierremoreau): What should be the proper behaviour with built-in
 //                     symbols?
 static spv_result_t GetImportExportPairs(
-    const MessageConsumer& consumer, const ir::IRContext& linked_context,
+    const MessageConsumer& consumer, const opt::IRContext& linked_context,
     const DefUseManager& def_use_manager,
     const DecorationManager& decoration_manager, bool allow_partial_linkage,
     LinkageTable* linkings_to_do);
@@ -120,7 +120,7 @@
 // checked.
 static spv_result_t CheckImportExportCompatibility(
     const MessageConsumer& consumer, const LinkageTable& linkings_to_do,
-    ir::IRContext* context);
+    opt::IRContext* context);
 
 // Remove linkage specific instructions, such as prototypes of imported
 // functions, declarations of imported variables, import (and export if
@@ -137,12 +137,12 @@
 static spv_result_t RemoveLinkageSpecificInstructions(
     const MessageConsumer& consumer, const LinkerOptions& options,
     const LinkageTable& linkings_to_do, DecorationManager* decoration_manager,
-    ir::IRContext* linked_context);
+    opt::IRContext* linked_context);
 
 // Verify that the unique ids of each instruction in |linked_context| (i.e. the
 // merged module) are truly unique. Does not check the validity of other ids
 static spv_result_t VerifyIds(const MessageConsumer& consumer,
-                              ir::IRContext* linked_context);
+                              opt::IRContext* linked_context);
 
 spv_result_t Link(const Context& context,
                   const std::vector<std::vector<uint32_t>>& binaries,
@@ -202,7 +202,7 @@
   if (res != SPV_SUCCESS) return res;
 
   // Phase 2: Generate the header
-  ir::ModuleHeader header;
+  opt::ModuleHeader header;
   res = GenerateHeader(consumer, modules, max_id_bound, &header);
   if (res != SPV_SUCCESS) return res;
   IRContext linked_context(c_context->target_env, consumer);
@@ -262,7 +262,7 @@
 }
 
 static spv_result_t ShiftIdsInModules(const MessageConsumer& consumer,
-                                      std::vector<ir::Module*>* modules,
+                                      std::vector<opt::Module*>* modules,
                                       uint32_t* max_id_bound) {
   spv_position_t position = {};
 
@@ -290,7 +290,7 @@
              << " " << id_bound << " is the current ID bound.";
 
     // Invalidate the DefUseManager
-    module->context()->InvalidateAnalyses(ir::IRContext::kAnalysisDefUse);
+    module->context()->InvalidateAnalyses(opt::IRContext::kAnalysisDefUse);
   }
   ++id_bound;
   if (id_bound > 0x3FFFFF)
@@ -304,9 +304,9 @@
 }
 
 static spv_result_t GenerateHeader(const MessageConsumer& consumer,
-                                   const std::vector<ir::Module*>& modules,
+                                   const std::vector<opt::Module*>& modules,
                                    uint32_t max_id_bound,
-                                   ir::ModuleHeader* header) {
+                                   opt::ModuleHeader* header) {
   spv_position_t position = {};
 
   if (modules.empty())
@@ -477,7 +477,7 @@
   // Process functions and their basic blocks
   for (const auto& module : input_modules) {
     for (const auto& func : *module) {
-      std::unique_ptr<ir::Function> cloned_func(func.Clone(linked_context));
+      std::unique_ptr<opt::Function> cloned_func(func.Clone(linked_context));
       cloned_func->SetParent(linked_module);
       linked_module->AddFunction(std::move(cloned_func));
     }
@@ -487,7 +487,7 @@
 }
 
 static spv_result_t GetImportExportPairs(
-    const MessageConsumer& consumer, const ir::IRContext& linked_context,
+    const MessageConsumer& consumer, const opt::IRContext& linked_context,
     const DefUseManager& def_use_manager,
     const DecorationManager& decoration_manager, bool allow_partial_linkage,
     LinkageTable* linkings_to_do) {
@@ -584,7 +584,7 @@
 
 static spv_result_t CheckImportExportCompatibility(
     const MessageConsumer& consumer, const LinkageTable& linkings_to_do,
-    ir::IRContext* context) {
+    opt::IRContext* context) {
   spv_position_t position = {};
 
   // Ensure th import and export types are the same.
@@ -628,7 +628,7 @@
 static spv_result_t RemoveLinkageSpecificInstructions(
     const MessageConsumer& consumer, const LinkerOptions& options,
     const LinkageTable& linkings_to_do, DecorationManager* decoration_manager,
-    ir::IRContext* linked_context) {
+    opt::IRContext* linked_context) {
   spv_position_t position = {};
 
   if (decoration_manager == nullptr)
@@ -746,11 +746,11 @@
 }
 
 spv_result_t VerifyIds(const MessageConsumer& consumer,
-                       ir::IRContext* linked_context) {
+                       opt::IRContext* linked_context) {
   std::unordered_set<uint32_t> ids;
   bool ok = true;
   linked_context->module()->ForEachInst(
-      [&ids, &ok](const ir::Instruction* inst) {
+      [&ids, &ok](const opt::Instruction* inst) {
         ok &= ids.insert(inst->unique_id()).second;
       });
 
diff --git a/source/opt/aggressive_dead_code_elim_pass.cpp b/source/opt/aggressive_dead_code_elim_pass.cpp
index d7b241c..83485f0 100644
--- a/source/opt/aggressive_dead_code_elim_pass.cpp
+++ b/source/opt/aggressive_dead_code_elim_pass.cpp
@@ -50,8 +50,8 @@
 // SpvOpDecorateStringGOOGLE
 // SpvOpDecorationGroup
 struct DecorationLess {
-  bool operator()(const ir::Instruction* lhs,
-                  const ir::Instruction* rhs) const {
+  bool operator()(const opt::Instruction* lhs,
+                  const opt::Instruction* rhs) const {
     assert(lhs && rhs);
     SpvOp lhsOp = lhs->opcode();
     SpvOp rhsOp = rhs->opcode();
@@ -82,11 +82,11 @@
 
 bool AggressiveDCEPass::IsVarOfStorage(uint32_t varId, uint32_t storageClass) {
   if (varId == 0) return false;
-  const ir::Instruction* varInst = get_def_use_mgr()->GetDef(varId);
+  const opt::Instruction* varInst = get_def_use_mgr()->GetDef(varId);
   const SpvOp op = varInst->opcode();
   if (op != SpvOpVariable) return false;
   const uint32_t varTypeId = varInst->type_id();
-  const ir::Instruction* varTypeInst = get_def_use_mgr()->GetDef(varTypeId);
+  const opt::Instruction* varTypeInst = get_def_use_mgr()->GetDef(varTypeId);
   if (varTypeInst->opcode() != SpvOpTypePointer) return false;
   return varTypeInst->GetSingleWordInOperand(kTypePointerStorageClassInIdx) ==
          storageClass;
@@ -105,7 +105,7 @@
 }
 
 void AggressiveDCEPass::AddStores(uint32_t ptrId) {
-  get_def_use_mgr()->ForEachUser(ptrId, [this, ptrId](ir::Instruction* user) {
+  get_def_use_mgr()->ForEachUser(ptrId, [this, ptrId](opt::Instruction* user) {
     switch (user->opcode()) {
       case SpvOpAccessChain:
       case SpvOpInBoundsAccessChain:
@@ -140,7 +140,7 @@
   return true;
 }
 
-bool AggressiveDCEPass::IsDead(ir::Instruction* inst) {
+bool AggressiveDCEPass::IsDead(opt::Instruction* inst) {
   if (IsLive(inst)) return false;
   if (inst->IsBranch() && !IsStructuredHeader(context()->get_instr_block(inst),
                                               nullptr, nullptr, nullptr))
@@ -148,16 +148,16 @@
   return true;
 }
 
-bool AggressiveDCEPass::IsTargetDead(ir::Instruction* inst) {
+bool AggressiveDCEPass::IsTargetDead(opt::Instruction* inst) {
   const uint32_t tId = inst->GetSingleWordInOperand(0);
-  ir::Instruction* tInst = get_def_use_mgr()->GetDef(tId);
-  if (ir::IsAnnotationInst(tInst->opcode())) {
+  opt::Instruction* tInst = get_def_use_mgr()->GetDef(tId);
+  if (opt::IsAnnotationInst(tInst->opcode())) {
     // This must be a decoration group. We go through annotations in a specific
     // order. So if this is not used by any group or group member decorates, it
     // is dead.
     assert(tInst->opcode() == SpvOpDecorationGroup);
     bool dead = true;
-    get_def_use_mgr()->ForEachUser(tInst, [&dead](ir::Instruction* user) {
+    get_def_use_mgr()->ForEachUser(tInst, [&dead](opt::Instruction* user) {
       if (user->opcode() == SpvOpGroupDecorate ||
           user->opcode() == SpvOpGroupMemberDecorate)
         dead = false;
@@ -178,14 +178,14 @@
   live_local_vars_.insert(varId);
 }
 
-bool AggressiveDCEPass::IsStructuredHeader(ir::BasicBlock* bp,
-                                           ir::Instruction** mergeInst,
-                                           ir::Instruction** branchInst,
+bool AggressiveDCEPass::IsStructuredHeader(opt::BasicBlock* bp,
+                                           opt::Instruction** mergeInst,
+                                           opt::Instruction** branchInst,
                                            uint32_t* mergeBlockId) {
   if (!bp) return false;
-  ir::Instruction* mi = bp->GetMergeInst();
+  opt::Instruction* mi = bp->GetMergeInst();
   if (mi == nullptr) return false;
-  ir::Instruction* bri = &*bp->tail();
+  opt::Instruction* bri = &*bp->tail();
   if (branchInst != nullptr) *branchInst = bri;
   if (mergeInst != nullptr) *mergeInst = mi;
   if (mergeBlockId != nullptr) *mergeBlockId = mi->GetSingleWordInOperand(0);
@@ -193,11 +193,11 @@
 }
 
 void AggressiveDCEPass::ComputeBlock2HeaderMaps(
-    std::list<ir::BasicBlock*>& structuredOrder) {
+    std::list<opt::BasicBlock*>& structuredOrder) {
   block2headerBranch_.clear();
   branch2merge_.clear();
   structured_order_index_.clear();
-  std::stack<ir::Instruction*> currentHeaderBranch;
+  std::stack<opt::Instruction*> currentHeaderBranch;
   currentHeaderBranch.push(nullptr);
   uint32_t currentMergeBlockId = 0;
   uint32_t index = 0;
@@ -208,12 +208,12 @@
     // we are leaving the current construct so we must update state
     if ((*bi)->id() == currentMergeBlockId) {
       currentHeaderBranch.pop();
-      ir::Instruction* chb = currentHeaderBranch.top();
+      opt::Instruction* chb = currentHeaderBranch.top();
       if (chb != nullptr)
         currentMergeBlockId = branch2merge_[chb]->GetSingleWordInOperand(0);
     }
-    ir::Instruction* mergeInst;
-    ir::Instruction* branchInst;
+    opt::Instruction* mergeInst;
+    opt::Instruction* branchInst;
     uint32_t mergeBlockId;
     bool is_header =
         IsStructuredHeader(*bi, &mergeInst, &branchInst, &mergeBlockId);
@@ -235,8 +235,8 @@
   }
 }
 
-void AggressiveDCEPass::AddBranch(uint32_t labelId, ir::BasicBlock* bp) {
-  std::unique_ptr<ir::Instruction> newBranch(new ir::Instruction(
+void AggressiveDCEPass::AddBranch(uint32_t labelId, opt::BasicBlock* bp) {
+  std::unique_ptr<opt::Instruction> newBranch(new opt::Instruction(
       context(), SpvOpBranch, 0, 0,
       {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {labelId}}}));
   context()->AnalyzeDefUse(&*newBranch);
@@ -245,35 +245,35 @@
 }
 
 void AggressiveDCEPass::AddBreaksAndContinuesToWorklist(
-    ir::Instruction* loopMerge) {
-  ir::BasicBlock* header = context()->get_instr_block(loopMerge);
+    opt::Instruction* loopMerge) {
+  opt::BasicBlock* header = context()->get_instr_block(loopMerge);
   uint32_t headerIndex = structured_order_index_[header];
   const uint32_t mergeId =
       loopMerge->GetSingleWordInOperand(kLoopMergeMergeBlockIdInIdx);
-  ir::BasicBlock* merge = context()->get_instr_block(mergeId);
+  opt::BasicBlock* merge = context()->get_instr_block(mergeId);
   uint32_t mergeIndex = structured_order_index_[merge];
   get_def_use_mgr()->ForEachUser(
-      mergeId, [headerIndex, mergeIndex, this](ir::Instruction* user) {
+      mergeId, [headerIndex, mergeIndex, this](opt::Instruction* user) {
         if (!user->IsBranch()) return;
-        ir::BasicBlock* block = context()->get_instr_block(user);
+        opt::BasicBlock* block = context()->get_instr_block(user);
         uint32_t index = structured_order_index_[block];
         if (headerIndex < index && index < mergeIndex) {
           // This is a break from the loop.
           AddToWorklist(user);
           // Add branch's merge if there is one.
-          ir::Instruction* userMerge = branch2merge_[user];
+          opt::Instruction* userMerge = branch2merge_[user];
           if (userMerge != nullptr) AddToWorklist(userMerge);
         }
       });
   const uint32_t contId =
       loopMerge->GetSingleWordInOperand(kLoopMergeContinueBlockIdInIdx);
   get_def_use_mgr()->ForEachUser(contId, [&contId,
-                                          this](ir::Instruction* user) {
+                                          this](opt::Instruction* user) {
     SpvOp op = user->opcode();
     if (op == SpvOpBranchConditional || op == SpvOpSwitch) {
       // A conditional branch or switch can only be a continue if it does not
       // have a merge instruction or its merge block is not the continue block.
-      ir::Instruction* hdrMerge = branch2merge_[user];
+      opt::Instruction* hdrMerge = branch2merge_[user];
       if (hdrMerge != nullptr && hdrMerge->opcode() == SpvOpSelectionMerge) {
         uint32_t hdrMergeId =
             hdrMerge->GetSingleWordInOperand(kSelectionMergeMergeBlockIdInIdx);
@@ -284,10 +284,10 @@
     } else if (op == SpvOpBranch) {
       // An unconditional branch can only be a continue if it is not
       // branching to its own merge block.
-      ir::BasicBlock* blk = context()->get_instr_block(user);
-      ir::Instruction* hdrBranch = block2headerBranch_[blk];
+      opt::BasicBlock* blk = context()->get_instr_block(user);
+      opt::Instruction* hdrBranch = block2headerBranch_[blk];
       if (hdrBranch == nullptr) return;
-      ir::Instruction* hdrMerge = branch2merge_[hdrBranch];
+      opt::Instruction* hdrMerge = branch2merge_[hdrBranch];
       if (hdrMerge->opcode() == SpvOpLoopMerge) return;
       uint32_t hdrMergeId =
           hdrMerge->GetSingleWordInOperand(kSelectionMergeMergeBlockIdInIdx);
@@ -299,17 +299,17 @@
   });
 }
 
-bool AggressiveDCEPass::AggressiveDCE(ir::Function* func) {
+bool AggressiveDCEPass::AggressiveDCE(opt::Function* func) {
   // Mark function parameters as live.
   AddToWorklist(&func->DefInst());
   func->ForEachParam(
-      [this](const ir::Instruction* param) {
-        AddToWorklist(const_cast<ir::Instruction*>(param));
+      [this](const opt::Instruction* param) {
+        AddToWorklist(const_cast<opt::Instruction*>(param));
       },
       false);
 
   // Compute map from block to controlling conditional branch
-  std::list<ir::BasicBlock*> structuredOrder;
+  std::list<opt::BasicBlock*> structuredOrder;
   cfg()->ComputeStructuredOrder(func, &*func->begin(), &structuredOrder);
   ComputeBlock2HeaderMaps(structuredOrder);
   bool modified = false;
@@ -404,10 +404,10 @@
     for (auto& ps : private_stores_) AddToWorklist(ps);
   // Perform closure on live instruction set.
   while (!worklist_.empty()) {
-    ir::Instruction* liveInst = worklist_.front();
+    opt::Instruction* liveInst = worklist_.front();
     // Add all operand instructions if not already live
     liveInst->ForEachInId([&liveInst, this](const uint32_t* iid) {
-      ir::Instruction* inInst = get_def_use_mgr()->GetDef(*iid);
+      opt::Instruction* inInst = get_def_use_mgr()->GetDef(*iid);
       // Do not add label if an operand of a branch. This is not needed
       // as part of live code discovery and can create false live code,
       // for example, the branch to a header of a loop.
@@ -421,11 +421,11 @@
     // conditional branch and its merge. Any containing control construct
     // is marked live when the merge and branch are processed out of the
     // worklist.
-    ir::BasicBlock* blk = context()->get_instr_block(liveInst);
-    ir::Instruction* branchInst = block2headerBranch_[blk];
+    opt::BasicBlock* blk = context()->get_instr_block(liveInst);
+    opt::Instruction* branchInst = block2headerBranch_[blk];
     if (branchInst != nullptr) {
       AddToWorklist(branchInst);
-      ir::Instruction* mergeInst = branch2merge_[branchInst];
+      opt::Instruction* mergeInst = branch2merge_[branchInst];
       AddToWorklist(mergeInst);
       // If in a loop, mark all its break and continue instructions live
       if (mergeInst->opcode() == SpvOpLoopMerge)
@@ -476,7 +476,8 @@
   // Kill dead instructions and remember dead blocks
   for (auto bi = structuredOrder.begin(); bi != structuredOrder.end();) {
     uint32_t mergeBlockId = 0;
-    (*bi)->ForEachInst([this, &modified, &mergeBlockId](ir::Instruction* inst) {
+    (*bi)->ForEachInst([this, &modified,
+                        &mergeBlockId](opt::Instruction* inst) {
       if (!IsDead(inst)) return;
       if (inst->opcode() == SpvOpLabel) return;
       // If dead instruction is selection merge, remember merge block
@@ -502,7 +503,7 @@
   return modified;
 }
 
-void AggressiveDCEPass::Initialize(ir::IRContext* c) {
+void AggressiveDCEPass::Initialize(opt::IRContext* c) {
   InitializeProcessing(c);
 
   // Initialize extensions whitelist
@@ -549,7 +550,7 @@
   InitializeModuleScopeLiveInstructions();
 
   // Process all entry point functions.
-  ProcessFunction pfn = [this](ir::Function* fp) { return AggressiveDCE(fp); };
+  ProcessFunction pfn = [this](opt::Function* fp) { return AggressiveDCE(fp); };
   modified |= ProcessEntryPointCallTree(pfn, get_module());
 
   // Process module-level instructions. Now that all live instructions have
@@ -562,7 +563,7 @@
   }
 
   // Cleanup all CFG including all unreachable blocks.
-  ProcessFunction cleanup = [this](ir::Function* f) { return CFGCleanup(f); };
+  ProcessFunction cleanup = [this](opt::Function* f) { return CFGCleanup(f); };
   modified |= ProcessEntryPointCallTree(cleanup, get_module());
 
   return modified ? Status::SuccessWithChange : Status::SuccessWithoutChange;
@@ -572,8 +573,8 @@
   // Identify live functions first. Those that are not live
   // are dead. ADCE is disabled for non-shaders so we do not check for exported
   // functions here.
-  std::unordered_set<const ir::Function*> live_function_set;
-  ProcessFunction mark_live = [&live_function_set](ir::Function* fp) {
+  std::unordered_set<const opt::Function*> live_function_set;
+  ProcessFunction mark_live = [&live_function_set](opt::Function* fp) {
     live_function_set.insert(fp);
     return false;
   };
@@ -594,10 +595,10 @@
   return modified;
 }
 
-void AggressiveDCEPass::EliminateFunction(ir::Function* func) {
+void AggressiveDCEPass::EliminateFunction(opt::Function* func) {
   // Remove all of the instruction in the function body
   func->ForEachInst(
-      [this](ir::Instruction* inst) { context()->KillInst(inst); }, true);
+      [this](opt::Instruction* inst) { context()->KillInst(inst); }, true);
 }
 
 bool AggressiveDCEPass::ProcessGlobalValues() {
@@ -605,7 +606,7 @@
   // This must be done before killing the instructions, otherwise there are
   // dead objects in the def/use database.
   bool modified = false;
-  ir::Instruction* instruction = &*get_module()->debug2_begin();
+  opt::Instruction* instruction = &*get_module()->debug2_begin();
   while (instruction) {
     if (instruction->opcode() != SpvOpName) {
       instruction = instruction->NextNode();
@@ -623,7 +624,7 @@
   // This code removes all unnecessary decorations safely (see #1174). It also
   // does so in a more efficient manner than deleting them only as the targets
   // are deleted.
-  std::vector<ir::Instruction*> annotations;
+  std::vector<opt::Instruction*> annotations;
   for (auto& inst : get_module()->annotations()) annotations.push_back(&inst);
   std::sort(annotations.begin(), annotations.end(), DecorationLess());
   for (auto annotation : annotations) {
@@ -642,7 +643,7 @@
         // target. If all targets are dead, remove this decoration.
         bool dead = true;
         for (uint32_t i = 1; i < annotation->NumOperands();) {
-          ir::Instruction* opInst =
+          opt::Instruction* opInst =
               get_def_use_mgr()->GetDef(annotation->GetSingleWordOperand(i));
           if (IsDead(opInst)) {
             // Don't increment |i|.
@@ -665,7 +666,7 @@
         // decoration.
         bool dead = true;
         for (uint32_t i = 1; i < annotation->NumOperands();) {
-          ir::Instruction* opInst =
+          opt::Instruction* opInst =
               get_def_use_mgr()->GetDef(annotation->GetSingleWordOperand(i));
           if (IsDead(opInst)) {
             // Don't increment |i|.
@@ -710,7 +711,7 @@
 
 AggressiveDCEPass::AggressiveDCEPass() {}
 
-Pass::Status AggressiveDCEPass::Process(ir::IRContext* c) {
+Pass::Status AggressiveDCEPass::Process(opt::IRContext* c) {
   Initialize(c);
   return ProcessImpl();
 }
diff --git a/source/opt/aggressive_dead_code_elim_pass.h b/source/opt/aggressive_dead_code_elim_pass.h
index 04cfc81..d782ba1 100644
--- a/source/opt/aggressive_dead_code_elim_pass.h
+++ b/source/opt/aggressive_dead_code_elim_pass.h
@@ -35,19 +35,19 @@
 
 // See optimizer.hpp for documentation.
 class AggressiveDCEPass : public MemPass {
-  using cbb_ptr = const ir::BasicBlock*;
+  using cbb_ptr = const opt::BasicBlock*;
 
  public:
   using GetBlocksFunction =
-      std::function<std::vector<ir::BasicBlock*>*(const ir::BasicBlock*)>;
+      std::function<std::vector<opt::BasicBlock*>*(const opt::BasicBlock*)>;
 
   AggressiveDCEPass();
   const char* name() const override { return "eliminate-dead-code-aggressive"; }
-  Status Process(ir::IRContext* c) override;
+  Status Process(opt::IRContext* c) override;
 
-  ir::IRContext::Analysis GetPreservedAnalyses() override {
-    return ir::IRContext::kAnalysisDefUse |
-           ir::IRContext::kAnalysisInstrToBlockMapping;
+  opt::IRContext::Analysis GetPreservedAnalyses() override {
+    return opt::IRContext::kAnalysisDefUse |
+           opt::IRContext::kAnalysisInstrToBlockMapping;
   }
 
  private:
@@ -61,19 +61,19 @@
   bool IsLocalVar(uint32_t varId);
 
   // Return true if |inst| is marked live.
-  bool IsLive(const ir::Instruction* inst) const {
+  bool IsLive(const opt::Instruction* inst) const {
     return live_insts_.Get(inst->unique_id());
   }
 
   // Returns true if |inst| is dead.
-  bool IsDead(ir::Instruction* inst);
+  bool IsDead(opt::Instruction* inst);
 
   // Adds entry points, execution modes and workgroup size decorations to the
   // worklist for processing with the first function.
   void InitializeModuleScopeLiveInstructions();
 
   // Add |inst| to worklist_ and live_insts_.
-  void AddToWorklist(ir::Instruction* inst) {
+  void AddToWorklist(opt::Instruction* inst) {
     if (!live_insts_.Set(inst->unique_id())) {
       worklist_.push(inst);
     }
@@ -92,7 +92,7 @@
   // Returns true if the target of |inst| is dead.  An instruction is dead if
   // its result id is used in decoration or debug instructions only. |inst| is
   // assumed to be OpName, OpMemberName or an annotation instruction.
-  bool IsTargetDead(ir::Instruction* inst);
+  bool IsTargetDead(opt::Instruction* inst);
 
   // If |varId| is local, mark all stores of varId as live.
   void ProcessLoad(uint32_t varId);
@@ -102,19 +102,20 @@
   // merge block if they are not nullptr.  Any of |mergeInst|, |branchInst| or
   // |mergeBlockId| may be a null pointer.  Returns false if |bp| is a null
   // pointer.
-  bool IsStructuredHeader(ir::BasicBlock* bp, ir::Instruction** mergeInst,
-                          ir::Instruction** branchInst, uint32_t* mergeBlockId);
+  bool IsStructuredHeader(opt::BasicBlock* bp, opt::Instruction** mergeInst,
+                          opt::Instruction** branchInst,
+                          uint32_t* mergeBlockId);
 
   // Initialize block2headerBranch_ and branch2merge_ using |structuredOrder|
   // to order blocks.
-  void ComputeBlock2HeaderMaps(std::list<ir::BasicBlock*>& structuredOrder);
+  void ComputeBlock2HeaderMaps(std::list<opt::BasicBlock*>& structuredOrder);
 
   // Add branch to |labelId| to end of block |bp|.
-  void AddBranch(uint32_t labelId, ir::BasicBlock* bp);
+  void AddBranch(uint32_t labelId, opt::BasicBlock* bp);
 
   // Add all break and continue branches in the loop associated with
   // |mergeInst| to worklist if not already live
-  void AddBreaksAndContinuesToWorklist(ir::Instruction* mergeInst);
+  void AddBreaksAndContinuesToWorklist(opt::Instruction* mergeInst);
 
   // Eliminates dead debug2 and annotation instructions. Marks dead globals for
   // removal (e.g. types, constants and variables).
@@ -124,7 +125,7 @@
   bool EliminateDeadFunctions();
 
   // Removes |func| from the module and deletes all its instructions.
-  void EliminateFunction(ir::Function* func);
+  void EliminateFunction(opt::Function* func);
 
   // For function |func|, mark all Stores to non-function-scope variables
   // and block terminating instructions as live. Recursively mark the values
@@ -135,9 +136,9 @@
   // existing control structures will remain. This can leave not-insignificant
   // sequences of ultimately useless code.
   // TODO(): Remove useless control constructs.
-  bool AggressiveDCE(ir::Function* func);
+  bool AggressiveDCE(opt::Function* func);
 
-  void Initialize(ir::IRContext* c);
+  void Initialize(opt::IRContext* c);
   Pass::Status ProcessImpl();
 
   // True if current function has a call instruction contained in it
@@ -154,22 +155,22 @@
   // If we don't know, then add it to this list.  Instructions are
   // removed from this list as the algorithm traces side effects,
   // building up the live instructions set |live_insts_|.
-  std::queue<ir::Instruction*> worklist_;
+  std::queue<opt::Instruction*> worklist_;
 
   // Map from block to the branch instruction in the header of the most
   // immediate controlling structured if or loop.  A loop header block points
   // to its own branch instruction.  An if-selection block points to the branch
   // of an enclosing construct's header, if one exists.
-  std::unordered_map<ir::BasicBlock*, ir::Instruction*> block2headerBranch_;
+  std::unordered_map<opt::BasicBlock*, opt::Instruction*> block2headerBranch_;
 
   // Maps basic block to their index in the structured order traversal.
-  std::unordered_map<ir::BasicBlock*, uint32_t> structured_order_index_;
+  std::unordered_map<opt::BasicBlock*, uint32_t> structured_order_index_;
 
   // Map from branch to its associated merge instruction, if any
-  std::unordered_map<ir::Instruction*, ir::Instruction*> branch2merge_;
+  std::unordered_map<opt::Instruction*, opt::Instruction*> branch2merge_;
 
   // Store instructions to variables of private storage
-  std::vector<ir::Instruction*> private_stores_;
+  std::vector<opt::Instruction*> private_stores_;
 
   // Live Instructions
   utils::BitVector live_insts_;
@@ -179,7 +180,7 @@
 
   // List of instructions to delete. Deletion is delayed until debug and
   // annotation instructions are processed.
-  std::vector<ir::Instruction*> to_kill_;
+  std::vector<opt::Instruction*> to_kill_;
 
   // Extensions supported by this pass.
   std::unordered_set<std::string> extensions_whitelist_;
diff --git a/source/opt/basic_block.cpp b/source/opt/basic_block.cpp
index 98b0695..292341c 100644
--- a/source/opt/basic_block.cpp
+++ b/source/opt/basic_block.cpp
@@ -23,8 +23,7 @@
 #include <ostream>
 
 namespace spvtools {
-namespace ir {
-
+namespace opt {
 namespace {
 
 const uint32_t kLoopMergeContinueBlockIdInIdx = 1;
@@ -91,7 +90,7 @@
 }
 
 void BasicBlock::KillAllInsts(bool killLabel) {
-  ForEachInst([killLabel](ir::Instruction* ip) {
+  ForEachInst([killLabel](opt::Instruction* ip) {
     if (killLabel || ip->opcode() != SpvOpLabel) {
       ip->context()->KillInst(ip);
     }
@@ -140,7 +139,7 @@
   }
 }
 
-bool BasicBlock::IsSuccessor(const ir::BasicBlock* block) const {
+bool BasicBlock::IsSuccessor(const opt::BasicBlock* block) const {
   uint32_t succId = block->id();
   bool isSuccessor = false;
   ForEachSuccessorLabel([&isSuccessor, succId](const uint32_t label) {
@@ -196,7 +195,7 @@
 
 std::string BasicBlock::PrettyPrint(uint32_t options) const {
   std::ostringstream str;
-  ForEachInst([&str, options](const ir::Instruction* inst) {
+  ForEachInst([&str, options](const opt::Instruction* inst) {
     str << inst->PrettyPrint(options);
     if (!IsTerminatorInst(inst->opcode())) {
       str << std::endl;
@@ -210,13 +209,13 @@
   assert(!insts_.empty());
 
   BasicBlock* new_block = new BasicBlock(MakeUnique<Instruction>(
-      context, SpvOpLabel, 0, label_id, std::initializer_list<ir::Operand>{}));
+      context, SpvOpLabel, 0, label_id, std::initializer_list<opt::Operand>{}));
 
   new_block->insts_.Splice(new_block->end(), &insts_, iter, end());
   new_block->SetParent(GetParent());
 
-  if (context->AreAnalysesValid(ir::IRContext::kAnalysisInstrToBlockMapping)) {
-    new_block->ForEachInst([new_block, context](ir::Instruction* inst) {
+  if (context->AreAnalysesValid(opt::IRContext::kAnalysisInstrToBlockMapping)) {
+    new_block->ForEachInst([new_block, context](opt::Instruction* inst) {
       context->set_instr_block(inst, new_block);
     });
   }
@@ -224,5 +223,5 @@
   return new_block;
 }
 
-}  // namespace ir
+}  // namespace opt
 }  // namespace spvtools
diff --git a/source/opt/basic_block.h b/source/opt/basic_block.h
index d34b047..1225250 100644
--- a/source/opt/basic_block.h
+++ b/source/opt/basic_block.h
@@ -30,7 +30,7 @@
 #include "iterator.h"
 
 namespace spvtools {
-namespace ir {
+namespace opt {
 
 class Function;
 class IRContext;
@@ -159,14 +159,14 @@
   void ForEachSuccessorLabel(const std::function<void(uint32_t*)>& f);
 
   // Returns true if |block| is a direct successor of |this|.
-  bool IsSuccessor(const ir::BasicBlock* block) const;
+  bool IsSuccessor(const opt::BasicBlock* block) const;
 
   // Runs the given function |f| on the merge and continue label, if any
   void ForMergeAndContinueLabel(const std::function<void(const uint32_t)>& f);
 
   // Returns true if this basic block has any Phi instructions.
   bool HasPhiInstructions() {
-    return !WhileEachPhiInst([](ir::Instruction*) { return false; });
+    return !WhileEachPhiInst([](opt::Instruction*) { return false; });
   }
 
   // Return true if this block is a loop header block.
@@ -313,7 +313,7 @@
       run_on_debug_line_insts);
 }
 
-}  // namespace ir
+}  // namespace opt
 }  // namespace spvtools
 
 #endif  // LIBSPIRV_OPT_BASIC_BLOCK_H_
diff --git a/source/opt/block_merge_pass.cpp b/source/opt/block_merge_pass.cpp
index 09cd3c4..e85a02d 100644
--- a/source/opt/block_merge_pass.cpp
+++ b/source/opt/block_merge_pass.cpp
@@ -22,9 +22,9 @@
 namespace spvtools {
 namespace opt {
 
-void BlockMergePass::KillInstAndName(ir::Instruction* inst) {
-  std::vector<ir::Instruction*> to_kill;
-  get_def_use_mgr()->ForEachUser(inst, [&to_kill](ir::Instruction* user) {
+void BlockMergePass::KillInstAndName(opt::Instruction* inst) {
+  std::vector<opt::Instruction*> to_kill;
+  get_def_use_mgr()->ForEachUser(inst, [&to_kill](opt::Instruction* user) {
     if (user->opcode() == SpvOpName) {
       to_kill.push_back(user);
     }
@@ -35,13 +35,13 @@
   context()->KillInst(inst);
 }
 
-bool BlockMergePass::MergeBlocks(ir::Function* func) {
+bool BlockMergePass::MergeBlocks(opt::Function* func) {
   bool modified = false;
   for (auto bi = func->begin(); bi != func->end();) {
     // Find block with single successor which has no other predecessors.
     auto ii = bi->end();
     --ii;
-    ir::Instruction* br = &*ii;
+    opt::Instruction* br = &*ii;
     if (br->opcode() != SpvOpBranch) {
       ++bi;
       continue;
@@ -69,14 +69,14 @@
       continue;
     }
 
-    ir::Instruction* merge_inst = bi->GetMergeInst();
+    opt::Instruction* merge_inst = bi->GetMergeInst();
     if (pred_is_header && lab_id != merge_inst->GetSingleWordInOperand(0u)) {
       // If this is a header block and the successor is not its merge, we must
       // be careful about which blocks we are willing to merge together.
       // OpLoopMerge must be followed by a conditional or unconditional branch.
       // The merge must be a loop merge because a selection merge cannot be
       // followed by an unconditional branch.
-      ir::BasicBlock* succ_block = context()->get_instr_block(lab_id);
+      opt::BasicBlock* succ_block = context()->get_instr_block(lab_id);
       SpvOp succ_term_op = succ_block->terminator()->opcode();
       assert(merge_inst->opcode() == SpvOpLoopMerge);
       if (succ_term_op != SpvOpBranch &&
@@ -122,7 +122,7 @@
   return modified;
 }
 
-bool BlockMergePass::IsHeader(ir::BasicBlock* block) {
+bool BlockMergePass::IsHeader(opt::BasicBlock* block) {
   return block->GetMergeInst() != nullptr;
 }
 
@@ -131,7 +131,7 @@
 }
 
 bool BlockMergePass::IsMerge(uint32_t id) {
-  return !get_def_use_mgr()->WhileEachUse(id, [](ir::Instruction* user,
+  return !get_def_use_mgr()->WhileEachUse(id, [](opt::Instruction* user,
                                                  uint32_t index) {
     SpvOp op = user->opcode();
     if ((op == SpvOpLoopMerge || op == SpvOpSelectionMerge) && index == 0u) {
@@ -141,22 +141,22 @@
   });
 }
 
-bool BlockMergePass::IsMerge(ir::BasicBlock* block) {
+bool BlockMergePass::IsMerge(opt::BasicBlock* block) {
   return IsMerge(block->id());
 }
 
-void BlockMergePass::Initialize(ir::IRContext* c) { InitializeProcessing(c); }
+void BlockMergePass::Initialize(opt::IRContext* c) { InitializeProcessing(c); }
 
 Pass::Status BlockMergePass::ProcessImpl() {
   // Process all entry point functions.
-  ProcessFunction pfn = [this](ir::Function* fp) { return MergeBlocks(fp); };
+  ProcessFunction pfn = [this](opt::Function* fp) { return MergeBlocks(fp); };
   bool modified = ProcessEntryPointCallTree(pfn, get_module());
   return modified ? Status::SuccessWithChange : Status::SuccessWithoutChange;
 }
 
 BlockMergePass::BlockMergePass() {}
 
-Pass::Status BlockMergePass::Process(ir::IRContext* c) {
+Pass::Status BlockMergePass::Process(opt::IRContext* c) {
   Initialize(c);
   return ProcessImpl();
 }
diff --git a/source/opt/block_merge_pass.h b/source/opt/block_merge_pass.h
index 5b12133..020d293 100644
--- a/source/opt/block_merge_pass.h
+++ b/source/opt/block_merge_pass.h
@@ -38,33 +38,33 @@
  public:
   BlockMergePass();
   const char* name() const override { return "merge-blocks"; }
-  Status Process(ir::IRContext*) override;
-  virtual ir::IRContext::Analysis GetPreservedAnalyses() override {
-    return ir::IRContext::kAnalysisDefUse |
-           ir::IRContext::kAnalysisInstrToBlockMapping |
-           ir::IRContext::kAnalysisDecorations |
-           ir::IRContext::kAnalysisCombinators |
-           ir::IRContext::kAnalysisNameMap;
+  Status Process(opt::IRContext*) override;
+  virtual opt::IRContext::Analysis GetPreservedAnalyses() override {
+    return opt::IRContext::kAnalysisDefUse |
+           opt::IRContext::kAnalysisInstrToBlockMapping |
+           opt::IRContext::kAnalysisDecorations |
+           opt::IRContext::kAnalysisCombinators |
+           opt::IRContext::kAnalysisNameMap;
   }
 
  private:
   // Kill any OpName instruction referencing |inst|, then kill |inst|.
-  void KillInstAndName(ir::Instruction* inst);
+  void KillInstAndName(opt::Instruction* inst);
 
   // Search |func| for blocks which have a single Branch to a block
   // with no other predecessors. Merge these blocks into a single block.
-  bool MergeBlocks(ir::Function* func);
+  bool MergeBlocks(opt::Function* func);
 
   // Returns true if |block| (or |id|) contains a merge instruction.
-  bool IsHeader(ir::BasicBlock* block);
+  bool IsHeader(opt::BasicBlock* block);
   bool IsHeader(uint32_t id);
 
   // Returns true if |block| (or |id|) is the merge target of a merge
   // instruction.
-  bool IsMerge(ir::BasicBlock* block);
+  bool IsMerge(opt::BasicBlock* block);
   bool IsMerge(uint32_t id);
 
-  void Initialize(ir::IRContext* c);
+  void Initialize(opt::IRContext* c);
   Pass::Status ProcessImpl();
 };
 
diff --git a/source/opt/build_module.cpp b/source/opt/build_module.cpp
index ae239bd..e0b2ce1 100644
--- a/source/opt/build_module.cpp
+++ b/source/opt/build_module.cpp
@@ -27,7 +27,7 @@
 spv_result_t SetSpvHeader(void* builder, spv_endianness_t, uint32_t magic,
                           uint32_t version, uint32_t generator,
                           uint32_t id_bound, uint32_t reserved) {
-  reinterpret_cast<ir::IrLoader*>(builder)->SetModuleHeader(
+  reinterpret_cast<opt::IrLoader*>(builder)->SetModuleHeader(
       magic, version, generator, id_bound, reserved);
   return SPV_SUCCESS;
 }
@@ -35,7 +35,7 @@
 // Processes a parsed instruction for IrLoader. Meets the interface requirement
 // of spvBinaryParse().
 spv_result_t SetSpvInst(void* builder, const spv_parsed_instruction_t* inst) {
-  if (reinterpret_cast<ir::IrLoader*>(builder)->AddInstruction(inst)) {
+  if (reinterpret_cast<opt::IrLoader*>(builder)->AddInstruction(inst)) {
     return SPV_SUCCESS;
   }
   return SPV_ERROR_INVALID_BINARY;
@@ -43,15 +43,15 @@
 
 }  // namespace
 
-std::unique_ptr<ir::IRContext> BuildModule(spv_target_env env,
-                                           MessageConsumer consumer,
-                                           const uint32_t* binary,
-                                           const size_t size) {
+std::unique_ptr<opt::IRContext> BuildModule(spv_target_env env,
+                                            MessageConsumer consumer,
+                                            const uint32_t* binary,
+                                            const size_t size) {
   auto context = spvContextCreate(env);
   SetContextMessageConsumer(context, consumer);
 
-  auto irContext = MakeUnique<ir::IRContext>(env, consumer);
-  ir::IrLoader loader(consumer, irContext->module());
+  auto irContext = MakeUnique<opt::IRContext>(env, consumer);
+  opt::IrLoader loader(consumer, irContext->module());
 
   spv_result_t status = spvBinaryParse(context, &loader, binary, size,
                                        SetSpvHeader, SetSpvInst, nullptr);
@@ -62,10 +62,10 @@
   return status == SPV_SUCCESS ? std::move(irContext) : nullptr;
 }
 
-std::unique_ptr<ir::IRContext> BuildModule(spv_target_env env,
-                                           MessageConsumer consumer,
-                                           const std::string& text,
-                                           uint32_t assemble_options) {
+std::unique_ptr<opt::IRContext> BuildModule(spv_target_env env,
+                                            MessageConsumer consumer,
+                                            const std::string& text,
+                                            uint32_t assemble_options) {
   SpirvTools t(env);
   t.SetMessageConsumer(consumer);
   std::vector<uint32_t> binary;
diff --git a/source/opt/build_module.h b/source/opt/build_module.h
index 7e94936..336b569 100644
--- a/source/opt/build_module.h
+++ b/source/opt/build_module.h
@@ -24,19 +24,20 @@
 
 namespace spvtools {
 
-// Builds an ir::Module returns the owning ir::IRContext from the given SPIR-V
+// Builds an opt::Module returns the owning opt::IRContext from the given SPIR-V
 // |binary|. |size| specifies number of words in |binary|. The |binary| will be
 // decoded according to the given target |env|. Returns nullptr if errors occur
 // and sends the errors to |consumer|.
-std::unique_ptr<ir::IRContext> BuildModule(spv_target_env env,
-                                           MessageConsumer consumer,
-                                           const uint32_t* binary, size_t size);
+std::unique_ptr<opt::IRContext> BuildModule(spv_target_env env,
+                                            MessageConsumer consumer,
+                                            const uint32_t* binary,
+                                            size_t size);
 
-// Builds an ir::Module and returns the owning ir::IRContext from the given
+// Builds an opt::Module and returns the owning opt::IRContext from the given
 // SPIR-V assembly |text|.  The |text| will be encoded according to the given
 // target |env|. Returns nullptr if errors occur and sends the errors to
 // |consumer|.
-std::unique_ptr<ir::IRContext> BuildModule(
+std::unique_ptr<opt::IRContext> BuildModule(
     spv_target_env env, MessageConsumer consumer, const std::string& text,
     uint32_t assemble_options = SpirvTools::kDefaultAssembleOption);
 
diff --git a/source/opt/ccp_pass.cpp b/source/opt/ccp_pass.cpp
index b64eadf..7c84469 100644
--- a/source/opt/ccp_pass.cpp
+++ b/source/opt/ccp_pass.cpp
@@ -39,14 +39,14 @@
 bool CCPPass::IsVaryingValue(uint32_t id) const { return id == kVaryingSSAId; }
 
 SSAPropagator::PropStatus CCPPass::MarkInstructionVarying(
-    ir::Instruction* instr) {
+    opt::Instruction* instr) {
   assert(instr->result_id() != 0 &&
          "Instructions with no result cannot be marked varying.");
   values_[instr->result_id()] = kVaryingSSAId;
   return SSAPropagator::kVarying;
 }
 
-SSAPropagator::PropStatus CCPPass::VisitPhi(ir::Instruction* phi) {
+SSAPropagator::PropStatus CCPPass::VisitPhi(opt::Instruction* phi) {
   uint32_t meet_val_id = 0;
 
   // Implement the lattice meet operation. The result of this Phi instruction is
@@ -100,7 +100,7 @@
   return SSAPropagator::kInteresting;
 }
 
-SSAPropagator::PropStatus CCPPass::VisitAssignment(ir::Instruction* instr) {
+SSAPropagator::PropStatus CCPPass::VisitAssignment(opt::Instruction* instr) {
   assert(instr->result_id() != 0 &&
          "Expecting an instruction that produces a result");
 
@@ -133,7 +133,7 @@
     }
     return it->second;
   };
-  ir::Instruction* folded_inst =
+  opt::Instruction* folded_inst =
       context()->get_instruction_folder().FoldInstructionToConstant(instr,
                                                                     map_func);
   if (folded_inst != nullptr) {
@@ -168,8 +168,8 @@
   return MarkInstructionVarying(instr);
 }
 
-SSAPropagator::PropStatus CCPPass::VisitBranch(ir::Instruction* instr,
-                                               ir::BasicBlock** dest_bb) const {
+SSAPropagator::PropStatus CCPPass::VisitBranch(
+    opt::Instruction* instr, opt::BasicBlock** dest_bb) const {
   assert(instr->IsBranch() && "Expected a branch instruction.");
 
   *dest_bb = nullptr;
@@ -250,8 +250,8 @@
   return SSAPropagator::kInteresting;
 }
 
-SSAPropagator::PropStatus CCPPass::VisitInstruction(ir::Instruction* instr,
-                                                    ir::BasicBlock** dest_bb) {
+SSAPropagator::PropStatus CCPPass::VisitInstruction(opt::Instruction* instr,
+                                                    opt::BasicBlock** dest_bb) {
   *dest_bb = nullptr;
   if (instr->opcode() == SpvOpPhi) {
     return VisitPhi(instr);
@@ -275,14 +275,14 @@
   return retval;
 }
 
-bool CCPPass::PropagateConstants(ir::Function* fp) {
+bool CCPPass::PropagateConstants(opt::Function* fp) {
   // Mark function parameters as varying.
-  fp->ForEachParam([this](const ir::Instruction* inst) {
+  fp->ForEachParam([this](const opt::Instruction* inst) {
     values_[inst->result_id()] = kVaryingSSAId;
   });
 
-  const auto visit_fn = [this](ir::Instruction* instr,
-                               ir::BasicBlock** dest_bb) {
+  const auto visit_fn = [this](opt::Instruction* instr,
+                               opt::BasicBlock** dest_bb) {
     return VisitInstruction(instr, dest_bb);
   };
 
@@ -296,7 +296,7 @@
   return false;
 }
 
-void CCPPass::Initialize(ir::IRContext* c) {
+void CCPPass::Initialize(opt::IRContext* c) {
   InitializeProcessing(c);
 
   const_mgr_ = context()->get_constant_mgr();
@@ -315,11 +315,11 @@
   }
 }
 
-Pass::Status CCPPass::Process(ir::IRContext* c) {
+Pass::Status CCPPass::Process(opt::IRContext* c) {
   Initialize(c);
 
   // Process all entry point functions.
-  ProcessFunction pfn = [this](ir::Function* fp) {
+  ProcessFunction pfn = [this](opt::Function* fp) {
     return PropagateConstants(fp);
   };
   bool modified = ProcessReachableCallTree(pfn, context());
diff --git a/source/opt/ccp_pass.h b/source/opt/ccp_pass.h
index 78142c7..ae582ae 100644
--- a/source/opt/ccp_pass.h
+++ b/source/opt/ccp_pass.h
@@ -29,46 +29,46 @@
  public:
   CCPPass() = default;
   const char* name() const override { return "ccp"; }
-  Status Process(ir::IRContext* c) override;
-  virtual ir::IRContext::Analysis GetPreservedAnalyses() override {
-    return ir::IRContext::kAnalysisDefUse |
-           ir::IRContext::kAnalysisInstrToBlockMapping |
-           ir::IRContext::kAnalysisDecorations |
-           ir::IRContext::kAnalysisCombinators | ir::IRContext::kAnalysisCFG |
-           ir::IRContext::kAnalysisDominatorAnalysis |
-           ir::IRContext::kAnalysisNameMap;
+  Status Process(opt::IRContext* c) override;
+  virtual opt::IRContext::Analysis GetPreservedAnalyses() override {
+    return opt::IRContext::kAnalysisDefUse |
+           opt::IRContext::kAnalysisInstrToBlockMapping |
+           opt::IRContext::kAnalysisDecorations |
+           opt::IRContext::kAnalysisCombinators | opt::IRContext::kAnalysisCFG |
+           opt::IRContext::kAnalysisDominatorAnalysis |
+           opt::IRContext::kAnalysisNameMap;
   }
 
  private:
   // Initializes the pass.
-  void Initialize(ir::IRContext* c);
+  void Initialize(opt::IRContext* c);
 
   // Runs constant propagation on the given function |fp|. Returns true if any
   // constants were propagated and the IR modified.
-  bool PropagateConstants(ir::Function* fp);
+  bool PropagateConstants(opt::Function* fp);
 
   // Visits a single instruction |instr|.  If the instruction is a conditional
   // branch that always jumps to the same basic block, it sets the destination
   // block in |dest_bb|.
-  SSAPropagator::PropStatus VisitInstruction(ir::Instruction* instr,
-                                             ir::BasicBlock** dest_bb);
+  SSAPropagator::PropStatus VisitInstruction(opt::Instruction* instr,
+                                             opt::BasicBlock** dest_bb);
 
   // Visits an OpPhi instruction |phi|. This applies the meet operator for the
   // CCP lattice. Essentially, if all the operands in |phi| have the same
   // constant value C, the result for |phi| gets assigned the value C.
-  SSAPropagator::PropStatus VisitPhi(ir::Instruction* phi);
+  SSAPropagator::PropStatus VisitPhi(opt::Instruction* phi);
 
   // Visits an SSA assignment instruction |instr|.  If the RHS of |instr| folds
   // into a constant value C, then the LHS of |instr| is assigned the value C in
   // |values_|.
-  SSAPropagator::PropStatus VisitAssignment(ir::Instruction* instr);
+  SSAPropagator::PropStatus VisitAssignment(opt::Instruction* instr);
 
   // Visits a branch instruction |instr|. If the branch is conditional
   // (OpBranchConditional or OpSwitch), and the value of its selector is known,
   // |dest_bb| will be set to the corresponding destination block. Unconditional
   // branches always set |dest_bb| to the single destination block.
-  SSAPropagator::PropStatus VisitBranch(ir::Instruction* instr,
-                                        ir::BasicBlock** dest_bb) const;
+  SSAPropagator::PropStatus VisitBranch(opt::Instruction* instr,
+                                        opt::BasicBlock** dest_bb) const;
 
   // Replaces all operands used in |fp| with the corresponding constant values
   // in |values_|.  Returns true if any operands were replaced, and false
@@ -77,7 +77,7 @@
 
   // Marks |instr| as varying by registering a varying value for its result
   // into the |values_| table. Returns SSAPropagator::kVarying.
-  SSAPropagator::PropStatus MarkInstructionVarying(ir::Instruction* instr);
+  SSAPropagator::PropStatus MarkInstructionVarying(opt::Instruction* instr);
 
   // Returns true if |id| is the special SSA id that corresponds to a varying
   // value.
diff --git a/source/opt/cfg.cpp b/source/opt/cfg.cpp
index 8314e7c..6d6530b 100644
--- a/source/opt/cfg.cpp
+++ b/source/opt/cfg.cpp
@@ -19,21 +19,20 @@
 #include "module.h"
 
 namespace spvtools {
-namespace ir {
-
+namespace opt {
 namespace {
 
 // Universal Limit of ResultID + 1
-const int kInvalidId = 0x400000;
+const int kMaxResultId = 0x400000;
 
 }  // namespace
 
-CFG::CFG(ir::Module* module)
+CFG::CFG(opt::Module* module)
     : module_(module),
-      pseudo_entry_block_(std::unique_ptr<ir::Instruction>(
-          new ir::Instruction(module->context(), SpvOpLabel, 0, 0, {}))),
-      pseudo_exit_block_(std::unique_ptr<ir::Instruction>(new ir::Instruction(
-          module->context(), SpvOpLabel, 0, kInvalidId, {}))) {
+      pseudo_entry_block_(std::unique_ptr<opt::Instruction>(
+          new opt::Instruction(module->context(), SpvOpLabel, 0, 0, {}))),
+      pseudo_exit_block_(std::unique_ptr<opt::Instruction>(new opt::Instruction(
+          module->context(), SpvOpLabel, 0, kMaxResultId, {}))) {
   for (auto& fn : *module) {
     for (auto& blk : fn) {
       RegisterBlock(&blk);
@@ -41,7 +40,7 @@
   }
 }
 
-void CFG::AddEdges(ir::BasicBlock* blk) {
+void CFG::AddEdges(opt::BasicBlock* blk) {
   uint32_t blk_id = blk->id();
   // Force the creation of an entry, not all basic block have predecessors
   // (such as the entry blocks and some unreachables).
@@ -54,7 +53,7 @@
 void CFG::RemoveNonExistingEdges(uint32_t blk_id) {
   std::vector<uint32_t> updated_pred_list;
   for (uint32_t id : preds(blk_id)) {
-    const ir::BasicBlock* pred_blk = block(id);
+    const opt::BasicBlock* pred_blk = block(id);
     bool has_branch = false;
     pred_blk->ForEachSuccessorLabel([&has_branch, blk_id](uint32_t succ) {
       if (succ == blk_id) {
@@ -67,8 +66,8 @@
   label2preds_.at(blk_id) = std::move(updated_pred_list);
 }
 
-void CFG::ComputeStructuredOrder(ir::Function* func, ir::BasicBlock* root,
-                                 std::list<ir::BasicBlock*>* order) {
+void CFG::ComputeStructuredOrder(opt::Function* func, opt::BasicBlock* root,
+                                 std::list<opt::BasicBlock*>* order) {
   assert(module_->context()->get_feature_mgr()->HasCapability(
              SpvCapabilityShader) &&
          "This only works on structured control flow");
@@ -77,16 +76,16 @@
   ComputeStructuredSuccessors(func);
   auto ignore_block = [](cbb_ptr) {};
   auto ignore_edge = [](cbb_ptr, cbb_ptr) {};
-  auto get_structured_successors = [this](const ir::BasicBlock* b) {
+  auto get_structured_successors = [this](const opt::BasicBlock* b) {
     return &(block2structured_succs_[b]);
   };
 
   // TODO(greg-lunarg): Get rid of const_cast by making moving const
   // out of the cfa.h prototypes and into the invoking code.
   auto post_order = [&](cbb_ptr b) {
-    order->push_front(const_cast<ir::BasicBlock*>(b));
+    order->push_front(const_cast<opt::BasicBlock*>(b));
   };
-  CFA<ir::BasicBlock>::DepthFirstTraversal(
+  CFA<opt::BasicBlock>::DepthFirstTraversal(
       root, get_structured_successors, ignore_block, post_order, ignore_edge);
 }
 
@@ -116,7 +115,7 @@
   }
 }
 
-void CFG::ComputeStructuredSuccessors(ir::Function* func) {
+void CFG::ComputeStructuredSuccessors(opt::Function* func) {
   block2structured_succs_.clear();
   for (auto& blk : *func) {
     // If no predecessors in function, make successor to pseudo entry.
@@ -155,7 +154,7 @@
   order->push_back(bb);
 }
 
-BasicBlock* CFG::SplitLoopHeader(ir::BasicBlock* bb) {
+BasicBlock* CFG::SplitLoopHeader(opt::BasicBlock* bb) {
   assert(bb->GetLoopMergeInst() && "Expecting bb to be the header of a loop.");
 
   Function* fn = bb->GetParent();
@@ -169,7 +168,7 @@
 
   const std::vector<uint32_t>& pred = preds(bb->id());
   // Find the back edge
-  ir::BasicBlock* latch_block = nullptr;
+  opt::BasicBlock* latch_block = nullptr;
   Function::iterator latch_block_iter = header_it;
   while (++latch_block_iter != fn->end()) {
     // If blocks are in the proper order, then the only branch that appears
@@ -191,13 +190,13 @@
     ++iter;
   }
 
-  std::unique_ptr<ir::BasicBlock> newBlock(
+  std::unique_ptr<opt::BasicBlock> newBlock(
       bb->SplitBasicBlock(context, context->TakeNextId(), iter));
 
   // Insert the new bb in the correct position
   auto insert_pos = header_it;
   ++insert_pos;
-  ir::BasicBlock* new_header = &*insert_pos.InsertBefore(std::move(newBlock));
+  opt::BasicBlock* new_header = &*insert_pos.InsertBefore(std::move(newBlock));
   new_header->SetParent(fn);
   uint32_t new_header_id = new_header->id();
   context->AnalyzeDefUse(new_header->GetLabelInst());
@@ -207,7 +206,7 @@
 
   // Update bb mappings.
   context->set_instr_block(new_header->GetLabelInst(), new_header);
-  new_header->ForEachInst([new_header, context](ir::Instruction* inst) {
+  new_header->ForEachInst([new_header, context](opt::Instruction* inst) {
     context->set_instr_block(inst, new_header);
   });
 
@@ -235,10 +234,10 @@
     if (preheader_phi_ops.size() > 2) {
       opt::InstructionBuilder builder(
           context, &*bb->begin(),
-          ir::IRContext::kAnalysisDefUse |
-              ir::IRContext::kAnalysisInstrToBlockMapping);
+          opt::IRContext::kAnalysisDefUse |
+              opt::IRContext::kAnalysisInstrToBlockMapping);
 
-      ir::Instruction* new_phi =
+      opt::Instruction* new_phi =
           builder.AddPhi(phi->type_id(), preheader_phi_ops);
 
       // Add the OpPhi to the header bb.
@@ -252,7 +251,7 @@
     }
 
     phi->RemoveFromList();
-    std::unique_ptr<ir::Instruction> phi_owner(phi);
+    std::unique_ptr<opt::Instruction> phi_owner(phi);
     phi->SetInOperands(std::move(header_phi_ops));
     new_header->begin()->InsertBefore(std::move(phi_owner));
     context->set_instr_block(phi, new_header);
@@ -262,11 +261,11 @@
   // Add a branch to the new header.
   opt::InstructionBuilder branch_builder(
       context, bb,
-      ir::IRContext::kAnalysisDefUse |
-          ir::IRContext::kAnalysisInstrToBlockMapping);
-  bb->AddInstruction(MakeUnique<ir::Instruction>(
+      opt::IRContext::kAnalysisDefUse |
+          opt::IRContext::kAnalysisInstrToBlockMapping);
+  bb->AddInstruction(MakeUnique<opt::Instruction>(
       context, SpvOpBranch, 0, 0,
-      std::initializer_list<ir::Operand>{
+      std::initializer_list<opt::Operand>{
           {SPV_OPERAND_TYPE_ID, {new_header->id()}}}));
   context->AnalyzeUses(bb->terminator());
   context->set_instr_block(bb->terminator(), bb);
@@ -278,7 +277,7 @@
       *id = new_header_id;
     }
   });
-  ir::Instruction* latch_branch = latch_block->terminator();
+  opt::Instruction* latch_branch = latch_block->terminator();
   context->AnalyzeUses(latch_branch);
   label2preds_[new_header->id()].push_back(latch_block->id());
 
@@ -289,7 +288,7 @@
   block_preds.erase(latch_pos);
 
   // Update the loop descriptors
-  if (context->AreAnalysesValid(ir::IRContext::kAnalysisLoopAnalysis)) {
+  if (context->AreAnalysesValid(opt::IRContext::kAnalysisLoopAnalysis)) {
     LoopDescriptor* loop_desc = context->GetLoopDescriptor(bb->GetParent());
     Loop* loop = (*loop_desc)[bb->id()];
 
@@ -319,5 +318,5 @@
   return reachable_blocks;
 }
 
-}  // namespace ir
+}  // namespace opt
 }  // namespace spvtools
diff --git a/source/opt/cfg.h b/source/opt/cfg.h
index 98d06a7..264b54f 100644
--- a/source/opt/cfg.h
+++ b/source/opt/cfg.h
@@ -23,17 +23,17 @@
 #include <unordered_set>
 
 namespace spvtools {
-namespace ir {
+namespace opt {
 
 class CFG {
  public:
-  CFG(ir::Module* module);
+  CFG(opt::Module* module);
 
   // Return the module described by this CFG.
-  ir::Module* get_module() const { return module_; }
+  opt::Module* get_module() const { return module_; }
 
   // Return the list of predecesors for basic block with label |blkid|.
-  // TODO(dnovillo): Move this to ir::BasicBlock.
+  // TODO(dnovillo): Move this to opt::BasicBlock.
   const std::vector<uint32_t>& preds(uint32_t blk_id) const {
     assert(label2preds_.count(blk_id));
     return label2preds_.at(blk_id);
@@ -41,26 +41,26 @@
 
   // Return a pointer to the basic block instance corresponding to the label
   // |blk_id|.
-  ir::BasicBlock* block(uint32_t blk_id) const { return id2block_.at(blk_id); }
+  opt::BasicBlock* block(uint32_t blk_id) const { return id2block_.at(blk_id); }
 
   // Return the pseudo entry and exit blocks.
-  const ir::BasicBlock* pseudo_entry_block() const {
+  const opt::BasicBlock* pseudo_entry_block() const {
     return &pseudo_entry_block_;
   }
-  ir::BasicBlock* pseudo_entry_block() { return &pseudo_entry_block_; }
+  opt::BasicBlock* pseudo_entry_block() { return &pseudo_entry_block_; }
 
-  const ir::BasicBlock* pseudo_exit_block() const {
+  const opt::BasicBlock* pseudo_exit_block() const {
     return &pseudo_exit_block_;
   }
-  ir::BasicBlock* pseudo_exit_block() { return &pseudo_exit_block_; }
+  opt::BasicBlock* pseudo_exit_block() { return &pseudo_exit_block_; }
 
   // Return true if |block_ptr| is the pseudo-entry block.
-  bool IsPseudoEntryBlock(ir::BasicBlock* block_ptr) const {
+  bool IsPseudoEntryBlock(opt::BasicBlock* block_ptr) const {
     return block_ptr == &pseudo_entry_block_;
   }
 
   // Return true if |block_ptr| is the pseudo-exit block.
-  bool IsPseudoExitBlock(ir::BasicBlock* block_ptr) const {
+  bool IsPseudoExitBlock(opt::BasicBlock* block_ptr) const {
     return block_ptr == &pseudo_exit_block_;
   }
 
@@ -68,8 +68,8 @@
   // This order has the property that dominators come before all blocks they
   // dominate and merge blocks come after all blocks that are in the control
   // constructs of their header.
-  void ComputeStructuredOrder(ir::Function* func, ir::BasicBlock* root,
-                              std::list<ir::BasicBlock*>* order);
+  void ComputeStructuredOrder(opt::Function* func, opt::BasicBlock* root,
+                              std::list<opt::BasicBlock*>* order);
 
   // Applies |f| to the basic block in post order starting with |bb|.
   // Note that basic blocks that cannot be reached from |bb| node will not be
@@ -85,14 +85,14 @@
 
   // Registers |blk| as a basic block in the cfg, this also updates the
   // predecessor lists of each successor of |blk|.
-  void RegisterBlock(ir::BasicBlock* blk) {
+  void RegisterBlock(opt::BasicBlock* blk) {
     uint32_t blk_id = blk->id();
     id2block_[blk_id] = blk;
     AddEdges(blk);
   }
 
   // Removes from the CFG any mapping for the basic block id |blk_id|.
-  void ForgetBlock(const ir::BasicBlock* blk) {
+  void ForgetBlock(const opt::BasicBlock* blk) {
     id2block_.erase(blk->id());
     label2preds_.erase(blk->id());
     RemoveSuccessorEdges(blk);
@@ -107,7 +107,7 @@
   }
 
   // Registers |blk| to all of its successors.
-  void AddEdges(ir::BasicBlock* blk);
+  void AddEdges(opt::BasicBlock* blk);
 
   // Registers the basic block id |pred_blk_id| as being a predecessor of the
   // basic block id |succ_blk_id|.
@@ -120,7 +120,7 @@
   void RemoveNonExistingEdges(uint32_t blk_id);
 
   // Remove all edges that leave |bb|.
-  void RemoveSuccessorEdges(const ir::BasicBlock* bb) {
+  void RemoveSuccessorEdges(const opt::BasicBlock* bb) {
     bb->ForEachSuccessorLabel(
         [bb, this](uint32_t succ_id) { RemoveEdge(bb->id(), succ_id); });
   }
@@ -130,12 +130,12 @@
   // is a new block that will be the new loop header.
   //
   // Returns a pointer to the new loop header.
-  BasicBlock* SplitLoopHeader(ir::BasicBlock* bb);
+  BasicBlock* SplitLoopHeader(opt::BasicBlock* bb);
 
   std::unordered_set<BasicBlock*> FindReachableBlocks(BasicBlock* start);
 
  private:
-  using cbb_ptr = const ir::BasicBlock*;
+  using cbb_ptr = const opt::BasicBlock*;
 
   // Compute structured successors for function |func|. A block's structured
   // successors are the blocks it branches to together with its declared merge
@@ -144,7 +144,7 @@
   // first search in the presence of early returns and kills. If the successor
   // vector contain duplicates of the merge or continue blocks, they are safely
   // ignored by DFS.
-  void ComputeStructuredSuccessors(ir::Function* func);
+  void ComputeStructuredSuccessors(opt::Function* func);
 
   // Computes the post-order traversal of the cfg starting at |bb| skipping
   // nodes in |seen|.  The order of the traversal is appended to |order|, and
@@ -154,28 +154,28 @@
                                  std::unordered_set<BasicBlock*>* seen);
 
   // Module for this CFG.
-  ir::Module* module_;
+  opt::Module* module_;
 
   // Map from block to its structured successor blocks. See
   // ComputeStructuredSuccessors() for definition.
-  std::unordered_map<const ir::BasicBlock*, std::vector<ir::BasicBlock*>>
+  std::unordered_map<const opt::BasicBlock*, std::vector<opt::BasicBlock*>>
       block2structured_succs_;
 
   // Extra block whose successors are all blocks with no predecessors
   // in function.
-  ir::BasicBlock pseudo_entry_block_;
+  opt::BasicBlock pseudo_entry_block_;
 
   // Augmented CFG Exit Block.
-  ir::BasicBlock pseudo_exit_block_;
+  opt::BasicBlock pseudo_exit_block_;
 
   // Map from block's label id to its predecessor blocks ids
   std::unordered_map<uint32_t, std::vector<uint32_t>> label2preds_;
 
   // Map from block's label id to block.
-  std::unordered_map<uint32_t, ir::BasicBlock*> id2block_;
+  std::unordered_map<uint32_t, opt::BasicBlock*> id2block_;
 };
 
-}  // namespace ir
+}  // namespace opt
 }  // namespace spvtools
 
 #endif  // LIBSPIRV_OPT_CFG_H_
diff --git a/source/opt/cfg_cleanup_pass.cpp b/source/opt/cfg_cleanup_pass.cpp
index 2565225..aa24c7a 100644
--- a/source/opt/cfg_cleanup_pass.cpp
+++ b/source/opt/cfg_cleanup_pass.cpp
@@ -27,13 +27,13 @@
 namespace spvtools {
 namespace opt {
 
-void CFGCleanupPass::Initialize(ir::IRContext* c) { InitializeProcessing(c); }
+void CFGCleanupPass::Initialize(opt::IRContext* c) { InitializeProcessing(c); }
 
-Pass::Status CFGCleanupPass::Process(ir::IRContext* c) {
+Pass::Status CFGCleanupPass::Process(opt::IRContext* c) {
   Initialize(c);
 
   // Process all entry point functions.
-  ProcessFunction pfn = [this](ir::Function* fp) { return CFGCleanup(fp); };
+  ProcessFunction pfn = [this](opt::Function* fp) { return CFGCleanup(fp); };
   bool modified = ProcessReachableCallTree(pfn, context());
   return modified ? Pass::Status::SuccessWithChange
                   : Pass::Status::SuccessWithoutChange;
diff --git a/source/opt/cfg_cleanup_pass.h b/source/opt/cfg_cleanup_pass.h
index 116e11d..dac5352 100644
--- a/source/opt/cfg_cleanup_pass.h
+++ b/source/opt/cfg_cleanup_pass.h
@@ -26,15 +26,15 @@
  public:
   CFGCleanupPass() = default;
   const char* name() const override { return "cfg-cleanup"; }
-  Status Process(ir::IRContext* c) override;
+  Status Process(opt::IRContext* c) override;
 
-  ir::IRContext::Analysis GetPreservedAnalyses() override {
-    return ir::IRContext::kAnalysisDefUse;
+  opt::IRContext::Analysis GetPreservedAnalyses() override {
+    return opt::IRContext::kAnalysisDefUse;
   }
 
  private:
   // Initialize the pass.
-  void Initialize(ir::IRContext* c);
+  void Initialize(opt::IRContext* c);
 };
 
 }  // namespace opt
diff --git a/source/opt/common_uniform_elim_pass.cpp b/source/opt/common_uniform_elim_pass.cpp
index 6c03bcc..e7bcfba 100644
--- a/source/opt/common_uniform_elim_pass.cpp
+++ b/source/opt/common_uniform_elim_pass.cpp
@@ -41,7 +41,7 @@
 }
 
 bool CommonUniformElimPass::IsSamplerOrImageType(
-    const ir::Instruction* typeInst) const {
+    const opt::Instruction* typeInst) const {
   switch (typeInst->opcode()) {
     case SpvOpTypeSampler:
     case SpvOpTypeImage:
@@ -53,7 +53,7 @@
   if (typeInst->opcode() != SpvOpTypeStruct) return false;
   // Return true if any member is a sampler or image
   return !typeInst->WhileEachInId([this](const uint32_t* tid) {
-    const ir::Instruction* compTypeInst = get_def_use_mgr()->GetDef(*tid);
+    const opt::Instruction* compTypeInst = get_def_use_mgr()->GetDef(*tid);
     if (IsSamplerOrImageType(compTypeInst)) {
       return false;
     }
@@ -62,28 +62,28 @@
 }
 
 bool CommonUniformElimPass::IsSamplerOrImageVar(uint32_t varId) const {
-  const ir::Instruction* varInst = get_def_use_mgr()->GetDef(varId);
+  const opt::Instruction* varInst = get_def_use_mgr()->GetDef(varId);
   assert(varInst->opcode() == SpvOpVariable);
   const uint32_t varTypeId = varInst->type_id();
-  const ir::Instruction* varTypeInst = get_def_use_mgr()->GetDef(varTypeId);
+  const opt::Instruction* varTypeInst = get_def_use_mgr()->GetDef(varTypeId);
   const uint32_t varPteTypeId =
       varTypeInst->GetSingleWordInOperand(kTypePointerTypeIdInIdx);
-  ir::Instruction* varPteTypeInst = get_def_use_mgr()->GetDef(varPteTypeId);
+  opt::Instruction* varPteTypeInst = get_def_use_mgr()->GetDef(varPteTypeId);
   return IsSamplerOrImageType(varPteTypeInst);
 }
 
-ir::Instruction* CommonUniformElimPass::GetPtr(ir::Instruction* ip,
-                                               uint32_t* objId) {
+opt::Instruction* CommonUniformElimPass::GetPtr(opt::Instruction* ip,
+                                                uint32_t* objId) {
   const SpvOp op = ip->opcode();
   assert(op == SpvOpStore || op == SpvOpLoad);
   *objId = ip->GetSingleWordInOperand(op == SpvOpStore ? kStorePtrIdInIdx
                                                        : kLoadPtrIdInIdx);
-  ir::Instruction* ptrInst = get_def_use_mgr()->GetDef(*objId);
+  opt::Instruction* ptrInst = get_def_use_mgr()->GetDef(*objId);
   while (ptrInst->opcode() == SpvOpCopyObject) {
     *objId = ptrInst->GetSingleWordInOperand(kCopyObjectOperandInIdx);
     ptrInst = get_def_use_mgr()->GetDef(*objId);
   }
-  ir::Instruction* objInst = ptrInst;
+  opt::Instruction* objInst = ptrInst;
   while (objInst->opcode() != SpvOpVariable &&
          objInst->opcode() != SpvOpFunctionParameter) {
     if (IsNonPtrAccessChain(objInst->opcode())) {
@@ -101,21 +101,21 @@
   assert(get_def_use_mgr()->GetDef(type_id)->opcode() == SpvOpTypeStruct);
   return !get_decoration_mgr()->WhileEachDecoration(
       type_id, SpvDecorationVolatile,
-      [](const ir::Instruction&) { return false; });
+      [](const opt::Instruction&) { return false; });
 }
 
 bool CommonUniformElimPass::IsAccessChainToVolatileStructType(
-    const ir::Instruction& AccessChainInst) {
+    const opt::Instruction& AccessChainInst) {
   assert(AccessChainInst.opcode() == SpvOpAccessChain);
 
   uint32_t ptr_id = AccessChainInst.GetSingleWordInOperand(0);
-  const ir::Instruction* ptr_inst = get_def_use_mgr()->GetDef(ptr_id);
+  const opt::Instruction* ptr_inst = get_def_use_mgr()->GetDef(ptr_id);
   uint32_t pointee_type_id = GetPointeeTypeId(ptr_inst);
   const uint32_t num_operands = AccessChainInst.NumOperands();
 
   // walk the type tree:
   for (uint32_t idx = 3; idx < num_operands; ++idx) {
-    ir::Instruction* pointee_type = get_def_use_mgr()->GetDef(pointee_type_id);
+    opt::Instruction* pointee_type = get_def_use_mgr()->GetDef(pointee_type_id);
 
     switch (pointee_type->opcode()) {
       case SpvOpTypeMatrix:
@@ -130,7 +130,7 @@
 
         if (idx < num_operands - 1) {
           const uint32_t index_id = AccessChainInst.GetSingleWordOperand(idx);
-          const ir::Instruction* index_inst =
+          const opt::Instruction* index_inst =
               get_def_use_mgr()->GetDef(index_id);
           uint32_t index_value = index_inst->GetSingleWordOperand(
               2);  // TODO: replace with GetUintValueFromConstant()
@@ -144,7 +144,7 @@
   return false;
 }
 
-bool CommonUniformElimPass::IsVolatileLoad(const ir::Instruction& loadInst) {
+bool CommonUniformElimPass::IsVolatileLoad(const opt::Instruction& loadInst) {
   assert(loadInst.opcode() == SpvOpLoad);
   // Check if this Load instruction has Volatile Memory Access flag
   if (loadInst.NumOperands() == 4) {
@@ -161,11 +161,11 @@
 }
 
 bool CommonUniformElimPass::IsUniformVar(uint32_t varId) {
-  const ir::Instruction* varInst =
+  const opt::Instruction* varInst =
       get_def_use_mgr()->id_to_defs().find(varId)->second;
   if (varInst->opcode() != SpvOpVariable) return false;
   const uint32_t varTypeId = varInst->type_id();
-  const ir::Instruction* varTypeInst =
+  const opt::Instruction* varTypeInst =
       get_def_use_mgr()->id_to_defs().find(varTypeId)->second;
   return varTypeInst->GetSingleWordInOperand(kTypePointerStorageClassInIdx) ==
              SpvStorageClassUniform ||
@@ -174,21 +174,21 @@
 }
 
 bool CommonUniformElimPass::HasUnsupportedDecorates(uint32_t id) const {
-  return !get_def_use_mgr()->WhileEachUser(id, [this](ir::Instruction* user) {
+  return !get_def_use_mgr()->WhileEachUser(id, [this](opt::Instruction* user) {
     if (IsNonTypeDecorate(user->opcode())) return false;
     return true;
   });
 }
 
 bool CommonUniformElimPass::HasOnlyNamesAndDecorates(uint32_t id) const {
-  return get_def_use_mgr()->WhileEachUser(id, [this](ir::Instruction* user) {
+  return get_def_use_mgr()->WhileEachUser(id, [this](opt::Instruction* user) {
     SpvOp op = user->opcode();
     if (op != SpvOpName && !IsNonTypeDecorate(op)) return false;
     return true;
   });
 }
 
-void CommonUniformElimPass::DeleteIfUseless(ir::Instruction* inst) {
+void CommonUniformElimPass::DeleteIfUseless(opt::Instruction* inst) {
   const uint32_t resId = inst->result_id();
   assert(resId != 0);
   if (HasOnlyNamesAndDecorates(resId)) {
@@ -196,34 +196,34 @@
   }
 }
 
-ir::Instruction* CommonUniformElimPass::ReplaceAndDeleteLoad(
-    ir::Instruction* loadInst, uint32_t replId, ir::Instruction* ptrInst) {
+opt::Instruction* CommonUniformElimPass::ReplaceAndDeleteLoad(
+    opt::Instruction* loadInst, uint32_t replId, opt::Instruction* ptrInst) {
   const uint32_t loadId = loadInst->result_id();
   context()->KillNamesAndDecorates(loadId);
   (void)context()->ReplaceAllUsesWith(loadId, replId);
   // remove load instruction
-  ir::Instruction* next_instruction = context()->KillInst(loadInst);
+  opt::Instruction* next_instruction = context()->KillInst(loadInst);
   // if access chain, see if it can be removed as well
   if (IsNonPtrAccessChain(ptrInst->opcode())) DeleteIfUseless(ptrInst);
   return next_instruction;
 }
 
 void CommonUniformElimPass::GenACLoadRepl(
-    const ir::Instruction* ptrInst,
-    std::vector<std::unique_ptr<ir::Instruction>>* newInsts,
+    const opt::Instruction* ptrInst,
+    std::vector<std::unique_ptr<opt::Instruction>>* newInsts,
     uint32_t* resultId) {
   // Build and append Load
   const uint32_t ldResultId = TakeNextId();
   const uint32_t varId =
       ptrInst->GetSingleWordInOperand(kAccessChainPtrIdInIdx);
-  const ir::Instruction* varInst = get_def_use_mgr()->GetDef(varId);
+  const opt::Instruction* varInst = get_def_use_mgr()->GetDef(varId);
   assert(varInst->opcode() == SpvOpVariable);
   const uint32_t varPteTypeId = GetPointeeTypeId(varInst);
-  std::vector<ir::Operand> load_in_operands;
+  std::vector<opt::Operand> load_in_operands;
   load_in_operands.push_back(
-      ir::Operand(spv_operand_type_t::SPV_OPERAND_TYPE_ID,
-                  std::initializer_list<uint32_t>{varId}));
-  std::unique_ptr<ir::Instruction> newLoad(new ir::Instruction(
+      opt::Operand(spv_operand_type_t::SPV_OPERAND_TYPE_ID,
+                   std::initializer_list<uint32_t>{varId}));
+  std::unique_ptr<opt::Instruction> newLoad(new opt::Instruction(
       context(), SpvOpLoad, varPteTypeId, ldResultId, load_in_operands));
   get_def_use_mgr()->AnalyzeInstDefUse(&*newLoad);
   newInsts->emplace_back(std::move(newLoad));
@@ -231,34 +231,34 @@
   // Build and append Extract
   const uint32_t extResultId = TakeNextId();
   const uint32_t ptrPteTypeId = GetPointeeTypeId(ptrInst);
-  std::vector<ir::Operand> ext_in_opnds;
+  std::vector<opt::Operand> ext_in_opnds;
   ext_in_opnds.push_back(
-      ir::Operand(spv_operand_type_t::SPV_OPERAND_TYPE_ID,
-                  std::initializer_list<uint32_t>{ldResultId}));
+      opt::Operand(spv_operand_type_t::SPV_OPERAND_TYPE_ID,
+                   std::initializer_list<uint32_t>{ldResultId}));
   uint32_t iidIdx = 0;
   ptrInst->ForEachInId([&iidIdx, &ext_in_opnds, this](const uint32_t* iid) {
     if (iidIdx > 0) {
-      const ir::Instruction* cInst = get_def_use_mgr()->GetDef(*iid);
+      const opt::Instruction* cInst = get_def_use_mgr()->GetDef(*iid);
       uint32_t val = cInst->GetSingleWordInOperand(kConstantValueInIdx);
       ext_in_opnds.push_back(
-          ir::Operand(spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER,
-                      std::initializer_list<uint32_t>{val}));
+          opt::Operand(spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER,
+                       std::initializer_list<uint32_t>{val}));
     }
     ++iidIdx;
   });
-  std::unique_ptr<ir::Instruction> newExt(
-      new ir::Instruction(context(), SpvOpCompositeExtract, ptrPteTypeId,
-                          extResultId, ext_in_opnds));
+  std::unique_ptr<opt::Instruction> newExt(
+      new opt::Instruction(context(), SpvOpCompositeExtract, ptrPteTypeId,
+                           extResultId, ext_in_opnds));
   get_def_use_mgr()->AnalyzeInstDefUse(&*newExt);
   newInsts->emplace_back(std::move(newExt));
   *resultId = extResultId;
 }
 
-bool CommonUniformElimPass::IsConstantIndexAccessChain(ir::Instruction* acp) {
+bool CommonUniformElimPass::IsConstantIndexAccessChain(opt::Instruction* acp) {
   uint32_t inIdx = 0;
   return acp->WhileEachInId([&inIdx, this](uint32_t* tid) {
     if (inIdx > 0) {
-      ir::Instruction* opInst = get_def_use_mgr()->GetDef(*tid);
+      opt::Instruction* opInst = get_def_use_mgr()->GetDef(*tid);
       if (opInst->opcode() != SpvOpConstant) return false;
     }
     ++inIdx;
@@ -266,13 +266,14 @@
   });
 }
 
-bool CommonUniformElimPass::UniformAccessChainConvert(ir::Function* func) {
+bool CommonUniformElimPass::UniformAccessChainConvert(opt::Function* func) {
   bool modified = false;
   for (auto bi = func->begin(); bi != func->end(); ++bi) {
-    for (ir::Instruction* inst = &*bi->begin(); inst; inst = inst->NextNode()) {
+    for (opt::Instruction* inst = &*bi->begin(); inst;
+         inst = inst->NextNode()) {
       if (inst->opcode() != SpvOpLoad) continue;
       uint32_t varId;
-      ir::Instruction* ptrInst = GetPtr(inst, &varId);
+      opt::Instruction* ptrInst = GetPtr(inst, &varId);
       if (!IsNonPtrAccessChain(ptrInst->opcode())) continue;
       // Do not convert nested access chains
       if (ptrInst->GetSingleWordInOperand(kAccessChainPtrIdInIdx) != varId)
@@ -283,7 +284,7 @@
       if (HasUnsupportedDecorates(ptrInst->result_id())) continue;
       if (IsVolatileLoad(*inst)) continue;
       if (IsAccessChainToVolatileStructType(*ptrInst)) continue;
-      std::vector<std::unique_ptr<ir::Instruction>> newInsts;
+      std::vector<std::unique_ptr<opt::Instruction>> newInsts;
       uint32_t replId;
       GenACLoadRepl(ptrInst, &newInsts, &replId);
       inst = ReplaceAndDeleteLoad(inst, replId, ptrInst);
@@ -294,7 +295,7 @@
   return modified;
 }
 
-void CommonUniformElimPass::ComputeStructuredSuccessors(ir::Function* func) {
+void CommonUniformElimPass::ComputeStructuredSuccessors(opt::Function* func) {
   block2structured_succs_.clear();
   for (auto& blk : *func) {
     // If header, make merge block first successor.
@@ -315,32 +316,32 @@
 }
 
 void CommonUniformElimPass::ComputeStructuredOrder(
-    ir::Function* func, std::list<ir::BasicBlock*>* order) {
+    opt::Function* func, std::list<opt::BasicBlock*>* order) {
   // Compute structured successors and do DFS
   ComputeStructuredSuccessors(func);
   auto ignore_block = [](cbb_ptr) {};
   auto ignore_edge = [](cbb_ptr, cbb_ptr) {};
-  auto get_structured_successors = [this](const ir::BasicBlock* block) {
+  auto get_structured_successors = [this](const opt::BasicBlock* block) {
     return &(block2structured_succs_[block]);
   };
   // TODO(greg-lunarg): Get rid of const_cast by making moving const
   // out of the cfa.h prototypes and into the invoking code.
   auto post_order = [&](cbb_ptr b) {
-    order->push_front(const_cast<ir::BasicBlock*>(b));
+    order->push_front(const_cast<opt::BasicBlock*>(b));
   };
 
   order->clear();
-  CFA<ir::BasicBlock>::DepthFirstTraversal(
+  CFA<opt::BasicBlock>::DepthFirstTraversal(
       &*func->begin(), get_structured_successors, ignore_block, post_order,
       ignore_edge);
 }
 
-bool CommonUniformElimPass::CommonUniformLoadElimination(ir::Function* func) {
+bool CommonUniformElimPass::CommonUniformLoadElimination(opt::Function* func) {
   // Process all blocks in structured order. This is just one way (the
   // simplest?) to keep track of the most recent block outside of control
   // flow, used to copy common instructions, guaranteed to dominate all
   // following load sites.
-  std::list<ir::BasicBlock*> structuredOrder;
+  std::list<opt::BasicBlock*> structuredOrder;
   ComputeStructuredOrder(func, &structuredOrder);
   uniform2load_id_.clear();
   bool modified = false;
@@ -354,7 +355,7 @@
   while (IsUniformLoadToBeRemoved(&*insertItr)) ++insertItr;
   uint32_t mergeBlockId = 0;
   for (auto bi = structuredOrder.begin(); bi != structuredOrder.end(); ++bi) {
-    ir::BasicBlock* bp = *bi;
+    opt::BasicBlock* bp = *bi;
     // Check if we are exiting outermost control construct. If so, remember
     // new load insertion point. Trying to keep register pressure down.
     if (mergeBlockId == bp->id()) {
@@ -364,10 +365,11 @@
       // ReplaceAndDeleteLoad() can set |insertItr| as a dangling pointer.
       while (IsUniformLoadToBeRemoved(&*insertItr)) ++insertItr;
     }
-    for (ir::Instruction* inst = &*bp->begin(); inst; inst = inst->NextNode()) {
+    for (opt::Instruction* inst = &*bp->begin(); inst;
+         inst = inst->NextNode()) {
       if (inst->opcode() != SpvOpLoad) continue;
       uint32_t varId;
-      ir::Instruction* ptrInst = GetPtr(inst, &varId);
+      opt::Instruction* ptrInst = GetPtr(inst, &varId);
       if (ptrInst->opcode() != SpvOpVariable) continue;
       if (!IsUniformVar(varId)) continue;
       if (IsSamplerOrImageVar(varId)) continue;
@@ -385,7 +387,7 @@
         } else {
           // Copy load into most recent dominating block and remember it
           replId = TakeNextId();
-          std::unique_ptr<ir::Instruction> newLoad(new ir::Instruction(
+          std::unique_ptr<opt::Instruction> newLoad(new opt::Instruction(
               context(), SpvOpLoad, inst->type_id(), replId,
               {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {varId}}}));
           get_def_use_mgr()->AnalyzeInstDefUse(&*newLoad);
@@ -406,14 +408,15 @@
   return modified;
 }
 
-bool CommonUniformElimPass::CommonUniformLoadElimBlock(ir::Function* func) {
+bool CommonUniformElimPass::CommonUniformLoadElimBlock(opt::Function* func) {
   bool modified = false;
   for (auto& blk : *func) {
     uniform2load_id_.clear();
-    for (ir::Instruction* inst = &*blk.begin(); inst; inst = inst->NextNode()) {
+    for (opt::Instruction* inst = &*blk.begin(); inst;
+         inst = inst->NextNode()) {
       if (inst->opcode() != SpvOpLoad) continue;
       uint32_t varId;
-      ir::Instruction* ptrInst = GetPtr(inst, &varId);
+      opt::Instruction* ptrInst = GetPtr(inst, &varId);
       if (ptrInst->opcode() != SpvOpVariable) continue;
       if (!IsUniformVar(varId)) continue;
       if (!IsSamplerOrImageVar(varId)) continue;
@@ -434,7 +437,7 @@
   return modified;
 }
 
-bool CommonUniformElimPass::CommonExtractElimination(ir::Function* func) {
+bool CommonUniformElimPass::CommonExtractElimination(opt::Function* func) {
   // Find all composite ids with duplicate extracts.
   for (auto bi = func->begin(); bi != func->end(); ++bi) {
     for (auto ii = bi->begin(); ii != bi->end(); ++ii) {
@@ -457,7 +460,7 @@
       for (auto idxItr : cItr->second) {
         if (idxItr.second.size() < 2) continue;
         uint32_t replId = TakeNextId();
-        std::unique_ptr<ir::Instruction> newExtract(
+        std::unique_ptr<opt::Instruction> newExtract(
             idxItr.second.front()->Clone(context()));
         newExtract->SetResultId(replId);
         get_def_use_mgr()->AnalyzeInstDefUse(&*newExtract);
@@ -476,7 +479,7 @@
   return modified;
 }
 
-bool CommonUniformElimPass::EliminateCommonUniform(ir::Function* func) {
+bool CommonUniformElimPass::EliminateCommonUniform(opt::Function* func) {
   bool modified = false;
   modified |= UniformAccessChainConvert(func);
   modified |= CommonUniformLoadElimination(func);
@@ -486,7 +489,7 @@
   return modified;
 }
 
-void CommonUniformElimPass::Initialize(ir::IRContext* c) {
+void CommonUniformElimPass::Initialize(opt::IRContext* c) {
   InitializeProcessing(c);
 
   // Clear collections.
@@ -525,12 +528,12 @@
     if (ai.opcode() == SpvOpGroupDecorate) return Status::SuccessWithoutChange;
   // If non-32-bit integer type in module, terminate processing
   // TODO(): Handle non-32-bit integer constants in access chains
-  for (const ir::Instruction& inst : get_module()->types_values())
+  for (const opt::Instruction& inst : get_module()->types_values())
     if (inst.opcode() == SpvOpTypeInt &&
         inst.GetSingleWordInOperand(kTypeIntWidthInIdx) != 32)
       return Status::SuccessWithoutChange;
   // Process entry point functions
-  ProcessFunction pfn = [this](ir::Function* fp) {
+  ProcessFunction pfn = [this](opt::Function* fp) {
     return EliminateCommonUniform(fp);
   };
   bool modified = ProcessEntryPointCallTree(pfn, get_module());
@@ -539,7 +542,7 @@
 
 CommonUniformElimPass::CommonUniformElimPass() {}
 
-Pass::Status CommonUniformElimPass::Process(ir::IRContext* c) {
+Pass::Status CommonUniformElimPass::Process(opt::IRContext* c) {
   Initialize(c);
   return ProcessImpl();
 }
diff --git a/source/opt/common_uniform_elim_pass.h b/source/opt/common_uniform_elim_pass.h
index eb586f2..83fba8e 100644
--- a/source/opt/common_uniform_elim_pass.h
+++ b/source/opt/common_uniform_elim_pass.h
@@ -36,15 +36,15 @@
 
 // See optimizer.hpp for documentation.
 class CommonUniformElimPass : public Pass {
-  using cbb_ptr = const ir::BasicBlock*;
+  using cbb_ptr = const opt::BasicBlock*;
 
  public:
   using GetBlocksFunction =
-      std::function<std::vector<ir::BasicBlock*>*(const ir::BasicBlock*)>;
+      std::function<std::vector<opt::BasicBlock*>*(const opt::BasicBlock*)>;
 
   CommonUniformElimPass();
   const char* name() const override { return "eliminate-common-uniform"; }
-  Status Process(ir::IRContext*) override;
+  Status Process(opt::IRContext*) override;
 
  private:
   // Returns true if |opcode| is a non-ptr access chain op
@@ -52,7 +52,7 @@
 
   // Returns true if |typeInst| is a sampler or image type or a struct
   // containing one, recursively.
-  bool IsSamplerOrImageType(const ir::Instruction* typeInst) const;
+  bool IsSamplerOrImageType(const opt::Instruction* typeInst) const;
 
   // Returns true if |varId| is a variable containing a sampler or image.
   bool IsSamplerOrImageVar(uint32_t varId) const;
@@ -60,7 +60,7 @@
   // Given a load or store pointed at by |ip|, return the top-most
   // non-CopyObj in its pointer operand. Also return the base pointer
   // in |objId|.
-  ir::Instruction* GetPtr(ir::Instruction* ip, uint32_t* objId);
+  opt::Instruction* GetPtr(opt::Instruction* ip, uint32_t* objId);
 
   // Return true if variable is uniform
   bool IsUniformVar(uint32_t varId);
@@ -73,12 +73,12 @@
   // if the accessed variable belongs to a volatile
   // decorated object or member of a struct type
   bool IsAccessChainToVolatileStructType(
-      const ir::Instruction& AccessChainInst);
+      const opt::Instruction& AccessChainInst);
 
   // Given an OpLoad instruction, return true if
   // OpLoad has a Volatile Memory Access flag or if
   // the resulting type is a volatile decorated struct
-  bool IsVolatileLoad(const ir::Instruction& loadInst);
+  bool IsVolatileLoad(const opt::Instruction& loadInst);
 
   // Return true if any uses of |id| are decorate ops.
   bool HasUnsupportedDecorates(uint32_t id) const;
@@ -87,25 +87,25 @@
   bool HasOnlyNamesAndDecorates(uint32_t id) const;
 
   // Delete inst if it has no uses. Assumes inst has a resultId.
-  void DeleteIfUseless(ir::Instruction* inst);
+  void DeleteIfUseless(opt::Instruction* inst);
 
   // Replace all instances of load's id with replId and delete load
   // and its access chain, if any
-  ir::Instruction* ReplaceAndDeleteLoad(ir::Instruction* loadInst,
-                                        uint32_t replId,
-                                        ir::Instruction* ptrInst);
+  opt::Instruction* ReplaceAndDeleteLoad(opt::Instruction* loadInst,
+                                         uint32_t replId,
+                                         opt::Instruction* ptrInst);
 
   // For the (constant index) access chain ptrInst, create an
   // equivalent load and extract
-  void GenACLoadRepl(const ir::Instruction* ptrInst,
-                     std::vector<std::unique_ptr<ir::Instruction>>* newInsts,
+  void GenACLoadRepl(const opt::Instruction* ptrInst,
+                     std::vector<std::unique_ptr<opt::Instruction>>* newInsts,
                      uint32_t* resultId);
 
   // Return true if all indices are constant
-  bool IsConstantIndexAccessChain(ir::Instruction* acp);
+  bool IsConstantIndexAccessChain(opt::Instruction* acp);
 
   // Convert all uniform access chain loads into load/extract.
-  bool UniformAccessChainConvert(ir::Function* func);
+  bool UniformAccessChainConvert(opt::Function* func);
 
   // Compute structured successors for function |func|.
   // A block's structured successors are the blocks it branches to
@@ -117,7 +117,7 @@
   //
   // TODO(dnovillo): This pass computes structured successors slightly different
   // than the implementation in class Pass. Can this be re-factored?
-  void ComputeStructuredSuccessors(ir::Function* func);
+  void ComputeStructuredSuccessors(opt::Function* func);
 
   // Compute structured block order for |func| into |structuredOrder|. This
   // order has the property that dominators come before all blocks they
@@ -126,24 +126,24 @@
   //
   // TODO(dnovillo): This pass computes structured order slightly different
   // than the implementation in class Pass. Can this be re-factored?
-  void ComputeStructuredOrder(ir::Function* func,
-                              std::list<ir::BasicBlock*>* order);
+  void ComputeStructuredOrder(opt::Function* func,
+                              std::list<opt::BasicBlock*>* order);
 
   // Eliminate loads of uniform variables which have previously been loaded.
   // If first load is in control flow, move it to first block of function.
   // Most effective if preceded by UniformAccessChainRemoval().
-  bool CommonUniformLoadElimination(ir::Function* func);
+  bool CommonUniformLoadElimination(opt::Function* func);
 
   // Eliminate loads of uniform sampler and image variables which have
   // previously
   // been loaded in the same block for types whose loads cannot cross blocks.
-  bool CommonUniformLoadElimBlock(ir::Function* func);
+  bool CommonUniformLoadElimBlock(opt::Function* func);
 
   // Eliminate duplicated extracts of same id. Extract may be moved to same
   // block as the id definition. This is primarily intended for extracts
   // from uniform loads. Most effective if preceded by
   // CommonUniformLoadElimination().
-  bool CommonExtractElimination(ir::Function* func);
+  bool CommonExtractElimination(opt::Function* func);
 
   // For function |func|, first change all uniform constant index
   // access chain loads into equivalent composite extracts. Then consolidate
@@ -157,7 +157,7 @@
   // is not enabled. It also currently does not support any extensions.
   //
   // This function currently only optimizes loads with a single index.
-  bool EliminateCommonUniform(ir::Function* func);
+  bool EliminateCommonUniform(opt::Function* func);
 
   // Initialize extensions whitelist
   void InitExtensions();
@@ -172,10 +172,10 @@
 
   // Return true if |inst| is an instruction that loads uniform variable and
   // can be replaced with other uniform load instruction.
-  bool IsUniformLoadToBeRemoved(ir::Instruction* inst) {
+  bool IsUniformLoadToBeRemoved(opt::Instruction* inst) {
     if (inst->opcode() == SpvOpLoad) {
       uint32_t varId;
-      ir::Instruction* ptrInst = GetPtr(inst, &varId);
+      opt::Instruction* ptrInst = GetPtr(inst, &varId);
       if (ptrInst->opcode() == SpvOpVariable && IsUniformVar(varId) &&
           !IsSamplerOrImageVar(varId) &&
           !HasUnsupportedDecorates(inst->result_id()) && !IsVolatileLoad(*inst))
@@ -184,7 +184,7 @@
     return false;
   }
 
-  void Initialize(ir::IRContext* c);
+  void Initialize(opt::IRContext* c);
   Pass::Status ProcessImpl();
 
   // Map from uniform variable id to its common load id
@@ -193,7 +193,7 @@
   // Map of extract composite ids to map of indices to insts
   // TODO(greg-lunarg): Consider std::vector.
   std::unordered_map<uint32_t,
-                     std::unordered_map<uint32_t, std::list<ir::Instruction*>>>
+                     std::unordered_map<uint32_t, std::list<opt::Instruction*>>>
       comp2idx2inst_;
 
   // Extensions supported by this pass.
@@ -201,7 +201,7 @@
 
   // Map from block to its structured successor blocks. See
   // ComputeStructuredSuccessors() for definition.
-  std::unordered_map<const ir::BasicBlock*, std::vector<ir::BasicBlock*>>
+  std::unordered_map<const opt::BasicBlock*, std::vector<opt::BasicBlock*>>
       block2structured_succs_;
 };
 
diff --git a/source/opt/compact_ids_pass.cpp b/source/opt/compact_ids_pass.cpp
index 98a207d..93ec0f9 100644
--- a/source/opt/compact_ids_pass.cpp
+++ b/source/opt/compact_ids_pass.cpp
@@ -21,10 +21,10 @@
 namespace spvtools {
 namespace opt {
 
-using ir::Instruction;
-using ir::Operand;
+using opt::Instruction;
+using opt::Operand;
 
-Pass::Status CompactIdsPass::Process(ir::IRContext* c) {
+Pass::Status CompactIdsPass::Process(opt::IRContext* c) {
   InitializeProcessing(c);
 
   bool modified = false;
diff --git a/source/opt/compact_ids_pass.h b/source/opt/compact_ids_pass.h
index bc23591..49bfdee 100644
--- a/source/opt/compact_ids_pass.h
+++ b/source/opt/compact_ids_pass.h
@@ -26,13 +26,13 @@
 class CompactIdsPass : public Pass {
  public:
   const char* name() const override { return "compact-ids"; }
-  Status Process(ir::IRContext*) override;
+  Status Process(opt::IRContext*) override;
 
   // Return the mask of preserved Analyses.
-  ir::IRContext::Analysis GetPreservedAnalyses() override {
-    return ir::IRContext::kAnalysisInstrToBlockMapping |
-           ir::IRContext::kAnalysisDominatorAnalysis |
-           ir::IRContext::kAnalysisLoopAnalysis;
+  opt::IRContext::Analysis GetPreservedAnalyses() override {
+    return opt::IRContext::kAnalysisInstrToBlockMapping |
+           opt::IRContext::kAnalysisDominatorAnalysis |
+           opt::IRContext::kAnalysisLoopAnalysis;
   }
 };
 
diff --git a/source/opt/composite.cpp b/source/opt/composite.cpp
index 1fbb71f..7338be9 100644
--- a/source/opt/composite.cpp
+++ b/source/opt/composite.cpp
@@ -26,7 +26,7 @@
 namespace opt {
 
 bool ExtInsMatch(const std::vector<uint32_t>& extIndices,
-                 const ir::Instruction* insInst, const uint32_t extOffset) {
+                 const opt::Instruction* insInst, const uint32_t extOffset) {
   uint32_t numIndices = static_cast<uint32_t>(extIndices.size()) - extOffset;
   if (numIndices != insInst->NumInOperands() - 2) return false;
   for (uint32_t i = 0; i < numIndices; ++i)
@@ -36,7 +36,7 @@
 }
 
 bool ExtInsConflict(const std::vector<uint32_t>& extIndices,
-                    const ir::Instruction* insInst, const uint32_t extOffset) {
+                    const opt::Instruction* insInst, const uint32_t extOffset) {
   if (extIndices.size() - extOffset == insInst->NumInOperands() - 2)
     return false;
   uint32_t extNumIndices = static_cast<uint32_t>(extIndices.size()) - extOffset;
diff --git a/source/opt/composite.h b/source/opt/composite.h
index 2153c62..276ff2c 100644
--- a/source/opt/composite.h
+++ b/source/opt/composite.h
@@ -34,7 +34,7 @@
 // Return true if the extract indices in |extIndices| starting at |extOffset|
 // match indices of insert |insInst|.
 bool ExtInsMatch(const std::vector<uint32_t>& extIndices,
-                 const ir::Instruction* insInst, const uint32_t extOffset);
+                 const opt::Instruction* insInst, const uint32_t extOffset);
 
 // Return true if indices in |extIndices| starting at |extOffset| and
 // indices of insert |insInst| conflict, specifically, if the insert
@@ -42,7 +42,7 @@
 // or less bits than the extract specifies, meaning the exact value being
 // inserted cannot be used to replace the extract.
 bool ExtInsConflict(const std::vector<uint32_t>& extIndices,
-                    const ir::Instruction* insInst, const uint32_t extOffset);
+                    const opt::Instruction* insInst, const uint32_t extOffset);
 
 }  // namespace opt
 }  // namespace spvtools
diff --git a/source/opt/const_folding_rules.cpp b/source/opt/const_folding_rules.cpp
index eb08d1a..42714b3 100644
--- a/source/opt/const_folding_rules.cpp
+++ b/source/opt/const_folding_rules.cpp
@@ -35,7 +35,7 @@
 
 // Folds an OpcompositeExtract where input is a composite constant.
 ConstantFoldingRule FoldExtractWithConstants() {
-  return [](ir::Instruction* inst,
+  return [](opt::Instruction* inst,
             const std::vector<const analysis::Constant*>& constants)
              -> const analysis::Constant* {
     const analysis::Constant* c = constants[kExtractCompositeIdInIdx];
@@ -47,7 +47,7 @@
       uint32_t element_index = inst->GetSingleWordInOperand(i);
       if (c->AsNullConstant()) {
         // Return Null for the return type.
-        ir::IRContext* context = inst->context();
+        opt::IRContext* context = inst->context();
         analysis::ConstantManager* const_mgr = context->get_constant_mgr();
         analysis::TypeManager* type_mgr = context->get_type_mgr();
         return const_mgr->GetConstant(type_mgr->GetType(inst->type_id()), {});
@@ -63,7 +63,7 @@
 }
 
 ConstantFoldingRule FoldVectorShuffleWithConstants() {
-  return [](ir::Instruction* inst,
+  return [](opt::Instruction* inst,
             const std::vector<const analysis::Constant*>& constants)
              -> const analysis::Constant* {
     assert(inst->opcode() == SpvOpVectorShuffle);
@@ -73,7 +73,7 @@
       return nullptr;
     }
 
-    ir::IRContext* context = inst->context();
+    opt::IRContext* context = inst->context();
     analysis::ConstantManager* const_mgr = context->get_constant_mgr();
     const analysis::Type* element_type = c1->type()->AsVector()->element_type();
 
@@ -100,11 +100,11 @@
     for (uint32_t i = 2; i < inst->NumInOperands(); ++i) {
       uint32_t index = inst->GetSingleWordInOperand(i);
       if (index < c1_components.size()) {
-        ir::Instruction* member_inst =
+        opt::Instruction* member_inst =
             const_mgr->GetDefiningInstruction(c1_components[index]);
         ids.push_back(member_inst->result_id());
       } else {
-        ir::Instruction* member_inst = const_mgr->GetDefiningInstruction(
+        opt::Instruction* member_inst = const_mgr->GetDefiningInstruction(
             c2_components[index - c1_components.size()]);
         ids.push_back(member_inst->result_id());
       }
@@ -116,11 +116,11 @@
 }
 
 ConstantFoldingRule FoldVectorTimesScalar() {
-  return [](ir::Instruction* inst,
+  return [](opt::Instruction* inst,
             const std::vector<const analysis::Constant*>& constants)
              -> const analysis::Constant* {
     assert(inst->opcode() == SpvOpVectorTimesScalar);
-    ir::IRContext* context = inst->context();
+    opt::IRContext* context = inst->context();
     analysis::ConstantManager* const_mgr = context->get_constant_mgr();
     analysis::TypeManager* type_mgr = context->get_type_mgr();
 
@@ -194,10 +194,10 @@
 ConstantFoldingRule FoldCompositeWithConstants() {
   // Folds an OpCompositeConstruct where all of the inputs are constants to a
   // constant.  A new constant is created if necessary.
-  return [](ir::Instruction* inst,
+  return [](opt::Instruction* inst,
             const std::vector<const analysis::Constant*>& constants)
              -> const analysis::Constant* {
-    ir::IRContext* context = inst->context();
+    opt::IRContext* context = inst->context();
     analysis::ConstantManager* const_mgr = context->get_constant_mgr();
     analysis::TypeManager* type_mgr = context->get_type_mgr();
     const analysis::Type* new_type = type_mgr->GetType(inst->type_id());
@@ -238,10 +238,10 @@
 // not |nullptr|, then their type is either |Float| or |Integer| or a |Vector|
 // whose element type is |Float| or |Integer|.
 ConstantFoldingRule FoldFPUnaryOp(UnaryScalarFoldingRule scalar_rule) {
-  return [scalar_rule](ir::Instruction* inst,
+  return [scalar_rule](opt::Instruction* inst,
                        const std::vector<const analysis::Constant*>& constants)
              -> const analysis::Constant* {
-    ir::IRContext* context = inst->context();
+    opt::IRContext* context = inst->context();
     analysis::ConstantManager* const_mgr = context->get_constant_mgr();
     analysis::TypeManager* type_mgr = context->get_type_mgr();
     const analysis::Type* result_type = type_mgr->GetType(inst->type_id());
@@ -288,10 +288,10 @@
 // that |constants| contains 2 entries.  If they are not |nullptr|, then their
 // type is either |Float| or a |Vector| whose element type is |Float|.
 ConstantFoldingRule FoldFPBinaryOp(BinaryScalarFoldingRule scalar_rule) {
-  return [scalar_rule](ir::Instruction* inst,
+  return [scalar_rule](opt::Instruction* inst,
                        const std::vector<const analysis::Constant*>& constants)
              -> const analysis::Constant* {
-    ir::IRContext* context = inst->context();
+    opt::IRContext* context = inst->context();
     analysis::ConstantManager* const_mgr = context->get_constant_mgr();
     analysis::TypeManager* type_mgr = context->get_type_mgr();
     const analysis::Type* result_type = type_mgr->GetType(inst->type_id());
@@ -518,10 +518,10 @@
 // Folds an OpDot where all of the inputs are constants to a
 // constant.  A new constant is created if necessary.
 ConstantFoldingRule FoldOpDotWithConstants() {
-  return [](ir::Instruction* inst,
+  return [](opt::Instruction* inst,
             const std::vector<const analysis::Constant*>& constants)
              -> const analysis::Constant* {
-    ir::IRContext* context = inst->context();
+    opt::IRContext* context = inst->context();
     analysis::ConstantManager* const_mgr = context->get_constant_mgr();
     analysis::TypeManager* type_mgr = context->get_type_mgr();
     const analysis::Type* new_type = type_mgr->GetType(inst->type_id());
@@ -614,10 +614,10 @@
 ConstantFoldingRule FoldFNegate() { return FoldFPUnaryOp(FoldFNegateOp()); }
 
 ConstantFoldingRule FoldFClampFeedingCompare(uint32_t cmp_opcode) {
-  return [cmp_opcode](ir::Instruction* inst,
+  return [cmp_opcode](opt::Instruction* inst,
                       const std::vector<const analysis::Constant*>& constants)
              -> const analysis::Constant* {
-    ir::IRContext* context = inst->context();
+    opt::IRContext* context = inst->context();
     analysis::ConstantManager* const_mgr = context->get_constant_mgr();
     analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr();
 
@@ -627,7 +627,7 @@
 
     uint32_t non_const_idx = (constants[0] ? 1 : 0);
     uint32_t operand_id = inst->GetSingleWordInOperand(non_const_idx);
-    ir::Instruction* operand_inst = def_use_mgr->GetDef(operand_id);
+    opt::Instruction* operand_inst = def_use_mgr->GetDef(operand_id);
 
     analysis::TypeManager* type_mgr = context->get_type_mgr();
     const analysis::Type* operand_type =
diff --git a/source/opt/const_folding_rules.h b/source/opt/const_folding_rules.h
index 4925142..354ec6b 100644
--- a/source/opt/const_folding_rules.h
+++ b/source/opt/const_folding_rules.h
@@ -48,7 +48,7 @@
 // fold an instruction, the later rules will not be attempted.
 
 using ConstantFoldingRule = std::function<const analysis::Constant*(
-    ir::Instruction* inst,
+    opt::Instruction* inst,
     const std::vector<const analysis::Constant*>& constants)>;
 
 class ConstantFoldingRules {
diff --git a/source/opt/constants.cpp b/source/opt/constants.cpp
index 377c462..45b57e7 100644
--- a/source/opt/constants.cpp
+++ b/source/opt/constants.cpp
@@ -102,7 +102,7 @@
   }
 }
 
-ConstantManager::ConstantManager(ir::IRContext* ctx) : ctx_(ctx) {
+ConstantManager::ConstantManager(opt::IRContext* ctx) : ctx_(ctx) {
   // Populate the constant table with values from constant declarations in the
   // module.  The values of each OpConstant declaration is the identity
   // assignment (i.e., each constant is its own value).
@@ -111,15 +111,15 @@
   }
 }
 
-Type* ConstantManager::GetType(const ir::Instruction* inst) const {
+Type* ConstantManager::GetType(const opt::Instruction* inst) const {
   return context()->get_type_mgr()->GetType(inst->type_id());
 }
 
 std::vector<const Constant*> ConstantManager::GetOperandConstants(
-    ir::Instruction* inst) const {
+    opt::Instruction* inst) const {
   std::vector<const Constant*> constants;
   for (uint32_t i = 0; i < inst->NumInOperands(); i++) {
-    const ir::Operand* operand = &inst->GetInOperand(i);
+    const opt::Operand* operand = &inst->GetInOperand(i);
     if (operand->type != SPV_OPERAND_TYPE_ID) {
       constants.push_back(nullptr);
     } else {
@@ -144,8 +144,8 @@
   return constants;
 }
 
-ir::Instruction* ConstantManager::BuildInstructionAndAddToModule(
-    const Constant* new_const, ir::Module::inst_iterator* pos,
+opt::Instruction* ConstantManager::BuildInstructionAndAddToModule(
+    const Constant* new_const, opt::Module::inst_iterator* pos,
     uint32_t type_id) {
   uint32_t new_id = context()->TakeNextId();
   auto new_inst = CreateInstruction(new_id, new_const, type_id);
@@ -160,8 +160,8 @@
   return new_inst_ptr;
 }
 
-ir::Instruction* ConstantManager::GetDefiningInstruction(
-    const Constant* c, uint32_t type_id, ir::Module::inst_iterator* pos) {
+opt::Instruction* ConstantManager::GetDefiningInstruction(
+    const Constant* c, uint32_t type_id, opt::Module::inst_iterator* pos) {
   assert(type_id == 0 ||
          context()->get_type_mgr()->GetType(type_id) == c->type());
   uint32_t decl_id = FindDeclaredConstant(c);
@@ -231,7 +231,7 @@
   }
 }
 
-const Constant* ConstantManager::GetConstantFromInst(ir::Instruction* inst) {
+const Constant* ConstantManager::GetConstantFromInst(opt::Instruction* inst) {
   std::vector<uint32_t> literal_words_or_ids;
 
   // Collect the constant defining literals or component ids.
@@ -262,29 +262,29 @@
   return GetConstant(GetType(inst), literal_words_or_ids);
 }
 
-std::unique_ptr<ir::Instruction> ConstantManager::CreateInstruction(
+std::unique_ptr<opt::Instruction> ConstantManager::CreateInstruction(
     uint32_t id, const Constant* c, uint32_t type_id) const {
   uint32_t type =
       (type_id == 0) ? context()->get_type_mgr()->GetId(c->type()) : type_id;
   if (c->AsNullConstant()) {
-    return MakeUnique<ir::Instruction>(context(), SpvOp::SpvOpConstantNull,
-                                       type, id,
-                                       std::initializer_list<ir::Operand>{});
+    return MakeUnique<opt::Instruction>(context(), SpvOp::SpvOpConstantNull,
+                                        type, id,
+                                        std::initializer_list<opt::Operand>{});
   } else if (const BoolConstant* bc = c->AsBoolConstant()) {
-    return MakeUnique<ir::Instruction>(
+    return MakeUnique<opt::Instruction>(
         context(),
         bc->value() ? SpvOp::SpvOpConstantTrue : SpvOp::SpvOpConstantFalse,
-        type, id, std::initializer_list<ir::Operand>{});
+        type, id, std::initializer_list<opt::Operand>{});
   } else if (const IntConstant* ic = c->AsIntConstant()) {
-    return MakeUnique<ir::Instruction>(
+    return MakeUnique<opt::Instruction>(
         context(), SpvOp::SpvOpConstant, type, id,
-        std::initializer_list<ir::Operand>{ir::Operand(
+        std::initializer_list<opt::Operand>{opt::Operand(
             spv_operand_type_t::SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER,
             ic->words())});
   } else if (const FloatConstant* fc = c->AsFloatConstant()) {
-    return MakeUnique<ir::Instruction>(
+    return MakeUnique<opt::Instruction>(
         context(), SpvOp::SpvOpConstant, type, id,
-        std::initializer_list<ir::Operand>{ir::Operand(
+        std::initializer_list<opt::Operand>{opt::Operand(
             spv_operand_type_t::SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER,
             fc->words())});
   } else if (const CompositeConstant* cc = c->AsCompositeConstant()) {
@@ -294,9 +294,9 @@
   }
 }
 
-std::unique_ptr<ir::Instruction> ConstantManager::CreateCompositeInstruction(
+std::unique_ptr<opt::Instruction> ConstantManager::CreateCompositeInstruction(
     uint32_t result_id, const CompositeConstant* cc, uint32_t type_id) const {
-  std::vector<ir::Operand> operands;
+  std::vector<opt::Operand> operands;
   for (const Constant* component_const : cc->GetComponents()) {
     uint32_t id = FindDeclaredConstant(component_const);
     if (id == 0) {
@@ -310,8 +310,8 @@
   }
   uint32_t type =
       (type_id == 0) ? context()->get_type_mgr()->GetId(cc->type()) : type_id;
-  return MakeUnique<ir::Instruction>(context(), SpvOp::SpvOpConstantComposite,
-                                     type, result_id, std::move(operands));
+  return MakeUnique<opt::Instruction>(context(), SpvOp::SpvOpConstantComposite,
+                                      type, result_id, std::move(operands));
 }
 
 const Constant* ConstantManager::GetConstant(
diff --git a/source/opt/constants.h b/source/opt/constants.h
index 82e38a3..63641f3 100644
--- a/source/opt/constants.h
+++ b/source/opt/constants.h
@@ -490,9 +490,9 @@
 // This class represents a pool of constants.
 class ConstantManager {
  public:
-  ConstantManager(ir::IRContext* ctx);
+  ConstantManager(opt::IRContext* ctx);
 
-  ir::IRContext* context() const { return ctx_; }
+  opt::IRContext* context() const { return ctx_; }
 
   // Gets or creates a unique Constant instance of type |type| and a vector of
   // constant defining words |words|. If a Constant instance existed already in
@@ -511,7 +511,7 @@
   // Gets or creates a Constant instance to hold the constant value of the given
   // instruction. It returns a pointer to a Constant instance or nullptr if it
   // could not create the constant.
-  const Constant* GetConstantFromInst(ir::Instruction* inst);
+  const Constant* GetConstantFromInst(opt::Instruction* inst);
 
   // Gets or creates a constant defining instruction for the given Constant |c|.
   // If |c| had already been defined, it returns a pointer to the existing
@@ -527,9 +527,9 @@
   //
   // When |type_id| is not zero, the type of |c| must be the type returned by
   // type manager when given |type_id|.
-  ir::Instruction* GetDefiningInstruction(
+  opt::Instruction* GetDefiningInstruction(
       const Constant* c, uint32_t type_id = 0,
-      ir::Module::inst_iterator* pos = nullptr);
+      opt::Module::inst_iterator* pos = nullptr);
 
   // Creates a constant defining instruction for the given Constant instance
   // and inserts the instruction at the position specified by the given
@@ -543,12 +543,12 @@
   // |type_id| is specified, it is used as the type of the constant. Otherwise
   // the type of the constant is derived by getting an id from the type manager
   // for |c|.
-  ir::Instruction* BuildInstructionAndAddToModule(
-      const Constant* c, ir::Module::inst_iterator* pos, uint32_t type_id = 0);
+  opt::Instruction* BuildInstructionAndAddToModule(
+      const Constant* c, opt::Module::inst_iterator* pos, uint32_t type_id = 0);
 
   // A helper function to get the result type of the given instruction. Returns
   // nullptr if the instruction does not have a type id (type id is 0).
-  Type* GetType(const ir::Instruction* inst) const;
+  Type* GetType(const opt::Instruction* inst) const;
 
   // A helper function to get the collected normal constant with the given id.
   // Returns the pointer to the Constant instance in case it is found.
@@ -591,12 +591,13 @@
 
   // Returns a vector of constants representing each in operand. If an operand
   // is not constant its entry is nullptr.
-  std::vector<const Constant*> GetOperandConstants(ir::Instruction* inst) const;
+  std::vector<const Constant*> GetOperandConstants(
+      opt::Instruction* inst) const;
 
   // Records a mapping between |inst| and the constant value generated by it.
   // It returns true if a new Constant was successfully mapped, false if |inst|
   // generates no constant values.
-  bool MapInst(ir::Instruction* inst) {
+  bool MapInst(opt::Instruction* inst) {
     if (auto cst = GetConstantFromInst(inst)) {
       MapConstantToInst(cst, inst);
       return true;
@@ -614,7 +615,7 @@
 
   // Records a new mapping between |inst| and |const_value|. This updates the
   // two mappings |id_to_const_val_| and |const_val_to_id_|.
-  void MapConstantToInst(const Constant* const_value, ir::Instruction* inst) {
+  void MapConstantToInst(const Constant* const_value, opt::Instruction* inst) {
     const_val_to_id_[const_value] = inst->result_id();
     id_to_const_val_[inst->result_id()] = const_value;
   }
@@ -645,7 +646,7 @@
   // |type_id| is specified, it is used as the type of the constant. Otherwise
   // the type of the constant is derived by getting an id from the type manager
   // for |c|.
-  std::unique_ptr<ir::Instruction> CreateInstruction(
+  std::unique_ptr<opt::Instruction> CreateInstruction(
       uint32_t result_id, const Constant* c, uint32_t type_id = 0) const;
 
   // Creates an OpConstantComposite instruction with the given result id and
@@ -657,12 +658,12 @@
   // |type_id| is specified, it is used as the type of the constant. Otherwise
   // the type of the constant is derived by getting an id from the type manager
   // for |c|.
-  std::unique_ptr<ir::Instruction> CreateCompositeInstruction(
+  std::unique_ptr<opt::Instruction> CreateCompositeInstruction(
       uint32_t result_id, const CompositeConstant* cc,
       uint32_t type_id = 0) const;
 
   // IR context that owns this constant manager.
-  ir::IRContext* ctx_;
+  opt::IRContext* ctx_;
 
   // A mapping from the result ids of Normal Constants to their
   // Constant instances. All Normal Constants in the module, either
diff --git a/source/opt/copy_prop_arrays.cpp b/source/opt/copy_prop_arrays.cpp
index c28edb3..f77c619 100644
--- a/source/opt/copy_prop_arrays.cpp
+++ b/source/opt/copy_prop_arrays.cpp
@@ -25,12 +25,12 @@
 namespace spvtools {
 namespace opt {
 
-Pass::Status CopyPropagateArrays::Process(ir::IRContext* ctx) {
+Pass::Status CopyPropagateArrays::Process(opt::IRContext* ctx) {
   InitializeProcessing(ctx);
 
   bool modified = false;
-  for (ir::Function& function : *get_module()) {
-    ir::BasicBlock* entry_bb = &*function.begin();
+  for (opt::Function& function : *get_module()) {
+    opt::BasicBlock* entry_bb = &*function.begin();
 
     for (auto var_inst = entry_bb->begin(); var_inst->opcode() == SpvOpVariable;
          ++var_inst) {
@@ -39,7 +39,7 @@
       }
 
       // Find the only store to the entire memory location, if it exists.
-      ir::Instruction* store_inst = FindStoreInstruction(&*var_inst);
+      opt::Instruction* store_inst = FindStoreInstruction(&*var_inst);
 
       if (!store_inst) {
         continue;
@@ -60,8 +60,8 @@
 }
 
 std::unique_ptr<CopyPropagateArrays::MemoryObject>
-CopyPropagateArrays::FindSourceObjectIfPossible(ir::Instruction* var_inst,
-                                                ir::Instruction* store_inst) {
+CopyPropagateArrays::FindSourceObjectIfPossible(opt::Instruction* var_inst,
+                                                opt::Instruction* store_inst) {
   assert(var_inst->opcode() == SpvOpVariable && "Expecting a variable.");
 
   // Check that the variable is a composite object where |store_inst|
@@ -95,11 +95,11 @@
   return source;
 }
 
-ir::Instruction* CopyPropagateArrays::FindStoreInstruction(
-    const ir::Instruction* var_inst) const {
-  ir::Instruction* store_inst = nullptr;
+opt::Instruction* CopyPropagateArrays::FindStoreInstruction(
+    const opt::Instruction* var_inst) const {
+  opt::Instruction* store_inst = nullptr;
   get_def_use_mgr()->WhileEachUser(
-      var_inst, [&store_inst, var_inst](ir::Instruction* use) {
+      var_inst, [&store_inst, var_inst](opt::Instruction* use) {
         if (use->opcode() == SpvOpStore &&
             use->GetSingleWordInOperand(kStorePointerInOperand) ==
                 var_inst->result_id()) {
@@ -115,24 +115,24 @@
   return store_inst;
 }
 
-void CopyPropagateArrays::PropagateObject(ir::Instruction* var_inst,
+void CopyPropagateArrays::PropagateObject(opt::Instruction* var_inst,
                                           MemoryObject* source,
-                                          ir::Instruction* insertion_point) {
+                                          opt::Instruction* insertion_point) {
   assert(var_inst->opcode() == SpvOpVariable &&
          "This function propagates variables.");
 
-  ir::Instruction* new_access_chain =
+  opt::Instruction* new_access_chain =
       BuildNewAccessChain(insertion_point, source);
   context()->KillNamesAndDecorates(var_inst);
   UpdateUses(var_inst, new_access_chain);
 }
 
-ir::Instruction* CopyPropagateArrays::BuildNewAccessChain(
-    ir::Instruction* insertion_point,
+opt::Instruction* CopyPropagateArrays::BuildNewAccessChain(
+    opt::Instruction* insertion_point,
     CopyPropagateArrays::MemoryObject* source) const {
   InstructionBuilder builder(context(), insertion_point,
-                             ir::IRContext::kAnalysisDefUse |
-                                 ir::IRContext::kAnalysisInstrToBlockMapping);
+                             opt::IRContext::kAnalysisDefUse |
+                                 opt::IRContext::kAnalysisInstrToBlockMapping);
 
   if (source->AccessChain().size() == 0) {
     return source->GetVariable();
@@ -143,9 +143,9 @@
                                 source->AccessChain());
 }
 
-bool CopyPropagateArrays::HasNoStores(ir::Instruction* ptr_inst) {
+bool CopyPropagateArrays::HasNoStores(opt::Instruction* ptr_inst) {
   return get_def_use_mgr()->WhileEachUser(
-      ptr_inst, [this](ir::Instruction* use) {
+      ptr_inst, [this](opt::Instruction* use) {
         if (use->opcode() == SpvOpLoad) {
           return true;
         } else if (use->opcode() == SpvOpAccessChain) {
@@ -162,15 +162,15 @@
       });
 }
 
-bool CopyPropagateArrays::HasValidReferencesOnly(ir::Instruction* ptr_inst,
-                                                 ir::Instruction* store_inst) {
-  ir::BasicBlock* store_block = context()->get_instr_block(store_inst);
+bool CopyPropagateArrays::HasValidReferencesOnly(opt::Instruction* ptr_inst,
+                                                 opt::Instruction* store_inst) {
+  opt::BasicBlock* store_block = context()->get_instr_block(store_inst);
   opt::DominatorAnalysis* dominator_analysis =
       context()->GetDominatorAnalysis(store_block->GetParent());
 
   return get_def_use_mgr()->WhileEachUser(
       ptr_inst,
-      [this, store_inst, dominator_analysis, ptr_inst](ir::Instruction* use) {
+      [this, store_inst, dominator_analysis, ptr_inst](opt::Instruction* use) {
         if (use->opcode() == SpvOpLoad ||
             use->opcode() == SpvOpImageTexelPointer) {
           // TODO: If there are many load in the same BB as |store_inst| the
@@ -194,7 +194,7 @@
 
 std::unique_ptr<CopyPropagateArrays::MemoryObject>
 CopyPropagateArrays::GetSourceObjectIfAny(uint32_t result) {
-  ir::Instruction* result_inst = context()->get_def_use_mgr()->GetDef(result);
+  opt::Instruction* result_inst = context()->get_def_use_mgr()->GetDef(result);
 
   switch (result_inst->opcode()) {
     case SpvOpLoad:
@@ -213,11 +213,11 @@
 }
 
 std::unique_ptr<CopyPropagateArrays::MemoryObject>
-CopyPropagateArrays::BuildMemoryObjectFromLoad(ir::Instruction* load_inst) {
+CopyPropagateArrays::BuildMemoryObjectFromLoad(opt::Instruction* load_inst) {
   std::vector<uint32_t> components_in_reverse;
   analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr();
 
-  ir::Instruction* current_inst = def_use_mgr->GetDef(
+  opt::Instruction* current_inst = def_use_mgr->GetDef(
       load_inst->GetSingleWordInOperand(kLoadPointerInOperand));
 
   // Build the access chain for the memory object by collecting the indices used
@@ -252,7 +252,7 @@
 
 std::unique_ptr<CopyPropagateArrays::MemoryObject>
 CopyPropagateArrays::BuildMemoryObjectFromExtract(
-    ir::Instruction* extract_inst) {
+    opt::Instruction* extract_inst) {
   assert(extract_inst->opcode() == SpvOpCompositeExtract &&
          "Expecting an OpCompositeExtract instruction.");
   analysis::ConstantManager* const_mgr = context()->get_constant_mgr();
@@ -283,7 +283,7 @@
 
 std::unique_ptr<CopyPropagateArrays::MemoryObject>
 CopyPropagateArrays::BuildMemoryObjectFromCompositeConstruct(
-    ir::Instruction* conststruct_inst) {
+    opt::Instruction* conststruct_inst) {
   assert(conststruct_inst->opcode() == SpvOpCompositeConstruct &&
          "Expecting an OpCompositeConstruct instruction.");
 
@@ -347,7 +347,8 @@
 }
 
 std::unique_ptr<CopyPropagateArrays::MemoryObject>
-CopyPropagateArrays::BuildMemoryObjectFromInsert(ir::Instruction* insert_inst) {
+CopyPropagateArrays::BuildMemoryObjectFromInsert(
+    opt::Instruction* insert_inst) {
   assert(insert_inst->opcode() == SpvOpCompositeInsert &&
          "Expecting an OpCompositeInsert instruction.");
 
@@ -406,7 +407,7 @@
 
   memory_object->GetParent();
 
-  ir::Instruction* current_insert =
+  opt::Instruction* current_insert =
       def_use_mgr->GetDef(insert_inst->GetSingleWordInOperand(1));
   for (uint32_t i = number_of_elements - 1; i > 0; --i) {
     if (current_insert->opcode() != SpvOpCompositeInsert) {
@@ -468,7 +469,7 @@
   return false;
 }
 
-bool CopyPropagateArrays::CanUpdateUses(ir::Instruction* original_ptr_inst,
+bool CopyPropagateArrays::CanUpdateUses(opt::Instruction* original_ptr_inst,
                                         uint32_t type_id) {
   analysis::TypeManager* type_mgr = context()->get_type_mgr();
   analysis::ConstantManager* const_mgr = context()->get_constant_mgr();
@@ -487,7 +488,7 @@
 
   return def_use_mgr->WhileEachUse(
       original_ptr_inst,
-      [this, type_mgr, const_mgr, type](ir::Instruction* use, uint32_t) {
+      [this, type_mgr, const_mgr, type](opt::Instruction* use, uint32_t) {
         switch (use->opcode()) {
           case SpvOpLoad: {
             analysis::Pointer* pointer_type = type->AsPointer();
@@ -560,8 +561,8 @@
         }
       });
 }
-void CopyPropagateArrays::UpdateUses(ir::Instruction* original_ptr_inst,
-                                     ir::Instruction* new_ptr_inst) {
+void CopyPropagateArrays::UpdateUses(opt::Instruction* original_ptr_inst,
+                                     opt::Instruction* new_ptr_inst) {
   // TODO (s-perron): Keep the def-use manager up to date.  Not done now because
   // it can cause problems for the |ForEachUse| traversals.  Can be use by
   // keeping a list of instructions that need updating, and then updating them
@@ -571,14 +572,14 @@
   analysis::ConstantManager* const_mgr = context()->get_constant_mgr();
   analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr();
 
-  std::vector<std::pair<ir::Instruction*, uint32_t> > uses;
+  std::vector<std::pair<opt::Instruction*, uint32_t> > uses;
   def_use_mgr->ForEachUse(original_ptr_inst,
-                          [&uses](ir::Instruction* use, uint32_t index) {
+                          [&uses](opt::Instruction* use, uint32_t index) {
                             uses.push_back({use, index});
                           });
 
   for (auto pair : uses) {
-    ir::Instruction* use = pair.first;
+    opt::Instruction* use = pair.first;
     uint32_t index = pair.second;
     analysis::Pointer* pointer_type = nullptr;
     switch (use->opcode()) {
@@ -671,7 +672,7 @@
         // decomposing the object into the base type, which must be the same,
         // and then rebuilding them.
         if (index == 1) {
-          ir::Instruction* target_pointer = def_use_mgr->GetDef(
+          opt::Instruction* target_pointer = def_use_mgr->GetDef(
               use->GetSingleWordInOperand(kStorePointerInOperand));
           pointer_type =
               type_mgr->GetType(target_pointer->type_id())->AsPointer();
@@ -702,8 +703,8 @@
 }
 
 uint32_t CopyPropagateArrays::GenerateCopy(
-    ir::Instruction* object_inst, uint32_t new_type_id,
-    ir::Instruction* insertion_position) {
+    opt::Instruction* object_inst, uint32_t new_type_id,
+    opt::Instruction* insertion_position) {
   analysis::TypeManager* type_mgr = context()->get_type_mgr();
   analysis::ConstantManager* const_mgr = context()->get_constant_mgr();
 
@@ -714,8 +715,8 @@
 
   opt::InstructionBuilder ir_builder(
       context(), insertion_position,
-      ir::IRContext::kAnalysisInstrToBlockMapping |
-          ir::IRContext::kAnalysisDefUse);
+      opt::IRContext::kAnalysisInstrToBlockMapping |
+          opt::IRContext::kAnalysisDefUse);
 
   analysis::Type* original_type = type_mgr->GetType(original_type_id);
   analysis::Type* new_type = type_mgr->GetType(new_type_id);
@@ -735,7 +736,7 @@
     assert(length_const->AsIntConstant());
     uint32_t array_length = length_const->AsIntConstant()->GetU32();
     for (uint32_t i = 0; i < array_length; i++) {
-      ir::Instruction* extract = ir_builder.AddCompositeExtract(
+      opt::Instruction* extract = ir_builder.AddCompositeExtract(
           original_element_type_id, object_inst->result_id(), {i});
       element_ids.push_back(
           GenerateCopy(extract, new_element_type_id, insertion_position));
@@ -753,7 +754,7 @@
         new_struct_type->element_types();
     std::vector<uint32_t> element_ids;
     for (uint32_t i = 0; i < original_types.size(); i++) {
-      ir::Instruction* extract = ir_builder.AddCompositeExtract(
+      opt::Instruction* extract = ir_builder.AddCompositeExtract(
           type_mgr->GetId(original_types[i]), object_inst->result_id(), {i});
       element_ids.push_back(GenerateCopy(extract, type_mgr->GetId(new_types[i]),
                                          insertion_position));
@@ -777,7 +778,7 @@
 }
 
 uint32_t CopyPropagateArrays::MemoryObject::GetNumberOfMembers() {
-  ir::IRContext* context = variable_inst_->context();
+  opt::IRContext* context = variable_inst_->context();
   analysis::TypeManager* type_mgr = context->get_type_mgr();
 
   const analysis::Type* type = type_mgr->GetType(variable_inst_->type_id());
@@ -804,7 +805,7 @@
 }
 
 template <class iterator>
-CopyPropagateArrays::MemoryObject::MemoryObject(ir::Instruction* var_inst,
+CopyPropagateArrays::MemoryObject::MemoryObject(opt::Instruction* var_inst,
                                                 iterator begin, iterator end)
     : variable_inst_(var_inst), access_chain_(begin, end) {}
 
diff --git a/source/opt/copy_prop_arrays.h b/source/opt/copy_prop_arrays.h
index db6156a..acee72f 100644
--- a/source/opt/copy_prop_arrays.h
+++ b/source/opt/copy_prop_arrays.h
@@ -38,15 +38,15 @@
 class CopyPropagateArrays : public MemPass {
  public:
   const char* name() const override { return "copy-propagate-arrays"; }
-  Status Process(ir::IRContext*) override;
+  Status Process(opt::IRContext*) override;
 
-  ir::IRContext::Analysis GetPreservedAnalyses() override {
-    return ir::IRContext::kAnalysisDefUse | ir::IRContext::kAnalysisCFG |
-           ir::IRContext::kAnalysisInstrToBlockMapping |
-           ir::IRContext::kAnalysisLoopAnalysis |
-           ir::IRContext::kAnalysisDecorations |
-           ir::IRContext::kAnalysisDominatorAnalysis |
-           ir::IRContext::kAnalysisNameMap;
+  opt::IRContext::Analysis GetPreservedAnalyses() override {
+    return opt::IRContext::kAnalysisDefUse | opt::IRContext::kAnalysisCFG |
+           opt::IRContext::kAnalysisInstrToBlockMapping |
+           opt::IRContext::kAnalysisLoopAnalysis |
+           opt::IRContext::kAnalysisDecorations |
+           opt::IRContext::kAnalysisDominatorAnalysis |
+           opt::IRContext::kAnalysisNameMap;
   }
 
  private:
@@ -62,7 +62,7 @@
     // are interpreted the same way they would be in an |OpAccessChain|
     // instruction.
     template <class iterator>
-    MemoryObject(ir::Instruction* var_inst, iterator begin, iterator end);
+    MemoryObject(opt::Instruction* var_inst, iterator begin, iterator end);
 
     // Change |this| to now point to the member identified by |access_chain|
     // (starting from the current member).  The elements in |access_chain| are
@@ -87,7 +87,7 @@
     uint32_t GetNumberOfMembers();
 
     // Returns the owning variable that the memory object is contained in.
-    ir::Instruction* GetVariable() const { return variable_inst_; }
+    opt::Instruction* GetVariable() const { return variable_inst_; }
 
     // Returns a vector of integers that can be used to access the specific
     // member that |this| represents starting from the owning variable.  These
@@ -127,7 +127,7 @@
 
    private:
     // The variable that owns this memory object.
-    ir::Instruction* variable_inst_;
+    opt::Instruction* variable_inst_;
 
     // The access chain to reach the particular member the memory object
     // represents.  It should be interpreted the same way the indices in an
@@ -142,18 +142,18 @@
   // and only identifies very simple cases.  If no such memory object can be
   // found, the return value is |nullptr|.
   std::unique_ptr<CopyPropagateArrays::MemoryObject> FindSourceObjectIfPossible(
-      ir::Instruction* var_inst, ir::Instruction* store_inst);
+      opt::Instruction* var_inst, opt::Instruction* store_inst);
 
   // Replaces all loads of |var_inst| with a load from |source| instead.
   // |insertion_pos| is a position where it is possible to construct the
   // address of |source| and also dominates all of the loads of |var_inst|.
-  void PropagateObject(ir::Instruction* var_inst, MemoryObject* source,
-                       ir::Instruction* insertion_pos);
+  void PropagateObject(opt::Instruction* var_inst, MemoryObject* source,
+                       opt::Instruction* insertion_pos);
 
   // Returns true if all of the references to |ptr_inst| can be rewritten and
   // are dominated by |store_inst|.
-  bool HasValidReferencesOnly(ir::Instruction* ptr_inst,
-                              ir::Instruction* store_inst);
+  bool HasValidReferencesOnly(opt::Instruction* ptr_inst,
+                              opt::Instruction* store_inst);
 
   // Returns a memory object that at one time was equivalent to the value in
   // |result|.  If no such memory object exists, the return value is |nullptr|.
@@ -163,21 +163,21 @@
   // object cannot be identified, the return value is |nullptr|.  The opcode of
   // |load_inst| must be |OpLoad|.
   std::unique_ptr<MemoryObject> BuildMemoryObjectFromLoad(
-      ir::Instruction* load_inst);
+      opt::Instruction* load_inst);
 
   // Returns the memory object that at some point was equivalent to the result
   // of |extract_inst|.  If a memory object cannot be identified, the return
   // value is |nullptr|.  The opcode of |extract_inst| must be
   // |OpCompositeExtract|.
   std::unique_ptr<MemoryObject> BuildMemoryObjectFromExtract(
-      ir::Instruction* extract_inst);
+      opt::Instruction* extract_inst);
 
   // Returns the memory object that at some point was equivalent to the result
   // of |construct_inst|.  If a memory object cannot be identified, the return
   // value is |nullptr|.  The opcode of |constuct_inst| must be
   // |OpCompositeConstruct|.
   std::unique_ptr<MemoryObject> BuildMemoryObjectFromCompositeConstruct(
-      ir::Instruction* conststruct_inst);
+      opt::Instruction* conststruct_inst);
 
   // Returns the memory object that at some point was equivalent to the result
   // of |insert_inst|.  If a memory object cannot be identified, the return
@@ -186,43 +186,44 @@
   // |OpCompositeInsert| instructions that insert the elements one at a time in
   // order from beginning to end.
   std::unique_ptr<MemoryObject> BuildMemoryObjectFromInsert(
-      ir::Instruction* insert_inst);
+      opt::Instruction* insert_inst);
 
   // Return true if |type_id| is a pointer type whose pointee type is an array.
   bool IsPointerToArrayType(uint32_t type_id);
 
   // Returns true of there are not stores using |ptr_inst| or something derived
   // from it.
-  bool HasNoStores(ir::Instruction* ptr_inst);
+  bool HasNoStores(opt::Instruction* ptr_inst);
 
   // Creates an |OpAccessChain| instruction whose result is a pointer the memory
   // represented by |source|.  The new instruction will be placed before
   // |insertion_point|.  |insertion_point| must be part of a function.  Returns
   // the new instruction.
-  ir::Instruction* BuildNewAccessChain(ir::Instruction* insertion_point,
-                                       MemoryObject* source) const;
+  opt::Instruction* BuildNewAccessChain(opt::Instruction* insertion_point,
+                                        MemoryObject* source) const;
 
   // Rewrites all uses of |original_ptr| to use |new_pointer_inst| updating
   // types of other instructions as needed.  This function should not be called
   // if |CanUpdateUses(original_ptr_inst, new_pointer_inst->type_id())| returns
   // false.
-  void UpdateUses(ir::Instruction* original_ptr_inst,
-                  ir::Instruction* new_pointer_inst);
+  void UpdateUses(opt::Instruction* original_ptr_inst,
+                  opt::Instruction* new_pointer_inst);
 
   // Return true if |UpdateUses| is able to change all of the uses of
   // |original_ptr_inst| to |type_id| and still have valid code.
-  bool CanUpdateUses(ir::Instruction* original_ptr_inst, uint32_t type_id);
+  bool CanUpdateUses(opt::Instruction* original_ptr_inst, uint32_t type_id);
 
   // Returns the id whose value is the same as |object_to_copy| except its type
   // is |new_type_id|.  Any instructions need to generate this value will be
   // inserted before |insertion_position|.
-  uint32_t GenerateCopy(ir::Instruction* object_to_copy, uint32_t new_type_id,
-                        ir::Instruction* insertion_position);
+  uint32_t GenerateCopy(opt::Instruction* object_to_copy, uint32_t new_type_id,
+                        opt::Instruction* insertion_position);
 
   // Returns a store to |var_inst| that writes to the entire variable, and is
   // the only store that does so.  Note it does not look through OpAccessChain
   // instruction, so partial stores are not considered.
-  ir::Instruction* FindStoreInstruction(const ir::Instruction* var_inst) const;
+  opt::Instruction* FindStoreInstruction(
+      const opt::Instruction* var_inst) const;
 };
 
 }  // namespace opt
diff --git a/source/opt/dead_branch_elim_pass.cpp b/source/opt/dead_branch_elim_pass.cpp
index 32c2911..e4aa61c 100644
--- a/source/opt/dead_branch_elim_pass.cpp
+++ b/source/opt/dead_branch_elim_pass.cpp
@@ -34,7 +34,7 @@
 
 bool DeadBranchElimPass::GetConstCondition(uint32_t condId, bool* condVal) {
   bool condIsConst;
-  ir::Instruction* cInst = get_def_use_mgr()->GetDef(condId);
+  opt::Instruction* cInst = get_def_use_mgr()->GetDef(condId);
   switch (cInst->opcode()) {
     case SpvOpConstantFalse: {
       *condVal = false;
@@ -56,9 +56,9 @@
 }
 
 bool DeadBranchElimPass::GetConstInteger(uint32_t selId, uint32_t* selVal) {
-  ir::Instruction* sInst = get_def_use_mgr()->GetDef(selId);
+  opt::Instruction* sInst = get_def_use_mgr()->GetDef(selId);
   uint32_t typeId = sInst->type_id();
-  ir::Instruction* typeInst = get_def_use_mgr()->GetDef(typeId);
+  opt::Instruction* typeInst = get_def_use_mgr()->GetDef(typeId);
   if (!typeInst || (typeInst->opcode() != SpvOpTypeInt)) return false;
   // TODO(greg-lunarg): Support non-32 bit ints
   if (typeInst->GetSingleWordInOperand(0) != 32) return false;
@@ -72,9 +72,9 @@
   return false;
 }
 
-void DeadBranchElimPass::AddBranch(uint32_t labelId, ir::BasicBlock* bp) {
+void DeadBranchElimPass::AddBranch(uint32_t labelId, opt::BasicBlock* bp) {
   assert(get_def_use_mgr()->GetDef(labelId) != nullptr);
-  std::unique_ptr<ir::Instruction> newBranch(new ir::Instruction(
+  std::unique_ptr<opt::Instruction> newBranch(new opt::Instruction(
       context(), SpvOpBranch, 0, 0,
       {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {labelId}}}));
   context()->AnalyzeDefUse(&*newBranch);
@@ -82,18 +82,18 @@
   bp->AddInstruction(std::move(newBranch));
 }
 
-ir::BasicBlock* DeadBranchElimPass::GetParentBlock(uint32_t id) {
+opt::BasicBlock* DeadBranchElimPass::GetParentBlock(uint32_t id) {
   return context()->get_instr_block(get_def_use_mgr()->GetDef(id));
 }
 
 bool DeadBranchElimPass::MarkLiveBlocks(
-    ir::Function* func, std::unordered_set<ir::BasicBlock*>* live_blocks) {
-  std::unordered_set<ir::BasicBlock*> continues;
-  std::vector<ir::BasicBlock*> stack;
+    opt::Function* func, std::unordered_set<opt::BasicBlock*>* live_blocks) {
+  std::unordered_set<opt::BasicBlock*> continues;
+  std::vector<opt::BasicBlock*> stack;
   stack.push_back(&*func->begin());
   bool modified = false;
   while (!stack.empty()) {
-    ir::BasicBlock* block = stack.back();
+    opt::BasicBlock* block = stack.back();
     stack.pop_back();
 
     // Live blocks doubles as visited set.
@@ -102,7 +102,7 @@
     uint32_t cont_id = block->ContinueBlockIdIfAny();
     if (cont_id != 0) continues.insert(GetParentBlock(cont_id));
 
-    ir::Instruction* terminator = block->terminator();
+    opt::Instruction* terminator = block->terminator();
     uint32_t live_lab_id = 0;
     // Check if the terminator has a single valid successor.
     if (terminator->opcode() == SpvOpBranchConditional) {
@@ -153,7 +153,7 @@
       // Remove the merge instruction if it is a selection merge.
       AddBranch(live_lab_id, block);
       context()->KillInst(terminator);
-      ir::Instruction* mergeInst = block->GetMergeInst();
+      opt::Instruction* mergeInst = block->GetMergeInst();
       if (mergeInst && mergeInst->opcode() == SpvOpSelectionMerge) {
         context()->KillInst(mergeInst);
       }
@@ -171,18 +171,18 @@
 }
 
 void DeadBranchElimPass::MarkUnreachableStructuredTargets(
-    const std::unordered_set<ir::BasicBlock*>& live_blocks,
-    std::unordered_set<ir::BasicBlock*>* unreachable_merges,
-    std::unordered_map<ir::BasicBlock*, ir::BasicBlock*>*
+    const std::unordered_set<opt::BasicBlock*>& live_blocks,
+    std::unordered_set<opt::BasicBlock*>* unreachable_merges,
+    std::unordered_map<opt::BasicBlock*, opt::BasicBlock*>*
         unreachable_continues) {
   for (auto block : live_blocks) {
     if (auto merge_id = block->MergeBlockIdIfAny()) {
-      ir::BasicBlock* merge_block = GetParentBlock(merge_id);
+      opt::BasicBlock* merge_block = GetParentBlock(merge_id);
       if (!live_blocks.count(merge_block)) {
         unreachable_merges->insert(merge_block);
       }
       if (auto cont_id = block->ContinueBlockIdIfAny()) {
-        ir::BasicBlock* cont_block = GetParentBlock(cont_id);
+        opt::BasicBlock* cont_block = GetParentBlock(cont_id);
         if (!live_blocks.count(cont_block)) {
           (*unreachable_continues)[cont_block] = block;
         }
@@ -192,8 +192,9 @@
 }
 
 bool DeadBranchElimPass::FixPhiNodesInLiveBlocks(
-    ir::Function* func, const std::unordered_set<ir::BasicBlock*>& live_blocks,
-    const std::unordered_map<ir::BasicBlock*, ir::BasicBlock*>&
+    opt::Function* func,
+    const std::unordered_set<opt::BasicBlock*>& live_blocks,
+    const std::unordered_map<opt::BasicBlock*, opt::BasicBlock*>&
         unreachable_continues) {
   bool modified = false;
   for (auto& block : *func) {
@@ -205,8 +206,8 @@
 
         bool changed = false;
         bool backedge_added = false;
-        ir::Instruction* inst = &*iter;
-        std::vector<ir::Operand> operands;
+        opt::Instruction* inst = &*iter;
+        std::vector<opt::Operand> operands;
         // Build a complete set of operands (not just input operands). Start
         // with type and result id operands.
         operands.push_back(inst->GetOperand(0u));
@@ -219,7 +220,8 @@
         // However, if there is only one other incoming edge, the OpPhi can be
         // eliminated.
         for (uint32_t i = 1; i < inst->NumInOperands(); i += 2) {
-          ir::BasicBlock* inc = GetParentBlock(inst->GetSingleWordInOperand(i));
+          opt::BasicBlock* inc =
+              GetParentBlock(inst->GetSingleWordInOperand(i));
           auto cont_iter = unreachable_continues.find(inc);
           if (cont_iter != unreachable_continues.end() &&
               cont_iter->second == &block && inst->NumInOperands() > 4) {
@@ -302,9 +304,10 @@
 }
 
 bool DeadBranchElimPass::EraseDeadBlocks(
-    ir::Function* func, const std::unordered_set<ir::BasicBlock*>& live_blocks,
-    const std::unordered_set<ir::BasicBlock*>& unreachable_merges,
-    const std::unordered_map<ir::BasicBlock*, ir::BasicBlock*>&
+    opt::Function* func,
+    const std::unordered_set<opt::BasicBlock*>& live_blocks,
+    const std::unordered_set<opt::BasicBlock*>& unreachable_merges,
+    const std::unordered_map<opt::BasicBlock*, opt::BasicBlock*>&
         unreachable_continues) {
   bool modified = false;
   for (auto ebi = func->begin(); ebi != func->end();) {
@@ -314,9 +317,9 @@
         // Make unreachable, but leave the label.
         KillAllInsts(&*ebi, false);
         // Add unreachable terminator.
-        ebi->AddInstruction(
-            MakeUnique<ir::Instruction>(context(), SpvOpUnreachable, 0, 0,
-                                        std::initializer_list<ir::Operand>{}));
+        ebi->AddInstruction(MakeUnique<opt::Instruction>(
+            context(), SpvOpUnreachable, 0, 0,
+            std::initializer_list<opt::Operand>{}));
         context()->set_instr_block(&*ebi->tail(), &*ebi);
         modified = true;
       }
@@ -330,10 +333,10 @@
         KillAllInsts(&*ebi, false);
         // Add unconditional branch to header.
         assert(unreachable_continues.count(&*ebi));
-        ebi->AddInstruction(
-            MakeUnique<ir::Instruction>(context(), SpvOpBranch, 0, 0,
-                                        std::initializer_list<ir::Operand>{
-                                            {SPV_OPERAND_TYPE_ID, {cont_id}}}));
+        ebi->AddInstruction(MakeUnique<opt::Instruction>(
+            context(), SpvOpBranch, 0, 0,
+            std::initializer_list<opt::Operand>{
+                {SPV_OPERAND_TYPE_ID, {cont_id}}}));
         get_def_use_mgr()->AnalyzeInstUse(&*ebi->tail());
         context()->set_instr_block(&*ebi->tail(), &*ebi);
         modified = true;
@@ -352,13 +355,13 @@
   return modified;
 }
 
-bool DeadBranchElimPass::EliminateDeadBranches(ir::Function* func) {
+bool DeadBranchElimPass::EliminateDeadBranches(opt::Function* func) {
   bool modified = false;
-  std::unordered_set<ir::BasicBlock*> live_blocks;
+  std::unordered_set<opt::BasicBlock*> live_blocks;
   modified |= MarkLiveBlocks(func, &live_blocks);
 
-  std::unordered_set<ir::BasicBlock*> unreachable_merges;
-  std::unordered_map<ir::BasicBlock*, ir::BasicBlock*> unreachable_continues;
+  std::unordered_set<opt::BasicBlock*> unreachable_merges;
+  std::unordered_map<opt::BasicBlock*, opt::BasicBlock*> unreachable_continues;
   MarkUnreachableStructuredTargets(live_blocks, &unreachable_merges,
                                    &unreachable_continues);
   modified |= FixPhiNodesInLiveBlocks(func, live_blocks, unreachable_continues);
@@ -368,7 +371,7 @@
   return modified;
 }
 
-void DeadBranchElimPass::Initialize(ir::IRContext* c) {
+void DeadBranchElimPass::Initialize(opt::IRContext* c) {
   InitializeProcessing(c);
 }
 
@@ -379,7 +382,7 @@
   for (auto& ai : get_module()->annotations())
     if (ai.opcode() == SpvOpGroupDecorate) return Status::SuccessWithoutChange;
   // Process all entry point functions
-  ProcessFunction pfn = [this](ir::Function* fp) {
+  ProcessFunction pfn = [this](opt::Function* fp) {
     return EliminateDeadBranches(fp);
   };
   bool modified = ProcessReachableCallTree(pfn, context());
@@ -388,7 +391,7 @@
 
 DeadBranchElimPass::DeadBranchElimPass() {}
 
-Pass::Status DeadBranchElimPass::Process(ir::IRContext* module) {
+Pass::Status DeadBranchElimPass::Process(opt::IRContext* module) {
   Initialize(module);
   return ProcessImpl();
 }
diff --git a/source/opt/dead_branch_elim_pass.h b/source/opt/dead_branch_elim_pass.h
index 57450bb..fbde8e7 100644
--- a/source/opt/dead_branch_elim_pass.h
+++ b/source/opt/dead_branch_elim_pass.h
@@ -34,16 +34,16 @@
 
 // See optimizer.hpp for documentation.
 class DeadBranchElimPass : public MemPass {
-  using cbb_ptr = const ir::BasicBlock*;
+  using cbb_ptr = const opt::BasicBlock*;
 
  public:
   DeadBranchElimPass();
   const char* name() const override { return "eliminate-dead-branches"; }
-  Status Process(ir::IRContext* context) override;
+  Status Process(opt::IRContext* context) override;
 
-  ir::IRContext::Analysis GetPreservedAnalyses() override {
-    return ir::IRContext::kAnalysisDefUse |
-           ir::IRContext::kAnalysisInstrToBlockMapping;
+  opt::IRContext::Analysis GetPreservedAnalyses() override {
+    return opt::IRContext::kAnalysisDefUse |
+           opt::IRContext::kAnalysisInstrToBlockMapping;
   }
 
  private:
@@ -56,7 +56,7 @@
   bool GetConstInteger(uint32_t valId, uint32_t* value);
 
   // Add branch to |labelId| to end of block |bp|.
-  void AddBranch(uint32_t labelId, ir::BasicBlock* bp);
+  void AddBranch(uint32_t labelId, opt::BasicBlock* bp);
 
   // For function |func|, look for BranchConditionals with constant condition
   // and convert to a Branch to the indicated label. Delete resulting dead
@@ -64,21 +64,21 @@
   // invalid control flow.
   // TODO(greg-lunarg): Remove remaining constant conditional branches and dead
   // blocks.
-  bool EliminateDeadBranches(ir::Function* func);
+  bool EliminateDeadBranches(opt::Function* func);
 
   // Returns the basic block containing |id|.
   // Note: this pass only requires correct instruction block mappings for the
   // input. This pass does not preserve the block mapping, so it is not kept
   // up-to-date during processing.
-  ir::BasicBlock* GetParentBlock(uint32_t id);
+  opt::BasicBlock* GetParentBlock(uint32_t id);
 
   // Marks live blocks reachable from the entry of |func|. Simplifies constant
   // branches and switches as it proceeds, to limit the number of live blocks.
   // It is careful not to eliminate backedges even if they are dead, but the
   // header is live. Likewise, unreachable merge blocks named in live merge
   // instruction must be retained (though they may be clobbered).
-  bool MarkLiveBlocks(ir::Function* func,
-                      std::unordered_set<ir::BasicBlock*>* live_blocks);
+  bool MarkLiveBlocks(opt::Function* func,
+                      std::unordered_set<opt::BasicBlock*>* live_blocks);
 
   // Checks for unreachable merge and continue blocks with live headers; those
   // blocks must be retained. Continues are tracked separately so that a live
@@ -88,9 +88,9 @@
   // |unreachable_continues| maps the id of an unreachable continue target to
   // the header block that declares it.
   void MarkUnreachableStructuredTargets(
-      const std::unordered_set<ir::BasicBlock*>& live_blocks,
-      std::unordered_set<ir::BasicBlock*>* unreachable_merges,
-      std::unordered_map<ir::BasicBlock*, ir::BasicBlock*>*
+      const std::unordered_set<opt::BasicBlock*>& live_blocks,
+      std::unordered_set<opt::BasicBlock*>* unreachable_merges,
+      std::unordered_map<opt::BasicBlock*, opt::BasicBlock*>*
           unreachable_continues);
 
   // Fix phis in reachable blocks so that only live (or unremovable) incoming
@@ -106,9 +106,9 @@
   // |unreachable_continues| maps continue targets that cannot be reached to
   // merge instruction that declares them.
   bool FixPhiNodesInLiveBlocks(
-      ir::Function* func,
-      const std::unordered_set<ir::BasicBlock*>& live_blocks,
-      const std::unordered_map<ir::BasicBlock*, ir::BasicBlock*>&
+      opt::Function* func,
+      const std::unordered_set<opt::BasicBlock*>& live_blocks,
+      const std::unordered_map<opt::BasicBlock*, opt::BasicBlock*>&
           unreachable_continues);
 
   // Erases dead blocks. Any block captured in |unreachable_merges| or
@@ -123,13 +123,13 @@
   // |unreachable_continues| maps continue targets that cannot be reached to
   // corresponding header block that declares them.
   bool EraseDeadBlocks(
-      ir::Function* func,
-      const std::unordered_set<ir::BasicBlock*>& live_blocks,
-      const std::unordered_set<ir::BasicBlock*>& unreachable_merges,
-      const std::unordered_map<ir::BasicBlock*, ir::BasicBlock*>&
+      opt::Function* func,
+      const std::unordered_set<opt::BasicBlock*>& live_blocks,
+      const std::unordered_set<opt::BasicBlock*>& unreachable_merges,
+      const std::unordered_map<opt::BasicBlock*, opt::BasicBlock*>&
           unreachable_continues);
 
-  void Initialize(ir::IRContext* c);
+  void Initialize(opt::IRContext* c);
   Pass::Status ProcessImpl();
 };
 
diff --git a/source/opt/dead_insert_elim_pass.cpp b/source/opt/dead_insert_elim_pass.cpp
index ed0c7b8..6402018 100644
--- a/source/opt/dead_insert_elim_pass.cpp
+++ b/source/opt/dead_insert_elim_pass.cpp
@@ -38,7 +38,7 @@
 
 }  // anonymous namespace
 
-uint32_t DeadInsertElimPass::NumComponents(ir::Instruction* typeInst) {
+uint32_t DeadInsertElimPass::NumComponents(opt::Instruction* typeInst) {
   switch (typeInst->opcode()) {
     case SpvOpTypeVector: {
       return typeInst->GetSingleWordInOperand(kTypeVectorCountInIdx);
@@ -49,10 +49,10 @@
     case SpvOpTypeArray: {
       uint32_t lenId =
           typeInst->GetSingleWordInOperand(kTypeArrayLengthIdInIdx);
-      ir::Instruction* lenInst = get_def_use_mgr()->GetDef(lenId);
+      opt::Instruction* lenInst = get_def_use_mgr()->GetDef(lenId);
       if (lenInst->opcode() != SpvOpConstant) return 0;
       uint32_t lenTypeId = lenInst->type_id();
-      ir::Instruction* lenTypeInst = get_def_use_mgr()->GetDef(lenTypeId);
+      opt::Instruction* lenTypeInst = get_def_use_mgr()->GetDef(lenTypeId);
       // TODO(greg-lunarg): Support non-32-bit array length
       if (lenTypeInst->GetSingleWordInOperand(kTypeIntWidthInIdx) != 32)
         return 0;
@@ -66,10 +66,11 @@
 }
 
 void DeadInsertElimPass::MarkInsertChain(
-    ir::Instruction* insertChain, std::vector<uint32_t>* pExtIndices,
+    opt::Instruction* insertChain, std::vector<uint32_t>* pExtIndices,
     uint32_t extOffset, std::unordered_set<uint32_t>* visited_phis) {
   // Not currently optimizing array inserts.
-  ir::Instruction* typeInst = get_def_use_mgr()->GetDef(insertChain->type_id());
+  opt::Instruction* typeInst =
+      get_def_use_mgr()->GetDef(insertChain->type_id());
   if (typeInst->opcode() == SpvOpTypeArray) return;
   // Insert chains are only composed of inserts and phis
   if (insertChain->opcode() != SpvOpCompositeInsert &&
@@ -90,7 +91,7 @@
       return;
     }
   }
-  ir::Instruction* insInst = insertChain;
+  opt::Instruction* insInst = insertChain;
   while (insInst->opcode() == SpvOpCompositeInsert) {
     // If no extract indices, mark insert and inserted object (which might
     // also be an insert chain) and continue up the chain though the input
@@ -159,12 +160,12 @@
   std::sort(ids.begin(), ids.end());
   auto new_end = std::unique(ids.begin(), ids.end());
   for (auto id_iter = ids.begin(); id_iter != new_end; ++id_iter) {
-    ir::Instruction* pi = get_def_use_mgr()->GetDef(*id_iter);
+    opt::Instruction* pi = get_def_use_mgr()->GetDef(*id_iter);
     MarkInsertChain(pi, pExtIndices, extOffset, visited_phis);
   }
 }
 
-bool DeadInsertElimPass::EliminateDeadInserts(ir::Function* func) {
+bool DeadInsertElimPass::EliminateDeadInserts(opt::Function* func) {
   bool modified = false;
   bool lastmodified = true;
   // Each pass can delete dead instructions, thus potentially revealing
@@ -176,7 +177,7 @@
   return modified;
 }
 
-bool DeadInsertElimPass::EliminateDeadInsertsOnePass(ir::Function* func) {
+bool DeadInsertElimPass::EliminateDeadInsertsOnePass(opt::Function* func) {
   bool modified = false;
   liveInserts_.clear();
   visitedPhis_.clear();
@@ -185,7 +186,7 @@
     for (auto ii = bi->begin(); ii != bi->end(); ++ii) {
       // Only process Inserts and composite Phis
       SpvOp op = ii->opcode();
-      ir::Instruction* typeInst = get_def_use_mgr()->GetDef(ii->type_id());
+      opt::Instruction* typeInst = get_def_use_mgr()->GetDef(ii->type_id());
       if (op != SpvOpCompositeInsert &&
           (op != SpvOpPhi || !spvOpcodeIsComposite(typeInst->opcode())))
         continue;
@@ -200,7 +201,7 @@
         }
       }
       const uint32_t id = ii->result_id();
-      get_def_use_mgr()->ForEachUser(id, [&ii, this](ir::Instruction* user) {
+      get_def_use_mgr()->ForEachUser(id, [&ii, this](opt::Instruction* user) {
         switch (user->opcode()) {
           case SpvOpCompositeInsert:
           case SpvOpPhi:
@@ -227,7 +228,7 @@
     }
   }
   // Find and disconnect dead inserts
-  std::vector<ir::Instruction*> dead_instructions;
+  std::vector<opt::Instruction*> dead_instructions;
   for (auto bi = func->begin(); bi != func->end(); ++bi) {
     for (auto ii = bi->begin(); ii != bi->end(); ++ii) {
       if (ii->opcode() != SpvOpCompositeInsert) continue;
@@ -242,9 +243,9 @@
   }
   // DCE dead inserts
   while (!dead_instructions.empty()) {
-    ir::Instruction* inst = dead_instructions.back();
+    opt::Instruction* inst = dead_instructions.back();
     dead_instructions.pop_back();
-    DCEInst(inst, [&dead_instructions](ir::Instruction* other_inst) {
+    DCEInst(inst, [&dead_instructions](opt::Instruction* other_inst) {
       auto i = std::find(dead_instructions.begin(), dead_instructions.end(),
                          other_inst);
       if (i != dead_instructions.end()) {
@@ -255,13 +256,13 @@
   return modified;
 }
 
-void DeadInsertElimPass::Initialize(ir::IRContext* c) {
+void DeadInsertElimPass::Initialize(opt::IRContext* c) {
   InitializeProcessing(c);
 }
 
 Pass::Status DeadInsertElimPass::ProcessImpl() {
   // Process all entry point functions.
-  ProcessFunction pfn = [this](ir::Function* fp) {
+  ProcessFunction pfn = [this](opt::Function* fp) {
     return EliminateDeadInserts(fp);
   };
   bool modified = ProcessEntryPointCallTree(pfn, get_module());
@@ -270,7 +271,7 @@
 
 DeadInsertElimPass::DeadInsertElimPass() {}
 
-Pass::Status DeadInsertElimPass::Process(ir::IRContext* c) {
+Pass::Status DeadInsertElimPass::Process(opt::IRContext* c) {
   Initialize(c);
   return ProcessImpl();
 }
diff --git a/source/opt/dead_insert_elim_pass.h b/source/opt/dead_insert_elim_pass.h
index bc47473..7b75062 100644
--- a/source/opt/dead_insert_elim_pass.h
+++ b/source/opt/dead_insert_elim_pass.h
@@ -37,45 +37,45 @@
  public:
   DeadInsertElimPass();
   const char* name() const override { return "eliminate-dead-inserts"; }
-  Status Process(ir::IRContext*) override;
-  virtual ir::IRContext::Analysis GetPreservedAnalyses() override {
-    return ir::IRContext::kAnalysisDefUse |
-           ir::IRContext::kAnalysisInstrToBlockMapping |
-           ir::IRContext::kAnalysisDecorations |
-           ir::IRContext::kAnalysisCombinators | ir::IRContext::kAnalysisCFG |
-           ir::IRContext::kAnalysisDominatorAnalysis |
-           ir::IRContext::kAnalysisNameMap;
+  Status Process(opt::IRContext*) override;
+  virtual opt::IRContext::Analysis GetPreservedAnalyses() override {
+    return opt::IRContext::kAnalysisDefUse |
+           opt::IRContext::kAnalysisInstrToBlockMapping |
+           opt::IRContext::kAnalysisDecorations |
+           opt::IRContext::kAnalysisCombinators | opt::IRContext::kAnalysisCFG |
+           opt::IRContext::kAnalysisDominatorAnalysis |
+           opt::IRContext::kAnalysisNameMap;
   }
 
  private:
   // Return the number of subcomponents in the composite type |typeId|.
   // Return 0 if not a composite type or number of components is not a
   // 32-bit constant.
-  uint32_t NumComponents(ir::Instruction* typeInst);
+  uint32_t NumComponents(opt::Instruction* typeInst);
 
   // Mark all inserts in instruction chain ending at |insertChain| with
   // indices that intersect with extract indices |extIndices| starting with
   // index at |extOffset|. Chains are composed solely of Inserts and Phis.
   // Mark all inserts in chain if |extIndices| is nullptr.
-  void MarkInsertChain(ir::Instruction* insertChain,
+  void MarkInsertChain(opt::Instruction* insertChain,
                        std::vector<uint32_t>* extIndices, uint32_t extOffset,
                        std::unordered_set<uint32_t>* visited_phis);
 
   // Perform EliminateDeadInsertsOnePass(|func|) until no modification is
   // made. Return true if modified.
-  bool EliminateDeadInserts(ir::Function* func);
+  bool EliminateDeadInserts(opt::Function* func);
 
   // DCE all dead struct, matrix and vector inserts in |func|. An insert is
   // dead if the value it inserts is never used. Replace any reference to the
   // insert with its original composite. Return true if modified. Dead inserts
   // in dependence cycles are not currently eliminated. Dead inserts into
   // arrays are not currently eliminated.
-  bool EliminateDeadInsertsOnePass(ir::Function* func);
+  bool EliminateDeadInsertsOnePass(opt::Function* func);
 
   // Return true if all extensions in this module are allowed by this pass.
   bool AllExtensionsSupported() const;
 
-  void Initialize(ir::IRContext* c);
+  void Initialize(opt::IRContext* c);
   Pass::Status ProcessImpl();
 
   // Live inserts
diff --git a/source/opt/dead_variable_elimination.cpp b/source/opt/dead_variable_elimination.cpp
index 1fec3a4..3aee3e3 100644
--- a/source/opt/dead_variable_elimination.cpp
+++ b/source/opt/dead_variable_elimination.cpp
@@ -22,7 +22,7 @@
 
 // This optimization removes global variables that are not needed because they
 // are definitely not accessed.
-Pass::Status DeadVariableElimination::Process(ir::IRContext* c) {
+Pass::Status DeadVariableElimination::Process(opt::IRContext* c) {
   // The algorithm will compute the reference count for every global variable.
   // Anything with a reference count of 0 will then be deleted.  For variables
   // that might have references that are not explicit in this context, we use
@@ -45,7 +45,7 @@
     // else, so we must keep the variable around.
     get_decoration_mgr()->ForEachDecoration(
         result_id, SpvDecorationLinkageAttributes,
-        [&count](const ir::Instruction& linkage_instruction) {
+        [&count](const opt::Instruction& linkage_instruction) {
           uint32_t last_operand = linkage_instruction.NumOperands() - 1;
           if (linkage_instruction.GetSingleWordOperand(last_operand) ==
               SpvLinkageTypeExport) {
@@ -58,8 +58,8 @@
       // at the uses and count the number of real references.
       count = 0;
       get_def_use_mgr()->ForEachUser(
-          result_id, [&count](ir::Instruction* user) {
-            if (!ir::IsAnnotationInst(user->opcode()) &&
+          result_id, [&count](opt::Instruction* user) {
+            if (!opt::IsAnnotationInst(user->opcode()) &&
                 user->opcode() != SpvOpName) {
               ++count;
             }
@@ -83,14 +83,14 @@
 }
 
 void DeadVariableElimination::DeleteVariable(uint32_t result_id) {
-  ir::Instruction* inst = get_def_use_mgr()->GetDef(result_id);
+  opt::Instruction* inst = get_def_use_mgr()->GetDef(result_id);
   assert(inst->opcode() == SpvOpVariable &&
          "Should not be trying to delete anything other than an OpVariable.");
 
   // Look for an initializer that references another variable.  We need to know
   // if that variable can be deleted after the reference is removed.
   if (inst->NumOperands() == 4) {
-    ir::Instruction* initializer =
+    opt::Instruction* initializer =
         get_def_use_mgr()->GetDef(inst->GetSingleWordOperand(3));
 
     // TODO: Handle OpSpecConstantOP which might be defined in terms of other
diff --git a/source/opt/dead_variable_elimination.h b/source/opt/dead_variable_elimination.h
index f016e78..b5e0966 100644
--- a/source/opt/dead_variable_elimination.h
+++ b/source/opt/dead_variable_elimination.h
@@ -27,10 +27,10 @@
 class DeadVariableElimination : public MemPass {
  public:
   const char* name() const override { return "dead-variable-elimination"; }
-  Status Process(ir::IRContext* c) override;
+  Status Process(opt::IRContext* c) override;
 
-  ir::IRContext::Analysis GetPreservedAnalyses() override {
-    return ir::IRContext::kAnalysisDefUse;
+  opt::IRContext::Analysis GetPreservedAnalyses() override {
+    return opt::IRContext::kAnalysisDefUse;
   }
 
  private:
diff --git a/source/opt/decoration_manager.cpp b/source/opt/decoration_manager.cpp
index f382d78..9078c9f 100644
--- a/source/opt/decoration_manager.cpp
+++ b/source/opt/decoration_manager.cpp
@@ -25,35 +25,35 @@
 namespace analysis {
 
 void DecorationManager::RemoveDecorationsFrom(
-    uint32_t id, std::function<bool(const ir::Instruction&)> pred) {
+    uint32_t id, std::function<bool(const opt::Instruction&)> pred) {
   const auto ids_iter = id_to_decoration_insts_.find(id);
   if (ids_iter == id_to_decoration_insts_.end()) return;
 
   TargetData& decorations_info = ids_iter->second;
   auto context = module_->context();
-  std::vector<ir::Instruction*> insts_to_kill;
+  std::vector<opt::Instruction*> insts_to_kill;
   const bool is_group = !decorations_info.decorate_insts.empty();
 
   // Schedule all direct decorations for removal if instructed as such by
   // |pred|.
-  for (ir::Instruction* inst : decorations_info.direct_decorations)
+  for (opt::Instruction* inst : decorations_info.direct_decorations)
     if (pred(*inst)) insts_to_kill.push_back(inst);
 
   // For all groups being directly applied to |id|, remove |id| (and the
   // literal if |inst| is an OpGroupMemberDecorate) from the instruction
   // applying the group.
-  std::unordered_set<const ir::Instruction*> indirect_decorations_to_remove;
-  for (ir::Instruction* inst : decorations_info.indirect_decorations) {
+  std::unordered_set<const opt::Instruction*> indirect_decorations_to_remove;
+  for (opt::Instruction* inst : decorations_info.indirect_decorations) {
     assert(inst->opcode() == SpvOpGroupDecorate ||
            inst->opcode() == SpvOpGroupMemberDecorate);
 
-    std::vector<ir::Instruction*> group_decorations_to_keep;
+    std::vector<opt::Instruction*> group_decorations_to_keep;
     const uint32_t group_id = inst->GetSingleWordInOperand(0u);
     const auto group_iter = id_to_decoration_insts_.find(group_id);
     assert(group_iter != id_to_decoration_insts_.end() &&
            "Unknown decoration group");
     const auto& group_decorations = group_iter->second.direct_decorations;
-    for (ir::Instruction* decoration : group_decorations) {
+    for (opt::Instruction* decoration : group_decorations) {
       if (!pred(*decoration)) group_decorations_to_keep.push_back(decoration);
     }
 
@@ -97,9 +97,9 @@
     // If only some of the decorations should be kept, clone them and apply
     // them directly to |id|.
     if (!group_decorations_to_keep.empty()) {
-      for (ir::Instruction* decoration : group_decorations_to_keep) {
+      for (opt::Instruction* decoration : group_decorations_to_keep) {
         // simply clone decoration and change |group_id| to |id|
-        std::unique_ptr<ir::Instruction> new_inst(
+        std::unique_ptr<opt::Instruction> new_inst(
             decoration->Clone(module_->context()));
         new_inst->SetInOperand(0, {id});
         module_->AddAnnotationInst(std::move(new_inst));
@@ -113,22 +113,22 @@
   indirect_decorations.erase(
       std::remove_if(
           indirect_decorations.begin(), indirect_decorations.end(),
-          [&indirect_decorations_to_remove](const ir::Instruction* inst) {
+          [&indirect_decorations_to_remove](const opt::Instruction* inst) {
             return indirect_decorations_to_remove.count(inst);
           }),
       indirect_decorations.end());
 
-  for (ir::Instruction* inst : insts_to_kill) context->KillInst(inst);
+  for (opt::Instruction* inst : insts_to_kill) context->KillInst(inst);
   insts_to_kill.clear();
 
   // Schedule all instructions applying the group for removal if this group no
   // longer applies decorations, either directly or indirectly.
   if (is_group && decorations_info.direct_decorations.empty() &&
       decorations_info.indirect_decorations.empty()) {
-    for (ir::Instruction* inst : decorations_info.decorate_insts)
+    for (opt::Instruction* inst : decorations_info.decorate_insts)
       insts_to_kill.push_back(inst);
   }
-  for (ir::Instruction* inst : insts_to_kill) context->KillInst(inst);
+  for (opt::Instruction* inst : insts_to_kill) context->KillInst(inst);
 
   if (decorations_info.direct_decorations.empty() &&
       decorations_info.indirect_decorations.empty() &&
@@ -140,20 +140,20 @@
   }
 }
 
-std::vector<ir::Instruction*> DecorationManager::GetDecorationsFor(
+std::vector<opt::Instruction*> DecorationManager::GetDecorationsFor(
     uint32_t id, bool include_linkage) {
-  return InternalGetDecorationsFor<ir::Instruction*>(id, include_linkage);
+  return InternalGetDecorationsFor<opt::Instruction*>(id, include_linkage);
 }
 
-std::vector<const ir::Instruction*> DecorationManager::GetDecorationsFor(
+std::vector<const opt::Instruction*> DecorationManager::GetDecorationsFor(
     uint32_t id, bool include_linkage) const {
   return const_cast<DecorationManager*>(this)
-      ->InternalGetDecorationsFor<const ir::Instruction*>(id, include_linkage);
+      ->InternalGetDecorationsFor<const opt::Instruction*>(id, include_linkage);
 }
 
 bool DecorationManager::HaveTheSameDecorations(uint32_t id1,
                                                uint32_t id2) const {
-  using InstructionList = std::vector<const ir::Instruction*>;
+  using InstructionList = std::vector<const opt::Instruction*>;
   using DecorationSet = std::set<std::u32string>;
 
   const InstructionList decorations_for1 = GetDecorationsFor(id1, false);
@@ -167,7 +167,7 @@
       [](const InstructionList& decoration_list, DecorationSet* decorate_set,
          DecorationSet* decorate_id_set, DecorationSet* decorate_string_set,
          DecorationSet* member_decorate_set) {
-        for (const ir::Instruction* inst : decoration_list) {
+        for (const opt::Instruction* inst : decoration_list) {
           std::u32string decoration_payload;
           // Ignore the opcode and the target as we do not want them to be
           // compared.
@@ -223,8 +223,8 @@
 // TODO(pierremoreau): If OpDecorateId is referencing an OpConstant, one could
 //                     check that the constants are the same rather than just
 //                     looking at the constant ID.
-bool DecorationManager::AreDecorationsTheSame(const ir::Instruction* inst1,
-                                              const ir::Instruction* inst2,
+bool DecorationManager::AreDecorationsTheSame(const opt::Instruction* inst1,
+                                              const opt::Instruction* inst2,
                                               bool ignore_target) const {
   switch (inst1->opcode()) {
     case SpvOpDecorate:
@@ -250,11 +250,11 @@
   if (!module_) return;
 
   // For each group and instruction, collect all their decoration instructions.
-  for (ir::Instruction& inst : module_->annotations()) {
+  for (opt::Instruction& inst : module_->annotations()) {
     AddDecoration(&inst);
   }
 }
-void DecorationManager::AddDecoration(ir::Instruction* inst) {
+void DecorationManager::AddDecoration(opt::Instruction* inst) {
   switch (inst->opcode()) {
     case SpvOpDecorate:
     case SpvOpDecorateId:
@@ -295,8 +295,8 @@
 
   const auto process_direct_decorations =
       [include_linkage,
-       &decorations](const std::vector<ir::Instruction*>& direct_decorations) {
-        for (ir::Instruction* inst : direct_decorations) {
+       &decorations](const std::vector<opt::Instruction*>& direct_decorations) {
+        for (opt::Instruction* inst : direct_decorations) {
           const bool is_linkage = inst->opcode() == SpvOpDecorate &&
                                   inst->GetSingleWordInOperand(1u) ==
                                       SpvDecorationLinkageAttributes;
@@ -308,7 +308,7 @@
   process_direct_decorations(ids_iter->second.direct_decorations);
 
   // Process the decorations of all groups applied to |id|.
-  for (const ir::Instruction* inst : target_data.indirect_decorations) {
+  for (const opt::Instruction* inst : target_data.indirect_decorations) {
     const uint32_t group_id = inst->GetSingleWordInOperand(0u);
     const auto group_iter = id_to_decoration_insts_.find(group_id);
     assert(group_iter != id_to_decoration_insts_.end() && "Unknown group ID");
@@ -320,8 +320,8 @@
 
 bool DecorationManager::WhileEachDecoration(
     uint32_t id, uint32_t decoration,
-    std::function<bool(const ir::Instruction&)> f) {
-  for (const ir::Instruction* inst : GetDecorationsFor(id, true)) {
+    std::function<bool(const opt::Instruction&)> f) {
+  for (const opt::Instruction* inst : GetDecorationsFor(id, true)) {
     switch (inst->opcode()) {
       case SpvOpMemberDecorate:
         if (inst->GetSingleWordInOperand(2) == decoration) {
@@ -344,8 +344,8 @@
 
 void DecorationManager::ForEachDecoration(
     uint32_t id, uint32_t decoration,
-    std::function<void(const ir::Instruction&)> f) {
-  WhileEachDecoration(id, decoration, [&f](const ir::Instruction& inst) {
+    std::function<void(const opt::Instruction&)> f) {
+  WhileEachDecoration(id, decoration, [&f](const opt::Instruction& inst) {
     f(inst);
     return true;
   });
@@ -355,9 +355,9 @@
   const auto decoration_list = id_to_decoration_insts_.find(from);
   if (decoration_list == id_to_decoration_insts_.end()) return;
   auto context = module_->context();
-  for (ir::Instruction* inst : decoration_list->second.direct_decorations) {
+  for (opt::Instruction* inst : decoration_list->second.direct_decorations) {
     // simply clone decoration and change |target-id| to |to|
-    std::unique_ptr<ir::Instruction> new_inst(inst->Clone(module_->context()));
+    std::unique_ptr<opt::Instruction> new_inst(inst->Clone(module_->context()));
     new_inst->SetInOperand(0, {to});
     module_->AddAnnotationInst(std::move(new_inst));
     auto decoration_iter = --module_->annotation_end();
@@ -365,15 +365,15 @@
   }
   // We need to copy the list of instructions as ForgetUses and AnalyzeUses are
   // going to modify it.
-  std::vector<ir::Instruction*> indirect_decorations =
+  std::vector<opt::Instruction*> indirect_decorations =
       decoration_list->second.indirect_decorations;
-  for (ir::Instruction* inst : indirect_decorations) {
+  for (opt::Instruction* inst : indirect_decorations) {
     switch (inst->opcode()) {
       case SpvOpGroupDecorate:
         context->ForgetUses(inst);
         // add |to| to list of decorated id's
         inst->AddOperand(
-            ir::Operand(spv_operand_type_t::SPV_OPERAND_TYPE_ID, {to}));
+            opt::Operand(spv_operand_type_t::SPV_OPERAND_TYPE_ID, {to}));
         context->AnalyzeUses(inst);
         break;
       case SpvOpGroupMemberDecorate: {
@@ -381,10 +381,10 @@
         // for each (id == from), add (to, literal) as operands
         const uint32_t num_operands = inst->NumOperands();
         for (uint32_t i = 1; i < num_operands; i += 2) {
-          ir::Operand op = inst->GetOperand(i);
+          opt::Operand op = inst->GetOperand(i);
           if (op.words[0] == from) {  // add new pair of operands: (to, literal)
             inst->AddOperand(
-                ir::Operand(spv_operand_type_t::SPV_OPERAND_TYPE_ID, {to}));
+                opt::Operand(spv_operand_type_t::SPV_OPERAND_TYPE_ID, {to}));
             op = inst->GetOperand(i + 1);
             inst->AddOperand(std::move(op));
           }
@@ -398,8 +398,8 @@
   }
 }
 
-void DecorationManager::RemoveDecoration(ir::Instruction* inst) {
-  const auto remove_from_container = [inst](std::vector<ir::Instruction*>& v) {
+void DecorationManager::RemoveDecoration(opt::Instruction* inst) {
+  const auto remove_from_container = [inst](std::vector<opt::Instruction*>& v) {
     v.erase(std::remove(v.begin(), v.end(), inst), v.end());
   };
 
diff --git a/source/opt/decoration_manager.h b/source/opt/decoration_manager.h
index 40ba13e..3ecda8f 100644
--- a/source/opt/decoration_manager.h
+++ b/source/opt/decoration_manager.h
@@ -27,11 +27,11 @@
 namespace opt {
 namespace analysis {
 
-// A class for analyzing and managing decorations in an ir::Module.
+// A class for analyzing and managing decorations in an opt::Module.
 class DecorationManager {
  public:
   // Constructs a decoration manager from the given |module|
-  explicit DecorationManager(ir::Module* module) : module_(module) {
+  explicit DecorationManager(opt::Module* module) : module_(module) {
     AnalyzeDecorations();
   }
   DecorationManager() = delete;
@@ -42,22 +42,22 @@
   // removed if they have no targets left, and OpDecorationGroup will be
   // removed if the group is not applied to anyone and contains no decorations.
   void RemoveDecorationsFrom(uint32_t id,
-                             std::function<bool(const ir::Instruction&)> pred =
-                                 [](const ir::Instruction&) { return true; });
+                             std::function<bool(const opt::Instruction&)> pred =
+                                 [](const opt::Instruction&) { return true; });
 
   // Removes all decorations from the result id of |inst|.
   //
   // NOTE: This is only meant to be called from ir_context, as only metadata
   // will be removed, and no actual instruction.
-  void RemoveDecoration(ir::Instruction* inst);
+  void RemoveDecoration(opt::Instruction* inst);
 
   // Returns a vector of all decorations affecting |id|. If a group is applied
   // to |id|, the decorations of that group are returned rather than the group
   // decoration instruction. If |include_linkage| is not set, linkage
   // decorations won't be returned.
-  std::vector<ir::Instruction*> GetDecorationsFor(uint32_t id,
-                                                  bool include_linkage);
-  std::vector<const ir::Instruction*> GetDecorationsFor(
+  std::vector<opt::Instruction*> GetDecorationsFor(uint32_t id,
+                                                   bool include_linkage);
+  std::vector<const opt::Instruction*> GetDecorationsFor(
       uint32_t id, bool include_linkage) const;
   // Returns whether two IDs have the same decorations. Two SpvOpGroupDecorate
   // instructions that apply the same decorations but to different IDs, still
@@ -69,22 +69,22 @@
   //
   // This is only valid for OpDecorate, OpMemberDecorate and OpDecorateId; it
   // will return false for other opcodes.
-  bool AreDecorationsTheSame(const ir::Instruction* inst1,
-                             const ir::Instruction* inst2,
+  bool AreDecorationsTheSame(const opt::Instruction* inst1,
+                             const opt::Instruction* inst2,
                              bool ignore_target) const;
 
   // |f| is run on each decoration instruction for |id| with decoration
   // |decoration|. Processed are all decorations which target |id| either
   // directly or indirectly by Decoration Groups.
   void ForEachDecoration(uint32_t id, uint32_t decoration,
-                         std::function<void(const ir::Instruction&)> f);
+                         std::function<void(const opt::Instruction&)> f);
 
   // |f| is run on each decoration instruction for |id| with decoration
   // |decoration|. Processes all decoration which target |id| either directly or
   // indirectly through decoration groups. If |f| returns false, iteration is
   // terminated and this function returns false.
   bool WhileEachDecoration(uint32_t id, uint32_t decoration,
-                           std::function<bool(const ir::Instruction&)> f);
+                           std::function<bool(const opt::Instruction&)> f);
 
   // Clone all decorations from one id |from|.
   // The cloned decorations are assigned to the given id |to| and are
@@ -93,7 +93,7 @@
   void CloneDecorations(uint32_t from, uint32_t to);
 
   // Informs the decoration manager of a new decoration that it needs to track.
-  void AddDecoration(ir::Instruction* inst);
+  void AddDecoration(opt::Instruction* inst);
 
  private:
   // Analyzes the defs and uses in the given |module| and populates data
@@ -105,19 +105,19 @@
 
   // Tracks decoration information of an ID.
   struct TargetData {
-    std::vector<ir::Instruction*> direct_decorations;    // All decorate
-                                                         // instructions applied
-                                                         // to the tracked ID.
-    std::vector<ir::Instruction*> indirect_decorations;  // All instructions
-                                                         // applying a group to
-                                                         // the tracked ID.
-    std::vector<ir::Instruction*> decorate_insts;  // All decorate instructions
-                                                   // applying the decorations
-                                                   // of the tracked ID to
-                                                   // targets.
-                                                   // It is empty if the
-                                                   // tracked ID is not a
-                                                   // group.
+    std::vector<opt::Instruction*> direct_decorations;  // All decorate
+                                                        // instructions applied
+                                                        // to the tracked ID.
+    std::vector<opt::Instruction*> indirect_decorations;  // All instructions
+                                                          // applying a group to
+                                                          // the tracked ID.
+    std::vector<opt::Instruction*> decorate_insts;  // All decorate instructions
+                                                    // applying the decorations
+                                                    // of the tracked ID to
+                                                    // targets.
+                                                    // It is empty if the
+                                                    // tracked ID is not a
+                                                    // group.
   };
 
   // Mapping from ids to the instructions applying a decoration to those ids.
@@ -127,7 +127,7 @@
   // SpvOpMemberGroupDecorate).
   std::unordered_map<uint32_t, TargetData> id_to_decoration_insts_;
   // The enclosing module.
-  ir::Module* module_;
+  opt::Module* module_;
 };
 
 }  // namespace analysis
diff --git a/source/opt/def_use_manager.cpp b/source/opt/def_use_manager.cpp
index 6e83b41..140bfb7 100644
--- a/source/opt/def_use_manager.cpp
+++ b/source/opt/def_use_manager.cpp
@@ -23,7 +23,7 @@
 namespace opt {
 namespace analysis {
 
-void DefUseManager::AnalyzeInstDef(ir::Instruction* inst) {
+void DefUseManager::AnalyzeInstDef(opt::Instruction* inst) {
   const uint32_t def_id = inst->result_id();
   if (def_id != 0) {
     auto iter = id_to_def_.find(def_id);
@@ -38,7 +38,7 @@
   }
 }
 
-void DefUseManager::AnalyzeInstUse(ir::Instruction* inst) {
+void DefUseManager::AnalyzeInstUse(opt::Instruction* inst) {
   // Create entry for the given instruction. Note that the instruction may
   // not have any in-operands. In such cases, we still need a entry for those
   // instructions so this manager knows it has seen the instruction later.
@@ -57,7 +57,7 @@
       case SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID:
       case SPV_OPERAND_TYPE_SCOPE_ID: {
         uint32_t use_id = inst->GetSingleWordOperand(i);
-        ir::Instruction* def = GetDef(use_id);
+        opt::Instruction* def = GetDef(use_id);
         assert(def && "Definition is not registered.");
         id_to_users_.insert(UserEntry(def, inst));
         used_ids->push_back(use_id);
@@ -68,12 +68,12 @@
   }
 }
 
-void DefUseManager::AnalyzeInstDefUse(ir::Instruction* inst) {
+void DefUseManager::AnalyzeInstDefUse(opt::Instruction* inst) {
   AnalyzeInstDef(inst);
   AnalyzeInstUse(inst);
 }
 
-void DefUseManager::UpdateDefUse(ir::Instruction* inst) {
+void DefUseManager::UpdateDefUse(opt::Instruction* inst) {
   const uint32_t def_id = inst->result_id();
   if (def_id != 0) {
     auto iter = id_to_def_.find(def_id);
@@ -84,38 +84,38 @@
   AnalyzeInstUse(inst);
 }
 
-ir::Instruction* DefUseManager::GetDef(uint32_t id) {
+opt::Instruction* DefUseManager::GetDef(uint32_t id) {
   auto iter = id_to_def_.find(id);
   if (iter == id_to_def_.end()) return nullptr;
   return iter->second;
 }
 
-const ir::Instruction* DefUseManager::GetDef(uint32_t id) const {
+const opt::Instruction* DefUseManager::GetDef(uint32_t id) const {
   const auto iter = id_to_def_.find(id);
   if (iter == id_to_def_.end()) return nullptr;
   return iter->second;
 }
 
 DefUseManager::IdToUsersMap::const_iterator DefUseManager::UsersBegin(
-    const ir::Instruction* def) const {
+    const opt::Instruction* def) const {
   return id_to_users_.lower_bound(
-      UserEntry(const_cast<ir::Instruction*>(def), nullptr));
+      UserEntry(const_cast<opt::Instruction*>(def), nullptr));
 }
 
 bool DefUseManager::UsersNotEnd(const IdToUsersMap::const_iterator& iter,
                                 const IdToUsersMap::const_iterator& cached_end,
-                                const ir::Instruction* inst) const {
+                                const opt::Instruction* inst) const {
   return (iter != cached_end && iter->first == inst);
 }
 
 bool DefUseManager::UsersNotEnd(const IdToUsersMap::const_iterator& iter,
-                                const ir::Instruction* inst) const {
+                                const opt::Instruction* inst) const {
   return UsersNotEnd(iter, id_to_users_.end(), inst);
 }
 
 bool DefUseManager::WhileEachUser(
-    const ir::Instruction* def,
-    const std::function<bool(ir::Instruction*)>& f) const {
+    const opt::Instruction* def,
+    const std::function<bool(opt::Instruction*)>& f) const {
   // Ensure that |def| has been registered.
   assert(def && (!def->HasResultId() || def == GetDef(def->result_id())) &&
          "Definition is not registered.");
@@ -129,27 +129,27 @@
 }
 
 bool DefUseManager::WhileEachUser(
-    uint32_t id, const std::function<bool(ir::Instruction*)>& f) const {
+    uint32_t id, const std::function<bool(opt::Instruction*)>& f) const {
   return WhileEachUser(GetDef(id), f);
 }
 
 void DefUseManager::ForEachUser(
-    const ir::Instruction* def,
-    const std::function<void(ir::Instruction*)>& f) const {
-  WhileEachUser(def, [&f](ir::Instruction* user) {
+    const opt::Instruction* def,
+    const std::function<void(opt::Instruction*)>& f) const {
+  WhileEachUser(def, [&f](opt::Instruction* user) {
     f(user);
     return true;
   });
 }
 
 void DefUseManager::ForEachUser(
-    uint32_t id, const std::function<void(ir::Instruction*)>& f) const {
+    uint32_t id, const std::function<void(opt::Instruction*)>& f) const {
   ForEachUser(GetDef(id), f);
 }
 
 bool DefUseManager::WhileEachUse(
-    const ir::Instruction* def,
-    const std::function<bool(ir::Instruction*, uint32_t)>& f) const {
+    const opt::Instruction* def,
+    const std::function<bool(opt::Instruction*, uint32_t)>& f) const {
   // Ensure that |def| has been registered.
   assert(def && (!def->HasResultId() || def == GetDef(def->result_id())) &&
          "Definition is not registered.");
@@ -157,9 +157,9 @@
 
   auto end = id_to_users_.end();
   for (auto iter = UsersBegin(def); UsersNotEnd(iter, end, def); ++iter) {
-    ir::Instruction* user = iter->second;
+    opt::Instruction* user = iter->second;
     for (uint32_t idx = 0; idx != user->NumOperands(); ++idx) {
-      const ir::Operand& op = user->GetOperand(idx);
+      const opt::Operand& op = user->GetOperand(idx);
       if (op.type != SPV_OPERAND_TYPE_RESULT_ID && spvIsIdType(op.type)) {
         if (def->result_id() == op.words[0]) {
           if (!f(user, idx)) return false;
@@ -172,14 +172,14 @@
 
 bool DefUseManager::WhileEachUse(
     uint32_t id,
-    const std::function<bool(ir::Instruction*, uint32_t)>& f) const {
+    const std::function<bool(opt::Instruction*, uint32_t)>& f) const {
   return WhileEachUse(GetDef(id), f);
 }
 
 void DefUseManager::ForEachUse(
-    const ir::Instruction* def,
-    const std::function<void(ir::Instruction*, uint32_t)>& f) const {
-  WhileEachUse(def, [&f](ir::Instruction* user, uint32_t index) {
+    const opt::Instruction* def,
+    const std::function<void(opt::Instruction*, uint32_t)>& f) const {
+  WhileEachUse(def, [&f](opt::Instruction* user, uint32_t index) {
     f(user, index);
     return true;
   });
@@ -187,13 +187,13 @@
 
 void DefUseManager::ForEachUse(
     uint32_t id,
-    const std::function<void(ir::Instruction*, uint32_t)>& f) const {
+    const std::function<void(opt::Instruction*, uint32_t)>& f) const {
   ForEachUse(GetDef(id), f);
 }
 
-uint32_t DefUseManager::NumUsers(const ir::Instruction* def) const {
+uint32_t DefUseManager::NumUsers(const opt::Instruction* def) const {
   uint32_t count = 0;
-  ForEachUser(def, [&count](ir::Instruction*) { ++count; });
+  ForEachUser(def, [&count](opt::Instruction*) { ++count; });
   return count;
 }
 
@@ -201,9 +201,9 @@
   return NumUsers(GetDef(id));
 }
 
-uint32_t DefUseManager::NumUses(const ir::Instruction* def) const {
+uint32_t DefUseManager::NumUses(const opt::Instruction* def) const {
   uint32_t count = 0;
-  ForEachUse(def, [&count](ir::Instruction*, uint32_t) { ++count; });
+  ForEachUse(def, [&count](opt::Instruction*, uint32_t) { ++count; });
   return count;
 }
 
@@ -211,20 +211,21 @@
   return NumUses(GetDef(id));
 }
 
-std::vector<ir::Instruction*> DefUseManager::GetAnnotations(uint32_t id) const {
-  std::vector<ir::Instruction*> annos;
-  const ir::Instruction* def = GetDef(id);
+std::vector<opt::Instruction*> DefUseManager::GetAnnotations(
+    uint32_t id) const {
+  std::vector<opt::Instruction*> annos;
+  const opt::Instruction* def = GetDef(id);
   if (!def) return annos;
 
-  ForEachUser(def, [&annos](ir::Instruction* user) {
-    if (ir::IsAnnotationInst(user->opcode())) {
+  ForEachUser(def, [&annos](opt::Instruction* user) {
+    if (opt::IsAnnotationInst(user->opcode())) {
       annos.push_back(user);
     }
   });
   return annos;
 }
 
-void DefUseManager::AnalyzeDefUse(ir::Module* module) {
+void DefUseManager::AnalyzeDefUse(opt::Module* module) {
   if (!module) return;
   // Analyze all the defs before any uses to catch forward references.
   module->ForEachInst(
@@ -233,7 +234,7 @@
       std::bind(&DefUseManager::AnalyzeInstUse, this, std::placeholders::_1));
 }
 
-void DefUseManager::ClearInst(ir::Instruction* inst) {
+void DefUseManager::ClearInst(opt::Instruction* inst) {
   auto iter = inst_to_used_ids_.find(inst);
   if (iter != inst_to_used_ids_.end()) {
     EraseUseRecordsOfOperandIds(inst);
@@ -250,14 +251,14 @@
   }
 }
 
-void DefUseManager::EraseUseRecordsOfOperandIds(const ir::Instruction* inst) {
+void DefUseManager::EraseUseRecordsOfOperandIds(const opt::Instruction* inst) {
   // Go through all ids used by this instruction, remove this instruction's
   // uses of them.
   auto iter = inst_to_used_ids_.find(inst);
   if (iter != inst_to_used_ids_.end()) {
     for (auto use_id : iter->second) {
       id_to_users_.erase(
-          UserEntry(GetDef(use_id), const_cast<ir::Instruction*>(inst)));
+          UserEntry(GetDef(use_id), const_cast<opt::Instruction*>(inst)));
     }
     inst_to_used_ids_.erase(inst);
   }
diff --git a/source/opt/def_use_manager.h b/source/opt/def_use_manager.h
index 2061703..9fe286d 100644
--- a/source/opt/def_use_manager.h
+++ b/source/opt/def_use_manager.h
@@ -33,7 +33,7 @@
 // * Ids referenced in OpSectionMerge & OpLoopMerge are considered as use.
 // * Ids referenced in OpPhi's in operands are considered as use.
 struct Use {
-  ir::Instruction* inst;   // Instruction using the id.
+  opt::Instruction* inst;  // Instruction using the id.
   uint32_t operand_index;  // logical operand index of the id use. This can be
                            // the index of result type id.
 };
@@ -58,7 +58,7 @@
 // Definition should never be null. User can be null, however, such an entry
 // should be used only for searching (e.g. all users of a particular definition)
 // and never stored in a container.
-using UserEntry = std::pair<ir::Instruction*, ir::Instruction*>;
+using UserEntry = std::pair<opt::Instruction*, opt::Instruction*>;
 
 // Orders UserEntry for use in associative containers (i.e. less than ordering).
 //
@@ -92,17 +92,17 @@
   }
 };
 
-// A class for analyzing and managing defs and uses in an ir::Module.
+// A class for analyzing and managing defs and uses in an opt::Module.
 class DefUseManager {
  public:
-  using IdToDefMap = std::unordered_map<uint32_t, ir::Instruction*>;
+  using IdToDefMap = std::unordered_map<uint32_t, opt::Instruction*>;
   using IdToUsersMap = std::set<UserEntry, UserEntryLess>;
 
   // Constructs a def-use manager from the given |module|. All internal messages
   // will be communicated to the outside via the given message |consumer|. This
   // instance only keeps a reference to the |consumer|, so the |consumer| should
   // outlive this instance.
-  DefUseManager(ir::Module* module) { AnalyzeDefUse(module); }
+  DefUseManager(opt::Module* module) { AnalyzeDefUse(module); }
 
   DefUseManager(const DefUseManager&) = delete;
   DefUseManager(DefUseManager&&) = delete;
@@ -110,20 +110,20 @@
   DefUseManager& operator=(DefUseManager&&) = delete;
 
   // Analyzes the defs in the given |inst|.
-  void AnalyzeInstDef(ir::Instruction* inst);
+  void AnalyzeInstDef(opt::Instruction* inst);
 
   // Analyzes the uses in the given |inst|.
   //
   // All operands of |inst| must be analyzed as defs.
-  void AnalyzeInstUse(ir::Instruction* inst);
+  void AnalyzeInstUse(opt::Instruction* inst);
 
   // Analyzes the defs and uses in the given |inst|.
-  void AnalyzeInstDefUse(ir::Instruction* inst);
+  void AnalyzeInstDefUse(opt::Instruction* inst);
 
   // Returns the def instruction for the given |id|. If there is no instruction
   // defining |id|, returns nullptr.
-  ir::Instruction* GetDef(uint32_t id);
-  const ir::Instruction* GetDef(uint32_t id) const;
+  opt::Instruction* GetDef(uint32_t id);
+  const opt::Instruction* GetDef(uint32_t id) const;
 
   // Runs the given function |f| on each unique user instruction of |def| (or
   // |id|).
@@ -132,10 +132,10 @@
   // only be visited once.
   //
   // |def| (or |id|) must be registered as a definition.
-  void ForEachUser(const ir::Instruction* def,
-                   const std::function<void(ir::Instruction*)>& f) const;
+  void ForEachUser(const opt::Instruction* def,
+                   const std::function<void(opt::Instruction*)>& f) const;
   void ForEachUser(uint32_t id,
-                   const std::function<void(ir::Instruction*)>& f) const;
+                   const std::function<void(opt::Instruction*)>& f) const;
 
   // Runs the given function |f| on each unique user instruction of |def| (or
   // |id|). If |f| returns false, iteration is terminated and this function
@@ -145,10 +145,10 @@
   // be only be visited once.
   //
   // |def| (or |id|) must be registered as a definition.
-  bool WhileEachUser(const ir::Instruction* def,
-                     const std::function<bool(ir::Instruction*)>& f) const;
+  bool WhileEachUser(const opt::Instruction* def,
+                     const std::function<bool(opt::Instruction*)>& f) const;
   bool WhileEachUser(uint32_t id,
-                     const std::function<bool(ir::Instruction*)>& f) const;
+                     const std::function<bool(opt::Instruction*)>& f) const;
 
   // Runs the given function |f| on each unique use of |def| (or
   // |id|).
@@ -157,11 +157,11 @@
   // visited separately.
   //
   // |def| (or |id|) must be registered as a definition.
-  void ForEachUse(const ir::Instruction* def,
-                  const std::function<void(ir::Instruction*,
+  void ForEachUse(const opt::Instruction* def,
+                  const std::function<void(opt::Instruction*,
                                            uint32_t operand_index)>& f) const;
   void ForEachUse(uint32_t id,
-                  const std::function<void(ir::Instruction*,
+                  const std::function<void(opt::Instruction*,
                                            uint32_t operand_index)>& f) const;
 
   // Runs the given function |f| on each unique use of |def| (or
@@ -172,19 +172,19 @@
   // visited separately.
   //
   // |def| (or |id|) must be registered as a definition.
-  bool WhileEachUse(const ir::Instruction* def,
-                    const std::function<bool(ir::Instruction*,
+  bool WhileEachUse(const opt::Instruction* def,
+                    const std::function<bool(opt::Instruction*,
                                              uint32_t operand_index)>& f) const;
   bool WhileEachUse(uint32_t id,
-                    const std::function<bool(ir::Instruction*,
+                    const std::function<bool(opt::Instruction*,
                                              uint32_t operand_index)>& f) const;
 
   // Returns the number of users of |def| (or |id|).
-  uint32_t NumUsers(const ir::Instruction* def) const;
+  uint32_t NumUsers(const opt::Instruction* def) const;
   uint32_t NumUsers(uint32_t id) const;
 
   // Returns the number of uses of |def| (or |id|).
-  uint32_t NumUses(const ir::Instruction* def) const;
+  uint32_t NumUses(const opt::Instruction* def) const;
   uint32_t NumUses(uint32_t id) const;
 
   // Returns the annotation instrunctions which are a direct use of the given
@@ -192,7 +192,7 @@
   // group(s), this function will just return the OpGroupDecorate
   // instrcution(s) which refer to the given id as an operand. The OpDecorate
   // instructions which decorate the decoration group will not be returned.
-  std::vector<ir::Instruction*> GetAnnotations(uint32_t id) const;
+  std::vector<opt::Instruction*> GetAnnotations(uint32_t id) const;
 
   // Returns the map from ids to their def instructions.
   const IdToDefMap& id_to_defs() const { return id_to_def_; }
@@ -204,10 +204,10 @@
   // record: |inst| uses an |id|, will be removed from the use records of |id|.
   // If |inst| defines an result id, the use record of this result id will also
   // be removed. Does nothing if |inst| was not analyzed before.
-  void ClearInst(ir::Instruction* inst);
+  void ClearInst(opt::Instruction* inst);
 
   // Erases the records that a given instruction uses its operand ids.
-  void EraseUseRecordsOfOperandIds(const ir::Instruction* inst);
+  void EraseUseRecordsOfOperandIds(const opt::Instruction* inst);
 
   friend bool operator==(const DefUseManager&, const DefUseManager&);
   friend bool operator!=(const DefUseManager& lhs, const DefUseManager& rhs) {
@@ -216,15 +216,15 @@
 
   // If |inst| has not already been analysed, then analyses its defintion and
   // uses.
-  void UpdateDefUse(ir::Instruction* inst);
+  void UpdateDefUse(opt::Instruction* inst);
 
  private:
   using InstToUsedIdsMap =
-      std::unordered_map<const ir::Instruction*, std::vector<uint32_t>>;
+      std::unordered_map<const opt::Instruction*, std::vector<uint32_t>>;
 
   // Returns the first location that {|def|, nullptr} could be inserted into the
   // users map without violating ordering.
-  IdToUsersMap::const_iterator UsersBegin(const ir::Instruction* def) const;
+  IdToUsersMap::const_iterator UsersBegin(const opt::Instruction* def) const;
 
   // Returns true if |iter| has not reached the end of |def|'s users.
   //
@@ -233,14 +233,14 @@
   // against |cached_end| for validity before other checks. This allows caching
   // the map's end which is a performance improvement on some platforms.
   bool UsersNotEnd(const IdToUsersMap::const_iterator& iter,
-                   const ir::Instruction* def) const;
+                   const opt::Instruction* def) const;
   bool UsersNotEnd(const IdToUsersMap::const_iterator& iter,
                    const IdToUsersMap::const_iterator& cached_end,
-                   const ir::Instruction* def) const;
+                   const opt::Instruction* def) const;
 
   // Analyzes the defs and uses in the given |module| and populates data
   // structures in this class. Does nothing if |module| is nullptr.
-  void AnalyzeDefUse(ir::Module* module);
+  void AnalyzeDefUse(opt::Module* module);
 
   IdToDefMap id_to_def_;      // Mapping from ids to their definitions
   IdToUsersMap id_to_users_;  // Mapping from ids to their users
diff --git a/source/opt/dominator_analysis.cpp b/source/opt/dominator_analysis.cpp
index 7ed4f7f..709e4cb 100644
--- a/source/opt/dominator_analysis.cpp
+++ b/source/opt/dominator_analysis.cpp
@@ -21,12 +21,12 @@
 namespace spvtools {
 namespace opt {
 
-ir::BasicBlock* DominatorAnalysisBase::CommonDominator(
-    ir::BasicBlock* b1, ir::BasicBlock* b2) const {
+opt::BasicBlock* DominatorAnalysisBase::CommonDominator(
+    opt::BasicBlock* b1, opt::BasicBlock* b2) const {
   if (!b1 || !b2) return nullptr;
 
-  std::unordered_set<ir::BasicBlock*> seen;
-  ir::BasicBlock* block = b1;
+  std::unordered_set<opt::BasicBlock*> seen;
+  opt::BasicBlock* block = b1;
   while (block && seen.insert(block).second) {
     block = ImmediateDominator(block);
   }
@@ -39,8 +39,8 @@
   return block;
 }
 
-bool DominatorAnalysisBase::Dominates(ir::Instruction* a,
-                                      ir::Instruction* b) const {
+bool DominatorAnalysisBase::Dominates(opt::Instruction* a,
+                                      opt::Instruction* b) const {
   if (!a || !b) {
     return false;
   }
@@ -49,14 +49,14 @@
     return true;
   }
 
-  ir::BasicBlock* bb_a = a->context()->get_instr_block(a);
-  ir::BasicBlock* bb_b = b->context()->get_instr_block(b);
+  opt::BasicBlock* bb_a = a->context()->get_instr_block(a);
+  opt::BasicBlock* bb_b = b->context()->get_instr_block(b);
 
   if (bb_a != bb_b) {
     return tree_.Dominates(bb_a, bb_b);
   }
 
-  ir::Instruction* current_inst = a;
+  opt::Instruction* current_inst = a;
   while ((current_inst = current_inst->NextNode())) {
     if (current_inst == b) {
       return true;
diff --git a/source/opt/dominator_analysis.h b/source/opt/dominator_analysis.h
index c40a344..3bdc25b 100644
--- a/source/opt/dominator_analysis.h
+++ b/source/opt/dominator_analysis.h
@@ -30,11 +30,13 @@
   explicit DominatorAnalysisBase(bool is_post_dom) : tree_(is_post_dom) {}
 
   // Calculates the dominator (or postdominator) tree for given function |f|.
-  inline void InitializeTree(const ir::Function* f) { tree_.InitializeTree(f); }
+  inline void InitializeTree(const opt::Function* f) {
+    tree_.InitializeTree(f);
+  }
 
   // Returns true if BasicBlock |a| dominates BasicBlock |b|.
-  inline bool Dominates(const ir::BasicBlock* a,
-                        const ir::BasicBlock* b) const {
+  inline bool Dominates(const opt::BasicBlock* a,
+                        const opt::BasicBlock* b) const {
     if (!a || !b) return false;
     return Dominates(a->id(), b->id());
   }
@@ -46,11 +48,11 @@
   }
 
   // Returns true if instruction |a| dominates instruction |b|.
-  bool Dominates(ir::Instruction* a, ir::Instruction* b) const;
+  bool Dominates(opt::Instruction* a, opt::Instruction* b) const;
 
   // Returns true if BasicBlock |a| strictly dominates BasicBlock |b|.
-  inline bool StrictlyDominates(const ir::BasicBlock* a,
-                                const ir::BasicBlock* b) const {
+  inline bool StrictlyDominates(const opt::BasicBlock* a,
+                                const opt::BasicBlock* b) const {
     if (!a || !b) return false;
     return StrictlyDominates(a->id(), b->id());
   }
@@ -63,19 +65,20 @@
 
   // Returns the immediate dominator of |node| or returns nullptr if it is has
   // no dominator.
-  inline ir::BasicBlock* ImmediateDominator(const ir::BasicBlock* node) const {
+  inline opt::BasicBlock* ImmediateDominator(
+      const opt::BasicBlock* node) const {
     if (!node) return nullptr;
     return tree_.ImmediateDominator(node);
   }
 
   // Returns the immediate dominator of |node_id| or returns nullptr if it is
   // has no dominator. Same as above but operates on IDs.
-  inline ir::BasicBlock* ImmediateDominator(uint32_t node_id) const {
+  inline opt::BasicBlock* ImmediateDominator(uint32_t node_id) const {
     return tree_.ImmediateDominator(node_id);
   }
 
   // Returns true if |node| is reachable from the entry.
-  inline bool IsReachable(const ir::BasicBlock* node) const {
+  inline bool IsReachable(const opt::BasicBlock* node) const {
     if (!node) return false;
     return tree_.ReachableFromRoots(node->id());
   }
@@ -114,7 +117,8 @@
 
   // Returns the most immediate basic block that dominates both |b1| and |b2|.
   // If there is no such basic block, nullptr is returned.
-  ir::BasicBlock* CommonDominator(ir::BasicBlock* b1, ir::BasicBlock* b2) const;
+  opt::BasicBlock* CommonDominator(opt::BasicBlock* b1,
+                                   opt::BasicBlock* b2) const;
 
  protected:
   DominatorTree tree_;
diff --git a/source/opt/dominator_tree.cpp b/source/opt/dominator_tree.cpp
index b3d005b..1f0c540 100644
--- a/source/opt/dominator_tree.cpp
+++ b/source/opt/dominator_tree.cpp
@@ -45,7 +45,7 @@
 // depth first search on generic BasicBlock types. Will call post and pre order
 // user defined functions during traversal
 //
-// BBType - BasicBlock type. Will either be ir::BasicBlock or DominatorTreeNode
+// BBType - BasicBlock type. Will either be opt::BasicBlock or DominatorTreeNode
 // SuccessorLambda - Lamdba matching the signature of 'const
 // std::vector<BBType>*(const BBType *A)'. Will return a vector of the nodes
 // succeding BasicBlock A.
@@ -66,7 +66,7 @@
 // depth first search on generic BasicBlock types. This overload is for only
 // performing user defined post order.
 //
-// BBType - BasicBlock type. Will either be ir::BasicBlock or DominatorTreeNode
+// BBType - BasicBlock type. Will either be opt::BasicBlock or DominatorTreeNode
 // SuccessorLambda - Lamdba matching the signature of 'const
 // std::vector<BBType>*(const BBType *A)'. Will return a vector of the nodes
 // succeding BasicBlock A.
@@ -84,7 +84,7 @@
 // Small type trait to get the function class type.
 template <typename BBType>
 struct GetFunctionClass {
-  using FunctionType = ir::Function;
+  using FunctionType = opt::Function;
 };
 
 // Helper class to compute predecessors and successors for each Basic Block in a
@@ -98,7 +98,7 @@
 // returned by this class will be predecessors in the original CFG.
 template <typename BBType>
 class BasicBlockSuccessorHelper {
-  // This should eventually become const ir::BasicBlock.
+  // This should eventually become const opt::BasicBlock.
   using BasicBlock = BBType;
   using Function = typename GetFunctionClass<BBType>::FunctionType;
 
@@ -219,8 +219,8 @@
   return Dominates(a, b);
 }
 
-bool DominatorTree::StrictlyDominates(const ir::BasicBlock* a,
-                                      const ir::BasicBlock* b) const {
+bool DominatorTree::StrictlyDominates(const opt::BasicBlock* a,
+                                      const opt::BasicBlock* b) const {
   return DominatorTree::StrictlyDominates(a->id(), b->id());
 }
 
@@ -248,17 +248,17 @@
          a->dfs_num_post_ > b->dfs_num_post_;
 }
 
-bool DominatorTree::Dominates(const ir::BasicBlock* A,
-                              const ir::BasicBlock* B) const {
+bool DominatorTree::Dominates(const opt::BasicBlock* A,
+                              const opt::BasicBlock* B) const {
   return Dominates(A->id(), B->id());
 }
 
-ir::BasicBlock* DominatorTree::ImmediateDominator(
-    const ir::BasicBlock* A) const {
+opt::BasicBlock* DominatorTree::ImmediateDominator(
+    const opt::BasicBlock* A) const {
   return ImmediateDominator(A->id());
 }
 
-ir::BasicBlock* DominatorTree::ImmediateDominator(uint32_t a) const {
+opt::BasicBlock* DominatorTree::ImmediateDominator(uint32_t a) const {
   // Check that A is a valid node in the tree.
   auto a_itr = nodes_.find(a);
   if (a_itr == nodes_.end()) return nullptr;
@@ -272,7 +272,7 @@
   return node->parent_->bb_;
 }
 
-DominatorTreeNode* DominatorTree::GetOrInsertNode(ir::BasicBlock* bb) {
+DominatorTreeNode* DominatorTree::GetOrInsertNode(opt::BasicBlock* bb) {
   DominatorTreeNode* dtn = nullptr;
 
   std::map<uint32_t, DominatorTreeNode>::iterator node_iter =
@@ -287,21 +287,21 @@
 }
 
 void DominatorTree::GetDominatorEdges(
-    const ir::Function* f, const ir::BasicBlock* dummy_start_node,
-    std::vector<std::pair<ir::BasicBlock*, ir::BasicBlock*>>* edges) {
+    const opt::Function* f, const opt::BasicBlock* dummy_start_node,
+    std::vector<std::pair<opt::BasicBlock*, opt::BasicBlock*>>* edges) {
   // Each time the depth first traversal calls the postorder callback
   // std::function we push that node into the postorder vector to create our
   // postorder list.
-  std::vector<const ir::BasicBlock*> postorder;
-  auto postorder_function = [&](const ir::BasicBlock* b) {
+  std::vector<const opt::BasicBlock*> postorder;
+  auto postorder_function = [&](const opt::BasicBlock* b) {
     postorder.push_back(b);
   };
 
-  // CFA::CalculateDominators requires std::vector<ir::BasicBlock*>
+  // CFA::CalculateDominators requires std::vector<opt::BasicBlock*>
   // BB are derived from F, so we need to const cast it at some point
   // no modification is made on F.
-  BasicBlockSuccessorHelper<ir::BasicBlock> helper{
-      *const_cast<ir::Function*>(f), dummy_start_node, postdominator_};
+  BasicBlockSuccessorHelper<opt::BasicBlock> helper{
+      *const_cast<opt::Function*>(f), dummy_start_node, postdominator_};
 
   // The successor function tells DepthFirstTraversal how to move to successive
   // nodes by providing an interface to get a list of successor nodes from any
@@ -318,23 +318,23 @@
   DepthFirstSearchPostOrder(dummy_start_node, successor_functor,
                             postorder_function);
   *edges =
-      CFA<ir::BasicBlock>::CalculateDominators(postorder, predecessor_functor);
+      CFA<opt::BasicBlock>::CalculateDominators(postorder, predecessor_functor);
 }
 
-void DominatorTree::InitializeTree(const ir::Function* f) {
+void DominatorTree::InitializeTree(const opt::Function* f) {
   ClearTree();
 
   // Skip over empty functions.
   if (f->cbegin() == f->cend()) {
     return;
   }
-  const ir::CFG& cfg = *f->context()->cfg();
+  const opt::CFG& cfg = *f->context()->cfg();
 
-  const ir::BasicBlock* dummy_start_node =
+  const opt::BasicBlock* dummy_start_node =
       postdominator_ ? cfg.pseudo_exit_block() : cfg.pseudo_entry_block();
 
   // Get the immediate dominator for each node.
-  std::vector<std::pair<ir::BasicBlock*, ir::BasicBlock*>> edges;
+  std::vector<std::pair<opt::BasicBlock*, opt::BasicBlock*>> edges;
   GetDominatorEdges(f, dummy_start_node, &edges);
 
   // Transform the vector<pair> into the tree structure which we can use to
diff --git a/source/opt/dominator_tree.h b/source/opt/dominator_tree.h
index ee2026b..43406a1 100644
--- a/source/opt/dominator_tree.h
+++ b/source/opt/dominator_tree.h
@@ -31,7 +31,7 @@
 // children. It also contains two values, for the pre and post indexes in the
 // tree which are used to compare two nodes.
 struct DominatorTreeNode {
-  explicit DominatorTreeNode(ir::BasicBlock* bb)
+  explicit DominatorTreeNode(opt::BasicBlock* bb)
       : bb_(bb),
         parent_(nullptr),
         children_({}),
@@ -77,7 +77,7 @@
 
   inline uint32_t id() const { return bb_->id(); }
 
-  ir::BasicBlock* bb_;
+  opt::BasicBlock* bb_;
   DominatorTreeNode* parent_;
   std::vector<DominatorTreeNode*> children_;
 
@@ -158,10 +158,10 @@
 
   // Build the (post-)dominator tree for the function |f|
   // Any existing data will be overwritten
-  void InitializeTree(const ir::Function* f);
+  void InitializeTree(const opt::Function* f);
 
   // Check if the basic block |a| dominates the basic block |b|.
-  bool Dominates(const ir::BasicBlock* a, const ir::BasicBlock* b) const;
+  bool Dominates(const opt::BasicBlock* a, const opt::BasicBlock* b) const;
 
   // Check if the basic block id |a| dominates the basic block id |b|.
   bool Dominates(uint32_t a, uint32_t b) const;
@@ -170,8 +170,8 @@
   bool Dominates(const DominatorTreeNode* a, const DominatorTreeNode* b) const;
 
   // Check if the basic block |a| strictly dominates the basic block |b|.
-  bool StrictlyDominates(const ir::BasicBlock* a,
-                         const ir::BasicBlock* b) const;
+  bool StrictlyDominates(const opt::BasicBlock* a,
+                         const opt::BasicBlock* b) const;
 
   // Check if the basic block id |a| strictly dominates the basic block id |b|.
   bool StrictlyDominates(uint32_t a, uint32_t b) const;
@@ -182,15 +182,15 @@
                          const DominatorTreeNode* b) const;
 
   // Returns the immediate dominator of basic block |a|.
-  ir::BasicBlock* ImmediateDominator(const ir::BasicBlock* A) const;
+  opt::BasicBlock* ImmediateDominator(const opt::BasicBlock* A) const;
 
   // Returns the immediate dominator of basic block id |a|.
-  ir::BasicBlock* ImmediateDominator(uint32_t a) const;
+  opt::BasicBlock* ImmediateDominator(uint32_t a) const;
 
   // Returns true if the basic block |a| is reachable by this tree. A node would
   // be unreachable if it cannot be reached by traversal from the start node or
   // for a postdominator tree, cannot be reached from the exit nodes.
-  inline bool ReachableFromRoots(const ir::BasicBlock* a) const {
+  inline bool ReachableFromRoots(const opt::BasicBlock* a) const {
     if (!a) return false;
     return ReachableFromRoots(a->id());
   }
@@ -242,12 +242,12 @@
 
   // Returns the DominatorTreeNode associated with the basic block |bb|.
   // If the |bb| is unknown to the dominator tree, it returns null.
-  inline DominatorTreeNode* GetTreeNode(ir::BasicBlock* bb) {
+  inline DominatorTreeNode* GetTreeNode(opt::BasicBlock* bb) {
     return GetTreeNode(bb->id());
   }
   // Returns the DominatorTreeNode associated with the basic block |bb|.
   // If the |bb| is unknown to the dominator tree, it returns null.
-  inline const DominatorTreeNode* GetTreeNode(ir::BasicBlock* bb) const {
+  inline const DominatorTreeNode* GetTreeNode(opt::BasicBlock* bb) const {
     return GetTreeNode(bb->id());
   }
 
@@ -272,7 +272,7 @@
 
   // Adds the basic block |bb| to the tree structure if it doesn't already
   // exist.
-  DominatorTreeNode* GetOrInsertNode(ir::BasicBlock* bb);
+  DominatorTreeNode* GetOrInsertNode(opt::BasicBlock* bb);
 
   // Recomputes the DF numbering of the tree.
   void ResetDFNumbering();
@@ -287,8 +287,8 @@
   // pair is its immediate dominator.
   // The root of the tree has themself as immediate dominator.
   void GetDominatorEdges(
-      const ir::Function* f, const ir::BasicBlock* dummy_start_node,
-      std::vector<std::pair<ir::BasicBlock*, ir::BasicBlock*>>* edges);
+      const opt::Function* f, const opt::BasicBlock* dummy_start_node,
+      std::vector<std::pair<opt::BasicBlock*, opt::BasicBlock*>>* edges);
 
   // The roots of the tree.
   std::vector<DominatorTreeNode*> roots_;
diff --git a/source/opt/eliminate_dead_constant_pass.cpp b/source/opt/eliminate_dead_constant_pass.cpp
index 5e299c6..07b4dca 100644
--- a/source/opt/eliminate_dead_constant_pass.cpp
+++ b/source/opt/eliminate_dead_constant_pass.cpp
@@ -26,22 +26,22 @@
 namespace spvtools {
 namespace opt {
 
-Pass::Status EliminateDeadConstantPass::Process(ir::IRContext* irContext) {
-  std::unordered_set<ir::Instruction*> working_list;
+Pass::Status EliminateDeadConstantPass::Process(opt::IRContext* irContext) {
+  std::unordered_set<opt::Instruction*> working_list;
   // Traverse all the instructions to get the initial set of dead constants as
   // working list and count number of real uses for constants. Uses in
   // annotation instructions do not count.
-  std::unordered_map<ir::Instruction*, size_t> use_counts;
-  std::vector<ir::Instruction*> constants = irContext->GetConstants();
+  std::unordered_map<opt::Instruction*, size_t> use_counts;
+  std::vector<opt::Instruction*> constants = irContext->GetConstants();
   for (auto* c : constants) {
     uint32_t const_id = c->result_id();
     size_t count = 0;
     irContext->get_def_use_mgr()->ForEachUse(
-        const_id, [&count](ir::Instruction* user, uint32_t index) {
+        const_id, [&count](opt::Instruction* user, uint32_t index) {
           (void)index;
           SpvOp op = user->opcode();
-          if (!(ir::IsAnnotationInst(op) || ir::IsDebug1Inst(op) ||
-                ir::IsDebug2Inst(op) || ir::IsDebug3Inst(op))) {
+          if (!(opt::IsAnnotationInst(op) || opt::IsDebug1Inst(op) ||
+                opt::IsDebug2Inst(op) || opt::IsDebug3Inst(op))) {
             ++count;
           }
         });
@@ -53,9 +53,9 @@
 
   // Start from the constants with 0 uses, back trace through the def-use chain
   // to find all dead constants.
-  std::unordered_set<ir::Instruction*> dead_consts;
+  std::unordered_set<opt::Instruction*> dead_consts;
   while (!working_list.empty()) {
-    ir::Instruction* inst = *working_list.begin();
+    opt::Instruction* inst = *working_list.begin();
     // Back propagate if the instruction contains IDs in its operands.
     switch (inst->opcode()) {
       case SpvOp::SpvOpConstantComposite:
@@ -68,7 +68,7 @@
             continue;
           }
           uint32_t operand_id = inst->GetSingleWordInOperand(i);
-          ir::Instruction* def_inst =
+          opt::Instruction* def_inst =
               irContext->get_def_use_mgr()->GetDef(operand_id);
           // If the use_count does not have any count for the def_inst,
           // def_inst must not be a constant, and should be ignored here.
diff --git a/source/opt/eliminate_dead_constant_pass.h b/source/opt/eliminate_dead_constant_pass.h
index 3ff69f5..9f0f537 100644
--- a/source/opt/eliminate_dead_constant_pass.h
+++ b/source/opt/eliminate_dead_constant_pass.h
@@ -26,7 +26,7 @@
 class EliminateDeadConstantPass : public Pass {
  public:
   const char* name() const override { return "eliminate-dead-const"; }
-  Status Process(ir::IRContext*) override;
+  Status Process(opt::IRContext*) override;
 };
 
 }  // namespace opt
diff --git a/source/opt/eliminate_dead_functions_pass.cpp b/source/opt/eliminate_dead_functions_pass.cpp
index 8f9748a..7529caf 100644
--- a/source/opt/eliminate_dead_functions_pass.cpp
+++ b/source/opt/eliminate_dead_functions_pass.cpp
@@ -20,13 +20,13 @@
 namespace spvtools {
 namespace opt {
 
-Pass::Status EliminateDeadFunctionsPass::Process(ir::IRContext* c) {
+Pass::Status EliminateDeadFunctionsPass::Process(opt::IRContext* c) {
   InitializeProcessing(c);
 
   // Identify live functions first.  Those that are not live
   // are dead.
-  std::unordered_set<const ir::Function*> live_function_set;
-  ProcessFunction mark_live = [&live_function_set](ir::Function* fp) {
+  std::unordered_set<const opt::Function*> live_function_set;
+  ProcessFunction mark_live = [&live_function_set](opt::Function* fp) {
     live_function_set.insert(fp);
     return false;
   };
@@ -48,10 +48,10 @@
                   : Pass::Status::SuccessWithoutChange;
 }
 
-void EliminateDeadFunctionsPass::EliminateFunction(ir::Function* func) {
+void EliminateDeadFunctionsPass::EliminateFunction(opt::Function* func) {
   // Remove all of the instruction in the function body
   func->ForEachInst(
-      [this](ir::Instruction* inst) { context()->KillInst(inst); }, true);
+      [this](opt::Instruction* inst) { context()->KillInst(inst); }, true);
 }
 }  // namespace opt
 }  // namespace spvtools
diff --git a/source/opt/eliminate_dead_functions_pass.h b/source/opt/eliminate_dead_functions_pass.h
index adb41bb..41a9c92 100644
--- a/source/opt/eliminate_dead_functions_pass.h
+++ b/source/opt/eliminate_dead_functions_pass.h
@@ -27,14 +27,14 @@
 class EliminateDeadFunctionsPass : public MemPass {
  public:
   const char* name() const override { return "eliminate-dead-functions"; }
-  Status Process(ir::IRContext* c) override;
+  Status Process(opt::IRContext* c) override;
 
-  ir::IRContext::Analysis GetPreservedAnalyses() override {
-    return ir::IRContext::kAnalysisDefUse;
+  opt::IRContext::Analysis GetPreservedAnalyses() override {
+    return opt::IRContext::kAnalysisDefUse;
   }
 
  private:
-  void EliminateFunction(ir::Function* func);
+  void EliminateFunction(opt::Function* func);
 };
 
 }  // namespace opt
diff --git a/source/opt/feature_manager.cpp b/source/opt/feature_manager.cpp
index 27ecfe3..580d96d 100644
--- a/source/opt/feature_manager.cpp
+++ b/source/opt/feature_manager.cpp
@@ -21,13 +21,13 @@
 namespace spvtools {
 namespace opt {
 
-void FeatureManager::Analyze(ir::Module* module) {
+void FeatureManager::Analyze(opt::Module* module) {
   AddExtensions(module);
   AddCapabilities(module);
   AddExtInstImportIds(module);
 }
 
-void FeatureManager::AddExtensions(ir::Module* module) {
+void FeatureManager::AddExtensions(opt::Module* module) {
   for (auto ext : module->extensions()) {
     const std::string name =
         reinterpret_cast<const char*>(ext.GetInOperand(0u).words.data());
@@ -51,13 +51,13 @@
   }
 }
 
-void FeatureManager::AddCapabilities(ir::Module* module) {
-  for (ir::Instruction& inst : module->capabilities()) {
+void FeatureManager::AddCapabilities(opt::Module* module) {
+  for (opt::Instruction& inst : module->capabilities()) {
     AddCapability(static_cast<SpvCapability>(inst.GetSingleWordInOperand(0)));
   }
 }
 
-void FeatureManager::AddExtInstImportIds(ir::Module* module) {
+void FeatureManager::AddExtInstImportIds(opt::Module* module) {
   extinst_importid_GLSLstd450_ = module->GetExtInstImportId("GLSL.std.450");
 }
 
diff --git a/source/opt/feature_manager.h b/source/opt/feature_manager.h
index e9d0298..9419ce9 100644
--- a/source/opt/feature_manager.h
+++ b/source/opt/feature_manager.h
@@ -36,7 +36,7 @@
   }
 
   // Analyzes |module| and records enabled extensions and capabilities.
-  void Analyze(ir::Module* module);
+  void Analyze(opt::Module* module);
 
   CapabilitySet* GetCapabilities() { return &capabilities_; }
   const CapabilitySet* GetCapabilities() const { return &capabilities_; }
@@ -47,17 +47,17 @@
 
  private:
   // Analyzes |module| and records enabled extensions.
-  void AddExtensions(ir::Module* module);
+  void AddExtensions(opt::Module* module);
 
   // Adds the given |capability| and all implied capabilities into the current
   // FeatureManager.
   void AddCapability(SpvCapability capability);
 
   // Analyzes |module| and records enabled capabilities.
-  void AddCapabilities(ir::Module* module);
+  void AddCapabilities(opt::Module* module);
 
   // Analyzes |module| and records imported external instruction sets.
-  void AddExtInstImportIds(ir::Module* module);
+  void AddExtInstImportIds(opt::Module* module);
 
   // Auxiliary object for querying SPIR-V grammar facts.
   const AssemblyGrammar& grammar_;
diff --git a/source/opt/flatten_decoration_pass.cpp b/source/opt/flatten_decoration_pass.cpp
index eac8297..2314dbf 100644
--- a/source/opt/flatten_decoration_pass.cpp
+++ b/source/opt/flatten_decoration_pass.cpp
@@ -23,13 +23,13 @@
 namespace spvtools {
 namespace opt {
 
-using ir::Instruction;
-using ir::Operand;
+using opt::Instruction;
+using opt::Operand;
 
 using Words = std::vector<uint32_t>;
 using OrderedUsesMap = std::unordered_map<uint32_t, Words>;
 
-Pass::Status FlattenDecorationPass::Process(ir::IRContext* c) {
+Pass::Status FlattenDecorationPass::Process(opt::IRContext* c) {
   InitializeProcessing(c);
 
   bool modified = false;
diff --git a/source/opt/flatten_decoration_pass.h b/source/opt/flatten_decoration_pass.h
index 7db6f86..fcbc792 100644
--- a/source/opt/flatten_decoration_pass.h
+++ b/source/opt/flatten_decoration_pass.h
@@ -26,7 +26,7 @@
 class FlattenDecorationPass : public Pass {
  public:
   const char* name() const override { return "flatten-decoration"; }
-  Status Process(ir::IRContext*) override;
+  Status Process(opt::IRContext*) override;
 };
 
 }  // namespace opt
diff --git a/source/opt/fold.cpp b/source/opt/fold.cpp
index 0e24b0b..2fc600f 100644
--- a/source/opt/fold.cpp
+++ b/source/opt/fold.cpp
@@ -177,10 +177,10 @@
   }
 }
 
-bool InstructionFolder::FoldInstructionInternal(ir::Instruction* inst) const {
-  ir::IRContext* context = inst->context();
+bool InstructionFolder::FoldInstructionInternal(opt::Instruction* inst) const {
+  opt::IRContext* context = inst->context();
   auto identity_map = [](uint32_t id) { return id; };
-  ir::Instruction* folded_inst = FoldInstructionToConstant(inst, identity_map);
+  opt::Instruction* folded_inst = FoldInstructionToConstant(inst, identity_map);
   if (folded_inst != nullptr) {
     inst->SetOpcode(SpvOpCopyObject);
     inst->SetInOperands({{SPV_OPERAND_TYPE_ID, {folded_inst->result_id()}}});
@@ -230,16 +230,16 @@
 }
 
 bool InstructionFolder::FoldBinaryIntegerOpToConstant(
-    ir::Instruction* inst, std::function<uint32_t(uint32_t)> id_map,
+    opt::Instruction* inst, std::function<uint32_t(uint32_t)> id_map,
     uint32_t* result) const {
   SpvOp opcode = inst->opcode();
-  ir::IRContext* context = inst->context();
+  opt::IRContext* context = inst->context();
   analysis::ConstantManager* const_manger = context->get_constant_mgr();
 
   uint32_t ids[2];
   const analysis::IntConstant* constants[2];
   for (uint32_t i = 0; i < 2; i++) {
-    const ir::Operand* operand = &inst->GetInOperand(i);
+    const opt::Operand* operand = &inst->GetInOperand(i);
     if (operand->type != SPV_OPERAND_TYPE_ID) {
       return false;
     }
@@ -414,16 +414,16 @@
 }
 
 bool InstructionFolder::FoldBinaryBooleanOpToConstant(
-    ir::Instruction* inst, std::function<uint32_t(uint32_t)> id_map,
+    opt::Instruction* inst, std::function<uint32_t(uint32_t)> id_map,
     uint32_t* result) const {
   SpvOp opcode = inst->opcode();
-  ir::IRContext* context = inst->context();
+  opt::IRContext* context = inst->context();
   analysis::ConstantManager* const_manger = context->get_constant_mgr();
 
   uint32_t ids[2];
   const analysis::BoolConstant* constants[2];
   for (uint32_t i = 0; i < 2; i++) {
-    const ir::Operand* operand = &inst->GetInOperand(i);
+    const opt::Operand* operand = &inst->GetInOperand(i);
     if (operand->type != SPV_OPERAND_TYPE_ID) {
       return false;
     }
@@ -463,7 +463,7 @@
 }
 
 bool InstructionFolder::FoldIntegerOpToConstant(
-    ir::Instruction* inst, std::function<uint32_t(uint32_t)> id_map,
+    opt::Instruction* inst, std::function<uint32_t(uint32_t)> id_map,
     uint32_t* result) const {
   assert(IsFoldableOpcode(inst->opcode()) &&
          "Unhandled instruction opcode in FoldScalars");
@@ -572,9 +572,9 @@
     return cst->AsNullConstant() != nullptr;
 }
 
-ir::Instruction* InstructionFolder::FoldInstructionToConstant(
-    ir::Instruction* inst, std::function<uint32_t(uint32_t)> id_map) const {
-  ir::IRContext* context = inst->context();
+opt::Instruction* InstructionFolder::FoldInstructionToConstant(
+    opt::Instruction* inst, std::function<uint32_t(uint32_t)> id_map) const {
+  opt::IRContext* context = inst->context();
   analysis::ConstantManager* const_mgr = context->get_constant_mgr();
 
   if (!inst->IsFoldableByFoldScalar() &&
@@ -602,7 +602,7 @@
          GetConstantFoldingRules().GetRulesForOpcode(inst->opcode())) {
       folded_const = rule(inst, constants);
       if (folded_const != nullptr) {
-        ir::Instruction* const_inst =
+        opt::Instruction* const_inst =
             const_mgr->GetDefiningInstruction(folded_const, inst->type_id());
         assert(const_inst->type_id() == inst->type_id());
         // May be a new instruction that needs to be analysed.
@@ -627,14 +627,14 @@
   if (successful) {
     const analysis::Constant* result_const =
         const_mgr->GetConstant(const_mgr->GetType(inst), {result_val});
-    ir::Instruction* folded_inst =
+    opt::Instruction* folded_inst =
         const_mgr->GetDefiningInstruction(result_const, inst->type_id());
     return folded_inst;
   }
   return nullptr;
 }
 
-bool InstructionFolder::IsFoldableType(ir::Instruction* type_inst) const {
+bool InstructionFolder::IsFoldableType(opt::Instruction* type_inst) const {
   // Support 32-bit integers.
   if (type_inst->opcode() == SpvOpTypeInt) {
     return type_inst->GetSingleWordInOperand(0) == 32;
@@ -647,9 +647,9 @@
   return false;
 }
 
-bool InstructionFolder::FoldInstruction(ir::Instruction* inst) const {
+bool InstructionFolder::FoldInstruction(opt::Instruction* inst) const {
   bool modified = false;
-  ir::Instruction* folded_inst(inst);
+  opt::Instruction* folded_inst(inst);
   while (folded_inst->opcode() != SpvOpCopyObject &&
          FoldInstructionInternal(&*folded_inst)) {
     modified = true;
diff --git a/source/opt/fold.h b/source/opt/fold.h
index c00b56e..967e482 100644
--- a/source/opt/fold.h
+++ b/source/opt/fold.h
@@ -66,7 +66,7 @@
 
   // Returns true if |FoldInstructionToConstant| could fold an instruction whose
   // result type is |type_inst|.
-  bool IsFoldableType(ir::Instruction* type_inst) const;
+  bool IsFoldableType(opt::Instruction* type_inst) const;
 
   // Tries to fold |inst| to a single constant, when the input ids to |inst|
   // have been substituted using |id_map|.  Returns a pointer to the OpConstant*
@@ -77,8 +77,8 @@
   // can be used for things like CCP where it is known that some ids contain a
   // constant, but the instruction itself has not been updated yet.  This can
   // map those ids to the appropriate constants.
-  ir::Instruction* FoldInstructionToConstant(
-      ir::Instruction* inst, std::function<uint32_t(uint32_t)> id_map) const;
+  opt::Instruction* FoldInstructionToConstant(
+      opt::Instruction* inst, std::function<uint32_t(uint32_t)> id_map) const;
   // Returns true if |inst| can be folded into a simpler instruction.
   // If |inst| can be simplified, |inst| is overwritten with the simplified
   // instruction reusing the same result id.
@@ -90,7 +90,7 @@
   // 1) An OpPhi becomes and OpCopyObject - If there are OpPhi instruction after
   //    |inst| in a basic block then this is invalid.  The caller must fix this
   //    up.
-  bool FoldInstruction(ir::Instruction* inst) const;
+  bool FoldInstruction(opt::Instruction* inst) const;
 
   // Return true if this opcode has a const folding rule associtated with it.
   bool HasConstFoldingRule(SpvOp opcode) const {
@@ -126,7 +126,7 @@
   uint32_t OperateWords(SpvOp opcode,
                         const std::vector<uint32_t>& operand_words) const;
 
-  bool FoldInstructionInternal(ir::Instruction* inst) const;
+  bool FoldInstructionInternal(opt::Instruction* inst) const;
 
   // Returns true if |inst| is a binary operation that takes two integers as
   // parameters and folds to a constant that can be represented as an unsigned
@@ -134,7 +134,7 @@
   // folded, the resulting value is returned in |*result|.  Valid result types
   // for the instruction are any integer (signed or unsigned) with 32-bits or
   // less, or a boolean value.
-  bool FoldBinaryIntegerOpToConstant(ir::Instruction* inst,
+  bool FoldBinaryIntegerOpToConstant(opt::Instruction* inst,
                                      std::function<uint32_t(uint32_t)> id_map,
                                      uint32_t* result) const;
 
@@ -142,7 +142,7 @@
   // folds
   // to a constant boolean value when the ids have been replaced using |id_map|.
   // If |inst| can be folded, the result value is returned in |*result|.
-  bool FoldBinaryBooleanOpToConstant(ir::Instruction* inst,
+  bool FoldBinaryBooleanOpToConstant(opt::Instruction* inst,
                                      std::function<uint32_t(uint32_t)> id_map,
                                      uint32_t* result) const;
 
@@ -150,7 +150,7 @@
   // substituted using id_map.  If it can, the value is returned in |result|. If
   // not, |result| is unchanged.  It is assumed that not all operands are
   // constant.  Those cases are handled by |FoldScalar|.
-  bool FoldIntegerOpToConstant(ir::Instruction* inst,
+  bool FoldIntegerOpToConstant(opt::Instruction* inst,
                                std::function<uint32_t(uint32_t)> id_map,
                                uint32_t* result) const;
 
diff --git a/source/opt/fold_spec_constant_op_and_composite_pass.cpp b/source/opt/fold_spec_constant_op_and_composite_pass.cpp
index df78c69..bd9950a 100644
--- a/source/opt/fold_spec_constant_op_and_composite_pass.cpp
+++ b/source/opt/fold_spec_constant_op_and_composite_pass.cpp
@@ -27,17 +27,17 @@
 namespace opt {
 
 Pass::Status FoldSpecConstantOpAndCompositePass::Process(
-    ir::IRContext* irContext) {
+    opt::IRContext* irContext) {
   Initialize(irContext);
   return ProcessImpl(irContext);
 }
 
-void FoldSpecConstantOpAndCompositePass::Initialize(ir::IRContext* irContext) {
+void FoldSpecConstantOpAndCompositePass::Initialize(opt::IRContext* irContext) {
   InitializeProcessing(irContext);
 }
 
 Pass::Status FoldSpecConstantOpAndCompositePass::ProcessImpl(
-    ir::IRContext* irContext) {
+    opt::IRContext* irContext) {
   bool modified = false;
   // Traverse through all the constant defining instructions. For Normal
   // Constants whose values are determined and do not depend on OpUndef
@@ -59,13 +59,13 @@
   // the dependee Spec Constants, all its dependent constants must have been
   // processed and all its dependent Spec Constants should have been folded if
   // possible.
-  ir::Module::inst_iterator next_inst = irContext->types_values_begin();
-  for (ir::Module::inst_iterator inst_iter = next_inst;
+  opt::Module::inst_iterator next_inst = irContext->types_values_begin();
+  for (opt::Module::inst_iterator inst_iter = next_inst;
        // Need to re-evaluate the end iterator since we may modify the list of
        // instructions in this section of the module as the process goes.
        inst_iter != irContext->types_values_end(); inst_iter = next_inst) {
     ++next_inst;
-    ir::Instruction* inst = &*inst_iter;
+    opt::Instruction* inst = &*inst_iter;
     // Collect constant values of normal constants and process the
     // OpSpecConstantOp and OpSpecConstantComposite instructions if possible.
     // The constant values will be stored in analysis::Constant instances.
@@ -121,9 +121,9 @@
 }
 
 bool FoldSpecConstantOpAndCompositePass::ProcessOpSpecConstantOp(
-    ir::Module::inst_iterator* pos) {
-  ir::Instruction* inst = &**pos;
-  ir::Instruction* folded_inst = nullptr;
+    opt::Module::inst_iterator* pos) {
+  opt::Instruction* inst = &**pos;
+  opt::Instruction* folded_inst = nullptr;
   assert(inst->GetInOperand(0).type ==
              SPV_OPERAND_TYPE_SPEC_CONSTANT_OP_NUMBER &&
          "The first in-operand of OpSpecContantOp instruction must be of "
@@ -161,16 +161,16 @@
 
 uint32_t FoldSpecConstantOpAndCompositePass::GetTypeComponent(
     uint32_t typeId, uint32_t element) const {
-  ir::Instruction* type = context()->get_def_use_mgr()->GetDef(typeId);
+  opt::Instruction* type = context()->get_def_use_mgr()->GetDef(typeId);
   uint32_t subtype = type->GetTypeComponent(element);
   assert(subtype != 0);
 
   return subtype;
 }
 
-ir::Instruction* FoldSpecConstantOpAndCompositePass::DoCompositeExtract(
-    ir::Module::inst_iterator* pos) {
-  ir::Instruction* inst = &**pos;
+opt::Instruction* FoldSpecConstantOpAndCompositePass::DoCompositeExtract(
+    opt::Module::inst_iterator* pos) {
+  opt::Instruction* inst = &**pos;
   assert(inst->NumInOperands() - 1 >= 2 &&
          "OpSpecConstantOp CompositeExtract requires at least two non-type "
          "non-opcode operands.");
@@ -218,9 +218,9 @@
       current_const, pos);
 }
 
-ir::Instruction* FoldSpecConstantOpAndCompositePass::DoVectorShuffle(
-    ir::Module::inst_iterator* pos) {
-  ir::Instruction* inst = &**pos;
+opt::Instruction* FoldSpecConstantOpAndCompositePass::DoVectorShuffle(
+    opt::Module::inst_iterator* pos) {
+  opt::Instruction* inst = &**pos;
   analysis::Vector* result_vec_type =
       context()->get_constant_mgr()->GetType(inst)->AsVector();
   assert(inst->NumInOperands() - 1 > 2 &&
@@ -323,9 +323,9 @@
 }
 }  // namespace
 
-ir::Instruction* FoldSpecConstantOpAndCompositePass::DoComponentWiseOperation(
-    ir::Module::inst_iterator* pos) {
-  const ir::Instruction* inst = &**pos;
+opt::Instruction* FoldSpecConstantOpAndCompositePass::DoComponentWiseOperation(
+    opt::Module::inst_iterator* pos) {
+  const opt::Instruction* inst = &**pos;
   const analysis::Type* result_type =
       context()->get_constant_mgr()->GetType(inst);
   SpvOp spec_opcode = static_cast<SpvOp>(inst->GetSingleWordInOperand(0));
@@ -334,7 +334,7 @@
 
   if (!std::all_of(
           inst->cbegin(), inst->cend(),
-          [&operands, this](const ir::Operand& o) {
+          [&operands, this](const opt::Operand& o) {
             // skip the operands that is not an id.
             if (o.type != spv_operand_type_t::SPV_OPERAND_TYPE_ID) return true;
             uint32_t id = o.words.front();
diff --git a/source/opt/fold_spec_constant_op_and_composite_pass.h b/source/opt/fold_spec_constant_op_and_composite_pass.h
index 5f901ee..5bf4676 100644
--- a/source/opt/fold_spec_constant_op_and_composite_pass.h
+++ b/source/opt/fold_spec_constant_op_and_composite_pass.h
@@ -36,19 +36,19 @@
 
   const char* name() const override { return "fold-spec-const-op-composite"; }
 
-  Status Process(ir::IRContext* irContext) override;
+  Status Process(opt::IRContext* irContext) override;
 
  private:
   // Initializes the type manager, def-use manager and get the maximal id used
   // in the module.
-  void Initialize(ir::IRContext* irContext);
+  void Initialize(opt::IRContext* irContext);
 
   // The real entry of processing. Iterates through the types-constants-globals
   // section of the given module, finds the Spec Constants defined with
   // OpSpecConstantOp and OpSpecConstantComposite instructions. If the result
   // value of those spec constants can be folded, fold them to their
   // corresponding normal constants.
-  Status ProcessImpl(ir::IRContext* irContext);
+  Status ProcessImpl(opt::IRContext* irContext);
 
   // Processes the OpSpecConstantOp instruction pointed by the given
   // instruction iterator, folds it to normal constants if possible. Returns
@@ -59,26 +59,27 @@
   // folding is done successfully, the original OpSpecConstantOp instruction
   // will be changed to Nop and new folded instruction will be inserted before
   // it.
-  bool ProcessOpSpecConstantOp(ir::Module::inst_iterator* pos);
+  bool ProcessOpSpecConstantOp(opt::Module::inst_iterator* pos);
 
   // Try to fold the OpSpecConstantOp CompositeExtract instruction pointed by
   // the given instruction iterator to a normal constant defining instruction.
   // Returns the pointer to the new constant defining instruction if succeeded.
   // Otherwise returns nullptr.
-  ir::Instruction* DoCompositeExtract(ir::Module::inst_iterator* inst_iter_ptr);
+  opt::Instruction* DoCompositeExtract(
+      opt::Module::inst_iterator* inst_iter_ptr);
 
   // Try to fold the OpSpecConstantOp VectorShuffle instruction pointed by the
   // given instruction iterator to a normal constant defining instruction.
   // Returns the pointer to the new constant defining instruction if succeeded.
   // Otherwise return nullptr.
-  ir::Instruction* DoVectorShuffle(ir::Module::inst_iterator* inst_iter_ptr);
+  opt::Instruction* DoVectorShuffle(opt::Module::inst_iterator* inst_iter_ptr);
 
   // Try to fold the OpSpecConstantOp <component wise operations> instruction
   // pointed by the given instruction iterator to a normal constant defining
   // instruction. Returns the pointer to the new constant defining instruction
   // if succeeded, otherwise return nullptr.
-  ir::Instruction* DoComponentWiseOperation(
-      ir::Module::inst_iterator* inst_iter_ptr);
+  opt::Instruction* DoComponentWiseOperation(
+      opt::Module::inst_iterator* inst_iter_ptr);
 
   // Returns the |element|'th subtype of |type|.
   //
diff --git a/source/opt/folding_rules.cpp b/source/opt/folding_rules.cpp
index 9365221..c3c956d 100644
--- a/source/opt/folding_rules.cpp
+++ b/source/opt/folding_rules.cpp
@@ -75,9 +75,9 @@
   return constants[0] ? constants[0] : constants[1];
 }
 
-ir::Instruction* NonConstInput(ir::IRContext* context,
-                               const analysis::Constant* c,
-                               ir::Instruction* inst) {
+opt::Instruction* NonConstInput(opt::IRContext* context,
+                                const analysis::Constant* c,
+                                opt::Instruction* inst) {
   uint32_t in_op = c ? 1u : 0u;
   return context->get_def_use_mgr()->GetDef(
       inst->GetSingleWordInOperand(in_op));
@@ -199,10 +199,10 @@
 
 // Replaces fdiv where second operand is constant with fmul.
 FoldingRule ReciprocalFDiv() {
-  return [](ir::Instruction* inst,
+  return [](opt::Instruction* inst,
             const std::vector<const analysis::Constant*>& constants) {
     assert(inst->opcode() == SpvOpFDiv);
-    ir::IRContext* context = inst->context();
+    opt::IRContext* context = inst->context();
     analysis::ConstantManager* const_mgr = context->get_constant_mgr();
     const analysis::Type* type =
         context->get_type_mgr()->GetType(inst->type_id());
@@ -244,17 +244,17 @@
 
 // Elides consecutive negate instructions.
 FoldingRule MergeNegateArithmetic() {
-  return [](ir::Instruction* inst,
+  return [](opt::Instruction* inst,
             const std::vector<const analysis::Constant*>& constants) {
     assert(inst->opcode() == SpvOpFNegate || inst->opcode() == SpvOpSNegate);
     (void)constants;
-    ir::IRContext* context = inst->context();
+    opt::IRContext* context = inst->context();
     const analysis::Type* type =
         context->get_type_mgr()->GetType(inst->type_id());
     if (HasFloatingPoint(type) && !inst->IsFloatingPointFoldingAllowed())
       return false;
 
-    ir::Instruction* op_inst =
+    opt::Instruction* op_inst =
         context->get_def_use_mgr()->GetDef(inst->GetSingleWordInOperand(0u));
     if (HasFloatingPoint(type) && !op_inst->IsFloatingPointFoldingAllowed())
       return false;
@@ -279,18 +279,18 @@
 // -(x / 2) = x / -2
 // -(2 / x) = -2 / x
 FoldingRule MergeNegateMulDivArithmetic() {
-  return [](ir::Instruction* inst,
+  return [](opt::Instruction* inst,
             const std::vector<const analysis::Constant*>& constants) {
     assert(inst->opcode() == SpvOpFNegate || inst->opcode() == SpvOpSNegate);
     (void)constants;
-    ir::IRContext* context = inst->context();
+    opt::IRContext* context = inst->context();
     analysis::ConstantManager* const_mgr = context->get_constant_mgr();
     const analysis::Type* type =
         context->get_type_mgr()->GetType(inst->type_id());
     if (HasFloatingPoint(type) && !inst->IsFloatingPointFoldingAllowed())
       return false;
 
-    ir::Instruction* op_inst =
+    opt::Instruction* op_inst =
         context->get_def_use_mgr()->GetDef(inst->GetSingleWordInOperand(0u));
     if (HasFloatingPoint(type) && !op_inst->IsFloatingPointFoldingAllowed())
       return false;
@@ -338,18 +338,18 @@
 // -(x - 2) = 2 - x
 // -(2 - x) = x - 2
 FoldingRule MergeNegateAddSubArithmetic() {
-  return [](ir::Instruction* inst,
+  return [](opt::Instruction* inst,
             const std::vector<const analysis::Constant*>& constants) {
     assert(inst->opcode() == SpvOpFNegate || inst->opcode() == SpvOpSNegate);
     (void)constants;
-    ir::IRContext* context = inst->context();
+    opt::IRContext* context = inst->context();
     analysis::ConstantManager* const_mgr = context->get_constant_mgr();
     const analysis::Type* type =
         context->get_type_mgr()->GetType(inst->type_id());
     if (HasFloatingPoint(type) && !inst->IsFloatingPointFoldingAllowed())
       return false;
 
-    ir::Instruction* op_inst =
+    opt::Instruction* op_inst =
         context->get_def_use_mgr()->GetDef(inst->GetSingleWordInOperand(0u));
     if (HasFloatingPoint(type) && !op_inst->IsFloatingPointFoldingAllowed())
       return false;
@@ -571,10 +571,10 @@
 // (x * 2) * 2 = x * 4
 // (2 * x) * 2 = x * 4
 FoldingRule MergeMulMulArithmetic() {
-  return [](ir::Instruction* inst,
+  return [](opt::Instruction* inst,
             const std::vector<const analysis::Constant*>& constants) {
     assert(inst->opcode() == SpvOpFMul || inst->opcode() == SpvOpIMul);
-    ir::IRContext* context = inst->context();
+    opt::IRContext* context = inst->context();
     analysis::ConstantManager* const_mgr = context->get_constant_mgr();
     const analysis::Type* type =
         context->get_type_mgr()->GetType(inst->type_id());
@@ -587,7 +587,7 @@
     // Determine the constant input and the variable input in |inst|.
     const analysis::Constant* const_input1 = ConstInput(constants);
     if (!const_input1) return false;
-    ir::Instruction* other_inst = NonConstInput(context, constants[0], inst);
+    opt::Instruction* other_inst = NonConstInput(context, constants[0], inst);
     if (HasFloatingPoint(type) && !other_inst->IsFloatingPointFoldingAllowed())
       return false;
 
@@ -624,10 +624,10 @@
 // (y / x) * x = y
 // x * (y / x) = y
 FoldingRule MergeMulDivArithmetic() {
-  return [](ir::Instruction* inst,
+  return [](opt::Instruction* inst,
             const std::vector<const analysis::Constant*>& constants) {
     assert(inst->opcode() == SpvOpFMul);
-    ir::IRContext* context = inst->context();
+    opt::IRContext* context = inst->context();
     analysis::ConstantManager* const_mgr = context->get_constant_mgr();
     analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr();
 
@@ -640,7 +640,7 @@
 
     for (uint32_t i = 0; i < 2; i++) {
       uint32_t op_id = inst->GetSingleWordInOperand(i);
-      ir::Instruction* op_inst = def_use_mgr->GetDef(op_id);
+      opt::Instruction* op_inst = def_use_mgr->GetDef(op_id);
       if (op_inst->opcode() == SpvOpFDiv) {
         if (op_inst->GetSingleWordInOperand(1) ==
             inst->GetSingleWordInOperand(1 - i)) {
@@ -654,7 +654,7 @@
 
     const analysis::Constant* const_input1 = ConstInput(constants);
     if (!const_input1) return false;
-    ir::Instruction* other_inst = NonConstInput(context, constants[0], inst);
+    opt::Instruction* other_inst = NonConstInput(context, constants[0], inst);
     if (!other_inst->IsFloatingPointFoldingAllowed()) return false;
 
     if (other_inst->opcode() == SpvOpFDiv) {
@@ -699,10 +699,10 @@
 // (-x) * 2 = x * -2
 // 2 * (-x) = x * -2
 FoldingRule MergeMulNegateArithmetic() {
-  return [](ir::Instruction* inst,
+  return [](opt::Instruction* inst,
             const std::vector<const analysis::Constant*>& constants) {
     assert(inst->opcode() == SpvOpFMul || inst->opcode() == SpvOpIMul);
-    ir::IRContext* context = inst->context();
+    opt::IRContext* context = inst->context();
     analysis::ConstantManager* const_mgr = context->get_constant_mgr();
     const analysis::Type* type =
         context->get_type_mgr()->GetType(inst->type_id());
@@ -714,7 +714,7 @@
 
     const analysis::Constant* const_input1 = ConstInput(constants);
     if (!const_input1) return false;
-    ir::Instruction* other_inst = NonConstInput(context, constants[0], inst);
+    opt::Instruction* other_inst = NonConstInput(context, constants[0], inst);
     if (uses_float && !other_inst->IsFloatingPointFoldingAllowed())
       return false;
 
@@ -740,10 +740,10 @@
 // (4 / x) / 2 = 2 / x
 // (x / 2) / 2 = x / 4
 FoldingRule MergeDivDivArithmetic() {
-  return [](ir::Instruction* inst,
+  return [](opt::Instruction* inst,
             const std::vector<const analysis::Constant*>& constants) {
     assert(inst->opcode() == SpvOpFDiv);
-    ir::IRContext* context = inst->context();
+    opt::IRContext* context = inst->context();
     analysis::ConstantManager* const_mgr = context->get_constant_mgr();
     const analysis::Type* type =
         context->get_type_mgr()->GetType(inst->type_id());
@@ -754,7 +754,7 @@
 
     const analysis::Constant* const_input1 = ConstInput(constants);
     if (!const_input1 || HasZero(const_input1)) return false;
-    ir::Instruction* other_inst = NonConstInput(context, constants[0], inst);
+    opt::Instruction* other_inst = NonConstInput(context, constants[0], inst);
     if (!other_inst->IsFloatingPointFoldingAllowed()) return false;
 
     bool first_is_variable = constants[0] == nullptr;
@@ -812,10 +812,10 @@
 // (x * y) / x = y
 // (y * x) / x = y
 FoldingRule MergeDivMulArithmetic() {
-  return [](ir::Instruction* inst,
+  return [](opt::Instruction* inst,
             const std::vector<const analysis::Constant*>& constants) {
     assert(inst->opcode() == SpvOpFDiv);
-    ir::IRContext* context = inst->context();
+    opt::IRContext* context = inst->context();
     analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr();
     analysis::ConstantManager* const_mgr = context->get_constant_mgr();
 
@@ -827,7 +827,7 @@
     if (width != 32 && width != 64) return false;
 
     uint32_t op_id = inst->GetSingleWordInOperand(0);
-    ir::Instruction* op_inst = def_use_mgr->GetDef(op_id);
+    opt::Instruction* op_inst = def_use_mgr->GetDef(op_id);
 
     if (op_inst->opcode() == SpvOpFMul) {
       for (uint32_t i = 0; i < 2; i++) {
@@ -843,7 +843,7 @@
 
     const analysis::Constant* const_input1 = ConstInput(constants);
     if (!const_input1 || HasZero(const_input1)) return false;
-    ir::Instruction* other_inst = NonConstInput(context, constants[0], inst);
+    opt::Instruction* other_inst = NonConstInput(context, constants[0], inst);
     if (!other_inst->IsFloatingPointFoldingAllowed()) return false;
 
     bool first_is_variable = constants[0] == nullptr;
@@ -885,11 +885,11 @@
 // (-x) / 2 = x / -2
 // 2 / (-x) = 2 / -x
 FoldingRule MergeDivNegateArithmetic() {
-  return [](ir::Instruction* inst,
+  return [](opt::Instruction* inst,
             const std::vector<const analysis::Constant*>& constants) {
     assert(inst->opcode() == SpvOpFDiv || inst->opcode() == SpvOpSDiv ||
            inst->opcode() == SpvOpUDiv);
-    ir::IRContext* context = inst->context();
+    opt::IRContext* context = inst->context();
     analysis::ConstantManager* const_mgr = context->get_constant_mgr();
     const analysis::Type* type =
         context->get_type_mgr()->GetType(inst->type_id());
@@ -901,7 +901,7 @@
 
     const analysis::Constant* const_input1 = ConstInput(constants);
     if (!const_input1) return false;
-    ir::Instruction* other_inst = NonConstInput(context, constants[0], inst);
+    opt::Instruction* other_inst = NonConstInput(context, constants[0], inst);
     if (uses_float && !other_inst->IsFloatingPointFoldingAllowed())
       return false;
 
@@ -931,10 +931,10 @@
 // (-x) + 2 = 2 - x
 // 2 + (-x) = 2 - x
 FoldingRule MergeAddNegateArithmetic() {
-  return [](ir::Instruction* inst,
+  return [](opt::Instruction* inst,
             const std::vector<const analysis::Constant*>& constants) {
     assert(inst->opcode() == SpvOpFAdd || inst->opcode() == SpvOpIAdd);
-    ir::IRContext* context = inst->context();
+    opt::IRContext* context = inst->context();
     const analysis::Type* type =
         context->get_type_mgr()->GetType(inst->type_id());
     bool uses_float = HasFloatingPoint(type);
@@ -942,7 +942,7 @@
 
     const analysis::Constant* const_input1 = ConstInput(constants);
     if (!const_input1) return false;
-    ir::Instruction* other_inst = NonConstInput(context, constants[0], inst);
+    opt::Instruction* other_inst = NonConstInput(context, constants[0], inst);
     if (uses_float && !other_inst->IsFloatingPointFoldingAllowed())
       return false;
 
@@ -965,10 +965,10 @@
 // (-x) - 2 = -2 - x
 // 2 - (-x) = x + 2
 FoldingRule MergeSubNegateArithmetic() {
-  return [](ir::Instruction* inst,
+  return [](opt::Instruction* inst,
             const std::vector<const analysis::Constant*>& constants) {
     assert(inst->opcode() == SpvOpFSub || inst->opcode() == SpvOpISub);
-    ir::IRContext* context = inst->context();
+    opt::IRContext* context = inst->context();
     analysis::ConstantManager* const_mgr = context->get_constant_mgr();
     const analysis::Type* type =
         context->get_type_mgr()->GetType(inst->type_id());
@@ -980,7 +980,7 @@
 
     const analysis::Constant* const_input1 = ConstInput(constants);
     if (!const_input1) return false;
-    ir::Instruction* other_inst = NonConstInput(context, constants[0], inst);
+    opt::Instruction* other_inst = NonConstInput(context, constants[0], inst);
     if (uses_float && !other_inst->IsFloatingPointFoldingAllowed())
       return false;
 
@@ -1014,10 +1014,10 @@
 // 2 + (x + 2) = x + 4
 // 2 + (2 + x) = x + 4
 FoldingRule MergeAddAddArithmetic() {
-  return [](ir::Instruction* inst,
+  return [](opt::Instruction* inst,
             const std::vector<const analysis::Constant*>& constants) {
     assert(inst->opcode() == SpvOpFAdd || inst->opcode() == SpvOpIAdd);
-    ir::IRContext* context = inst->context();
+    opt::IRContext* context = inst->context();
     const analysis::Type* type =
         context->get_type_mgr()->GetType(inst->type_id());
     analysis::ConstantManager* const_mgr = context->get_constant_mgr();
@@ -1029,7 +1029,7 @@
 
     const analysis::Constant* const_input1 = ConstInput(constants);
     if (!const_input1) return false;
-    ir::Instruction* other_inst = NonConstInput(context, constants[0], inst);
+    opt::Instruction* other_inst = NonConstInput(context, constants[0], inst);
     if (uses_float && !other_inst->IsFloatingPointFoldingAllowed())
       return false;
 
@@ -1040,7 +1040,7 @@
       const analysis::Constant* const_input2 = ConstInput(other_constants);
       if (!const_input2) return false;
 
-      ir::Instruction* non_const_input =
+      opt::Instruction* non_const_input =
           NonConstInput(context, other_constants[0], other_inst);
       uint32_t merged_id = PerformOperation(const_mgr, inst->opcode(),
                                             const_input1, const_input2);
@@ -1062,10 +1062,10 @@
 // 2 + (x - 2) = x + 0
 // 2 + (2 - x) = 4 - x
 FoldingRule MergeAddSubArithmetic() {
-  return [](ir::Instruction* inst,
+  return [](opt::Instruction* inst,
             const std::vector<const analysis::Constant*>& constants) {
     assert(inst->opcode() == SpvOpFAdd || inst->opcode() == SpvOpIAdd);
-    ir::IRContext* context = inst->context();
+    opt::IRContext* context = inst->context();
     const analysis::Type* type =
         context->get_type_mgr()->GetType(inst->type_id());
     analysis::ConstantManager* const_mgr = context->get_constant_mgr();
@@ -1077,7 +1077,7 @@
 
     const analysis::Constant* const_input1 = ConstInput(constants);
     if (!const_input1) return false;
-    ir::Instruction* other_inst = NonConstInput(context, constants[0], inst);
+    opt::Instruction* other_inst = NonConstInput(context, constants[0], inst);
     if (uses_float && !other_inst->IsFloatingPointFoldingAllowed())
       return false;
 
@@ -1122,10 +1122,10 @@
 // 2 - (x + 2) = 0 - x
 // 2 - (2 + x) = 0 - x
 FoldingRule MergeSubAddArithmetic() {
-  return [](ir::Instruction* inst,
+  return [](opt::Instruction* inst,
             const std::vector<const analysis::Constant*>& constants) {
     assert(inst->opcode() == SpvOpFSub || inst->opcode() == SpvOpISub);
-    ir::IRContext* context = inst->context();
+    opt::IRContext* context = inst->context();
     const analysis::Type* type =
         context->get_type_mgr()->GetType(inst->type_id());
     analysis::ConstantManager* const_mgr = context->get_constant_mgr();
@@ -1137,7 +1137,7 @@
 
     const analysis::Constant* const_input1 = ConstInput(constants);
     if (!const_input1) return false;
-    ir::Instruction* other_inst = NonConstInput(context, constants[0], inst);
+    opt::Instruction* other_inst = NonConstInput(context, constants[0], inst);
     if (uses_float && !other_inst->IsFloatingPointFoldingAllowed())
       return false;
 
@@ -1148,7 +1148,7 @@
       const analysis::Constant* const_input2 = ConstInput(other_constants);
       if (!const_input2) return false;
 
-      ir::Instruction* non_const_input =
+      opt::Instruction* non_const_input =
           NonConstInput(context, other_constants[0], other_inst);
 
       // If the first operand of the sub is not a constant, swap the constants
@@ -1188,10 +1188,10 @@
 // 2 - (x - 2) = 4 - x
 // 2 - (2 - x) = x + 0
 FoldingRule MergeSubSubArithmetic() {
-  return [](ir::Instruction* inst,
+  return [](opt::Instruction* inst,
             const std::vector<const analysis::Constant*>& constants) {
     assert(inst->opcode() == SpvOpFSub || inst->opcode() == SpvOpISub);
-    ir::IRContext* context = inst->context();
+    opt::IRContext* context = inst->context();
     const analysis::Type* type =
         context->get_type_mgr()->GetType(inst->type_id());
     analysis::ConstantManager* const_mgr = context->get_constant_mgr();
@@ -1203,7 +1203,7 @@
 
     const analysis::Constant* const_input1 = ConstInput(constants);
     if (!const_input1) return false;
-    ir::Instruction* other_inst = NonConstInput(context, constants[0], inst);
+    opt::Instruction* other_inst = NonConstInput(context, constants[0], inst);
     if (uses_float && !other_inst->IsFloatingPointFoldingAllowed())
       return false;
 
@@ -1214,7 +1214,7 @@
       const analysis::Constant* const_input2 = ConstInput(other_constants);
       if (!const_input2) return false;
 
-      ir::Instruction* non_const_input =
+      opt::Instruction* non_const_input =
           NonConstInput(context, other_constants[0], other_inst);
 
       // Merge the constants.
@@ -1255,7 +1255,7 @@
 }
 
 FoldingRule IntMultipleBy1() {
-  return [](ir::Instruction* inst,
+  return [](opt::Instruction* inst,
             const std::vector<const analysis::Constant*>& constants) {
     assert(inst->opcode() == SpvOpIMul && "Wrong opcode.  Should be OpIMul.");
     for (uint32_t i = 0; i < 2; i++) {
@@ -1281,7 +1281,7 @@
 }
 
 FoldingRule CompositeConstructFeedingExtract() {
-  return [](ir::Instruction* inst,
+  return [](opt::Instruction* inst,
             const std::vector<const analysis::Constant*>&) {
     // If the input to an OpCompositeExtract is an OpCompositeConstruct,
     // then we can simply use the appropriate element in the construction.
@@ -1290,13 +1290,13 @@
     analysis::DefUseManager* def_use_mgr = inst->context()->get_def_use_mgr();
     analysis::TypeManager* type_mgr = inst->context()->get_type_mgr();
     uint32_t cid = inst->GetSingleWordInOperand(kExtractCompositeIdInIdx);
-    ir::Instruction* cinst = def_use_mgr->GetDef(cid);
+    opt::Instruction* cinst = def_use_mgr->GetDef(cid);
 
     if (cinst->opcode() != SpvOpCompositeConstruct) {
       return false;
     }
 
-    std::vector<ir::Operand> operands;
+    std::vector<opt::Operand> operands;
     analysis::Type* composite_type = type_mgr->GetType(cinst->type_id());
     if (composite_type->AsVector() == nullptr) {
       // Get the element being extracted from the OpCompositeConstruct
@@ -1321,7 +1321,7 @@
       for (uint32_t construct_index = 0;
            construct_index < cinst->NumInOperands(); ++construct_index) {
         uint32_t element_id = cinst->GetSingleWordInOperand(construct_index);
-        ir::Instruction* element_def = def_use_mgr->GetDef(element_id);
+        opt::Instruction* element_def = def_use_mgr->GetDef(element_id);
         analysis::Vector* element_type =
             type_mgr->GetType(element_def->type_id())->AsVector();
         if (element_type) {
@@ -1366,7 +1366,7 @@
   //
   // This is a common code pattern because of the way that scalar replacement
   // works.
-  return [](ir::Instruction* inst,
+  return [](opt::Instruction* inst,
             const std::vector<const analysis::Constant*>&) {
     assert(inst->opcode() == SpvOpCompositeConstruct &&
            "Wrong opcode.  Should be OpCompositeConstruct.");
@@ -1379,7 +1379,7 @@
     // - all extract from the same id.
     for (uint32_t i = 0; i < inst->NumInOperands(); ++i) {
       uint32_t element_id = inst->GetSingleWordInOperand(i);
-      ir::Instruction* element_inst = def_use_mgr->GetDef(element_id);
+      opt::Instruction* element_inst = def_use_mgr->GetDef(element_id);
 
       if (element_inst->opcode() != SpvOpCompositeExtract) {
         return false;
@@ -1404,7 +1404,7 @@
 
     // The last check it to see that the object being extracted from is the
     // correct type.
-    ir::Instruction* original_inst = def_use_mgr->GetDef(original_id);
+    opt::Instruction* original_inst = def_use_mgr->GetDef(original_id);
     if (original_inst->type_id() != inst->type_id()) {
       return false;
     }
@@ -1417,13 +1417,13 @@
 }
 
 FoldingRule InsertFeedingExtract() {
-  return [](ir::Instruction* inst,
+  return [](opt::Instruction* inst,
             const std::vector<const analysis::Constant*>&) {
     assert(inst->opcode() == SpvOpCompositeExtract &&
            "Wrong opcode.  Should be OpCompositeExtract.");
     analysis::DefUseManager* def_use_mgr = inst->context()->get_def_use_mgr();
     uint32_t cid = inst->GetSingleWordInOperand(kExtractCompositeIdInIdx);
-    ir::Instruction* cinst = def_use_mgr->GetDef(cid);
+    opt::Instruction* cinst = def_use_mgr->GetDef(cid);
 
     if (cinst->opcode() != SpvOpCompositeInsert) {
       return false;
@@ -1461,7 +1461,7 @@
     // Extracting an element of the value that was inserted.  Extract from
     // that value directly.
     if (i + 1 == cinst->NumInOperands()) {
-      std::vector<ir::Operand> operands;
+      std::vector<opt::Operand> operands;
       operands.push_back(
           {SPV_OPERAND_TYPE_ID,
            {cinst->GetSingleWordInOperand(kInsertObjectIdInIdx)}});
@@ -1475,7 +1475,7 @@
 
     // Extracting a value that is disjoint from the element being inserted.
     // Rewrite the extract to use the composite input to the insert.
-    std::vector<ir::Operand> operands;
+    std::vector<opt::Operand> operands;
     operands.push_back(
         {SPV_OPERAND_TYPE_ID,
          {cinst->GetSingleWordInOperand(kInsertCompositeIdInIdx)}});
@@ -1492,21 +1492,21 @@
 // operands of the VectorShuffle.  We just need to adjust the index in the
 // extract instruction.
 FoldingRule VectorShuffleFeedingExtract() {
-  return [](ir::Instruction* inst,
+  return [](opt::Instruction* inst,
             const std::vector<const analysis::Constant*>&) {
     assert(inst->opcode() == SpvOpCompositeExtract &&
            "Wrong opcode.  Should be OpCompositeExtract.");
     analysis::DefUseManager* def_use_mgr = inst->context()->get_def_use_mgr();
     analysis::TypeManager* type_mgr = inst->context()->get_type_mgr();
     uint32_t cid = inst->GetSingleWordInOperand(kExtractCompositeIdInIdx);
-    ir::Instruction* cinst = def_use_mgr->GetDef(cid);
+    opt::Instruction* cinst = def_use_mgr->GetDef(cid);
 
     if (cinst->opcode() != SpvOpVectorShuffle) {
       return false;
     }
 
     // Find the size of the first vector operand of the VectorShuffle
-    ir::Instruction* first_input =
+    opt::Instruction* first_input =
         def_use_mgr->GetDef(cinst->GetSingleWordInOperand(0));
     analysis::Type* first_input_type =
         type_mgr->GetType(first_input->type_id());
@@ -1541,16 +1541,17 @@
 // operands of the FMix.
 FoldingRule FMixFeedingExtract() {
   return
-      [](ir::Instruction* inst, const std::vector<const analysis::Constant*>&) {
+      [](opt::Instruction* inst,
+         const std::vector<const analysis::Constant*>&) {
         assert(inst->opcode() == SpvOpCompositeExtract &&
                "Wrong opcode.  Should be OpCompositeExtract.");
-        ir::IRContext* context = inst->context();
+        opt::IRContext* context = inst->context();
         analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr();
         analysis::ConstantManager* const_mgr = context->get_constant_mgr();
 
         uint32_t composite_id =
             inst->GetSingleWordInOperand(kExtractCompositeIdInIdx);
-        ir::Instruction* composite_inst = def_use_mgr->GetDef(composite_id);
+        opt::Instruction* composite_inst = def_use_mgr->GetDef(composite_id);
 
         if (composite_inst->opcode() != SpvOpExtInst) {
           return false;
@@ -1568,7 +1569,7 @@
 
         // Get the |a| for the FMix instruction.
         uint32_t a_id = composite_inst->GetSingleWordInOperand(kFMixAIdInIdx);
-        std::unique_ptr<ir::Instruction> a(inst->Clone(inst->context()));
+        std::unique_ptr<opt::Instruction> a(inst->Clone(inst->context()));
         a->SetInOperand(kExtractCompositeIdInIdx, {a_id});
         context->get_instruction_folder().FoldInstruction(a.get());
 
@@ -1612,42 +1613,42 @@
 FoldingRule RedundantPhi() {
   // An OpPhi instruction where all values are the same or the result of the phi
   // itself, can be replaced by the value itself.
-  return
-      [](ir::Instruction* inst, const std::vector<const analysis::Constant*>&) {
-        assert(inst->opcode() == SpvOpPhi && "Wrong opcode.  Should be OpPhi.");
+  return [](opt::Instruction* inst,
+            const std::vector<const analysis::Constant*>&) {
+    assert(inst->opcode() == SpvOpPhi && "Wrong opcode.  Should be OpPhi.");
 
-        uint32_t incoming_value = 0;
+    uint32_t incoming_value = 0;
 
-        for (uint32_t i = 0; i < inst->NumInOperands(); i += 2) {
-          uint32_t op_id = inst->GetSingleWordInOperand(i);
-          if (op_id == inst->result_id()) {
-            continue;
-          }
+    for (uint32_t i = 0; i < inst->NumInOperands(); i += 2) {
+      uint32_t op_id = inst->GetSingleWordInOperand(i);
+      if (op_id == inst->result_id()) {
+        continue;
+      }
 
-          if (incoming_value == 0) {
-            incoming_value = op_id;
-          } else if (op_id != incoming_value) {
-            // Found two possible value.  Can't simplify.
-            return false;
-          }
-        }
+      if (incoming_value == 0) {
+        incoming_value = op_id;
+      } else if (op_id != incoming_value) {
+        // Found two possible value.  Can't simplify.
+        return false;
+      }
+    }
 
-        if (incoming_value == 0) {
-          // Code looks invalid.  Don't do anything.
-          return false;
-        }
+    if (incoming_value == 0) {
+      // Code looks invalid.  Don't do anything.
+      return false;
+    }
 
-        // We have a single incoming value.  Simplify using that value.
-        inst->SetOpcode(SpvOpCopyObject);
-        inst->SetInOperands({{SPV_OPERAND_TYPE_ID, {incoming_value}}});
-        return true;
-      };
+    // We have a single incoming value.  Simplify using that value.
+    inst->SetOpcode(SpvOpCopyObject);
+    inst->SetInOperands({{SPV_OPERAND_TYPE_ID, {incoming_value}}});
+    return true;
+  };
 }
 
 FoldingRule RedundantSelect() {
   // An OpSelect instruction where both values are the same or the condition is
   // constant can be replaced by one of the values
-  return [](ir::Instruction* inst,
+  return [](opt::Instruction* inst,
             const std::vector<const analysis::Constant*>& constants) {
     assert(inst->opcode() == SpvOpSelect &&
            "Wrong opcode.  Should be OpSelect.");
@@ -1683,7 +1684,7 @@
           return true;
         } else {
           // Convert to a vector shuffle.
-          std::vector<ir::Operand> ops;
+          std::vector<opt::Operand> ops;
           ops.push_back({SPV_OPERAND_TYPE_ID, {true_id}});
           ops.push_back({SPV_OPERAND_TYPE_ID, {false_id}});
           const analysis::VectorConstant* vector_const =
@@ -1763,7 +1764,7 @@
 }
 
 FoldingRule RedundantFAdd() {
-  return [](ir::Instruction* inst,
+  return [](opt::Instruction* inst,
             const std::vector<const analysis::Constant*>& constants) {
     assert(inst->opcode() == SpvOpFAdd && "Wrong opcode.  Should be OpFAdd.");
     assert(constants.size() == 2);
@@ -1788,7 +1789,7 @@
 }
 
 FoldingRule RedundantFSub() {
-  return [](ir::Instruction* inst,
+  return [](opt::Instruction* inst,
             const std::vector<const analysis::Constant*>& constants) {
     assert(inst->opcode() == SpvOpFSub && "Wrong opcode.  Should be OpFSub.");
     assert(constants.size() == 2);
@@ -1819,7 +1820,7 @@
 }
 
 FoldingRule RedundantFMul() {
-  return [](ir::Instruction* inst,
+  return [](opt::Instruction* inst,
             const std::vector<const analysis::Constant*>& constants) {
     assert(inst->opcode() == SpvOpFMul && "Wrong opcode.  Should be OpFMul.");
     assert(constants.size() == 2);
@@ -1852,7 +1853,7 @@
 }
 
 FoldingRule RedundantFDiv() {
-  return [](ir::Instruction* inst,
+  return [](opt::Instruction* inst,
             const std::vector<const analysis::Constant*>& constants) {
     assert(inst->opcode() == SpvOpFDiv && "Wrong opcode.  Should be OpFDiv.");
     assert(constants.size() == 2);
@@ -1883,7 +1884,7 @@
 }
 
 FoldingRule RedundantFMix() {
-  return [](ir::Instruction* inst,
+  return [](opt::Instruction* inst,
             const std::vector<const analysis::Constant*>& constants) {
     assert(inst->opcode() == SpvOpExtInst &&
            "Wrong opcode.  Should be OpExtInst.");
@@ -1920,11 +1921,11 @@
 // This rule look for a dot with a constant vector containing a single 1 and
 // the rest 0s.  This is the same as doing an extract.
 FoldingRule DotProductDoingExtract() {
-  return [](ir::Instruction* inst,
+  return [](opt::Instruction* inst,
             const std::vector<const analysis::Constant*>& constants) {
     assert(inst->opcode() == SpvOpDot && "Wrong opcode.  Should be OpDot.");
 
-    ir::IRContext* context = inst->context();
+    opt::IRContext* context = inst->context();
     analysis::ConstantManager* const_mgr = context->get_constant_mgr();
 
     if (!inst->IsFloatingPointFoldingAllowed()) {
@@ -1976,7 +1977,7 @@
         continue;
       }
 
-      std::vector<ir::Operand> operands;
+      std::vector<opt::Operand> operands;
       operands.push_back(
           {SPV_OPERAND_TYPE_ID, {inst->GetSingleWordInOperand(1u - i)}});
       operands.push_back(
@@ -1995,11 +1996,11 @@
 // TODO: We can do something similar for OpImageWrite, but checking for volatile
 // is complicated.  Waiting to see if it is needed.
 FoldingRule StoringUndef() {
-  return [](ir::Instruction* inst,
+  return [](opt::Instruction* inst,
             const std::vector<const analysis::Constant*>&) {
     assert(inst->opcode() == SpvOpStore && "Wrong opcode.  Should be OpStore.");
 
-    ir::IRContext* context = inst->context();
+    opt::IRContext* context = inst->context();
     analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr();
 
     // If this is a volatile store, the store cannot be removed.
@@ -2010,7 +2011,7 @@
     }
 
     uint32_t object_id = inst->GetSingleWordInOperand(kStoreObjectInIdx);
-    ir::Instruction* object_inst = def_use_mgr->GetDef(object_id);
+    opt::Instruction* object_inst = def_use_mgr->GetDef(object_id);
     if (object_inst->opcode() == SpvOpUndef) {
       inst->ToNop();
       return true;
diff --git a/source/opt/folding_rules.h b/source/opt/folding_rules.h
index ddedf2b..19fe217 100644
--- a/source/opt/folding_rules.h
+++ b/source/opt/folding_rules.h
@@ -52,7 +52,7 @@
 // the later rules will not be attempted.
 
 using FoldingRule = std::function<bool(
-    ir::Instruction* inst,
+    opt::Instruction* inst,
     const std::vector<const analysis::Constant*>& constants)>;
 
 class FoldingRules {
diff --git a/source/opt/freeze_spec_constant_value_pass.cpp b/source/opt/freeze_spec_constant_value_pass.cpp
index ef589b0..15ba05e 100644
--- a/source/opt/freeze_spec_constant_value_pass.cpp
+++ b/source/opt/freeze_spec_constant_value_pass.cpp
@@ -18,10 +18,10 @@
 namespace spvtools {
 namespace opt {
 
-Pass::Status FreezeSpecConstantValuePass::Process(ir::IRContext* irContext) {
+Pass::Status FreezeSpecConstantValuePass::Process(opt::IRContext* irContext) {
   bool modified = false;
   irContext->module()->ForEachInst(
-      [&modified, irContext](ir::Instruction* inst) {
+      [&modified, irContext](opt::Instruction* inst) {
         switch (inst->opcode()) {
           case SpvOp::SpvOpSpecConstant:
             inst->SetOpcode(SpvOp::SpvOpConstant);
diff --git a/source/opt/freeze_spec_constant_value_pass.h b/source/opt/freeze_spec_constant_value_pass.h
index fc7f44e..bd27252 100644
--- a/source/opt/freeze_spec_constant_value_pass.h
+++ b/source/opt/freeze_spec_constant_value_pass.h
@@ -26,7 +26,7 @@
 class FreezeSpecConstantValuePass : public Pass {
  public:
   const char* name() const override { return "freeze-spec-const"; }
-  Status Process(ir::IRContext*) override;
+  Status Process(opt::IRContext*) override;
 };
 
 }  // namespace opt
diff --git a/source/opt/function.cpp b/source/opt/function.cpp
index 5a648eb..943022e 100644
--- a/source/opt/function.cpp
+++ b/source/opt/function.cpp
@@ -18,7 +18,7 @@
 #include <sstream>
 
 namespace spvtools {
-namespace ir {
+namespace opt {
 
 Function* Function::Clone(IRContext* ctx) const {
   Function* clone =
@@ -96,7 +96,7 @@
 
 std::string Function::PrettyPrint(uint32_t options) const {
   std::ostringstream str;
-  ForEachInst([&str, options](const ir::Instruction* inst) {
+  ForEachInst([&str, options](const opt::Instruction* inst) {
     str << inst->PrettyPrint(options);
     if (inst->opcode() != SpvOpFunctionEnd) {
       str << std::endl;
@@ -105,5 +105,5 @@
   return str.str();
 }
 
-}  // namespace ir
+}  // namespace opt
 }  // namespace spvtools
diff --git a/source/opt/function.h b/source/opt/function.h
index 2ef4acc..1f2a318 100644
--- a/source/opt/function.h
+++ b/source/opt/function.h
@@ -26,7 +26,7 @@
 #include "iterator.h"
 
 namespace spvtools {
-namespace ir {
+namespace opt {
 
 class CFG;
 class IRContext;
@@ -102,7 +102,7 @@
 
   // Returns an iterator to the basic block |id|.
   iterator FindBlock(uint32_t bb_id) {
-    return std::find_if(begin(), end(), [bb_id](const ir::BasicBlock& it_bb) {
+    return std::find_if(begin(), end(), [bb_id](const opt::BasicBlock& it_bb) {
       return bb_id == it_bb.id();
     });
   }
@@ -122,8 +122,8 @@
   // Returns the context of the current function.
   IRContext* context() const { return def_inst_->context(); }
 
-  BasicBlock* InsertBasicBlockAfter(std::unique_ptr<ir::BasicBlock>&& new_block,
-                                    BasicBlock* position);
+  BasicBlock* InsertBasicBlockAfter(
+      std::unique_ptr<opt::BasicBlock>&& new_block, BasicBlock* position);
 
   // Pretty-prints all the basic blocks in this function into a std::string.
   //
@@ -192,7 +192,7 @@
   end_inst_ = std::move(end_inst);
 }
 
-}  // namespace ir
+}  // namespace opt
 }  // namespace spvtools
 
 #endif  // LIBSPIRV_OPT_CONSTRUCTS_H_
diff --git a/source/opt/if_conversion.cpp b/source/opt/if_conversion.cpp
index adaab14..151b758 100644
--- a/source/opt/if_conversion.cpp
+++ b/source/opt/if_conversion.cpp
@@ -19,18 +19,18 @@
 namespace spvtools {
 namespace opt {
 
-Pass::Status IfConversion::Process(ir::IRContext* c) {
+Pass::Status IfConversion::Process(opt::IRContext* c) {
   InitializeProcessing(c);
 
   const ValueNumberTable& vn_table = *context()->GetValueNumberTable();
   bool modified = false;
-  std::vector<ir::Instruction*> to_kill;
+  std::vector<opt::Instruction*> to_kill;
   for (auto& func : *get_module()) {
     DominatorAnalysis* dominators = context()->GetDominatorAnalysis(&func);
     for (auto& block : func) {
       // Check if it is possible for |block| to have phis that can be
       // transformed.
-      ir::BasicBlock* common = nullptr;
+      opt::BasicBlock* common = nullptr;
       if (!CheckBlock(&block, dominators, &common)) continue;
 
       // Get an insertion point.
@@ -41,11 +41,11 @@
 
       InstructionBuilder builder(
           context(), &*iter,
-          ir::IRContext::kAnalysisDefUse |
-              ir::IRContext::kAnalysisInstrToBlockMapping);
+          opt::IRContext::kAnalysisDefUse |
+              opt::IRContext::kAnalysisInstrToBlockMapping);
       block.ForEachPhiInst([this, &builder, &modified, &common, &to_kill,
                             dominators, &block,
-                            &vn_table](ir::Instruction* phi) {
+                            &vn_table](opt::Instruction* phi) {
         // This phi is not compatible, but subsequent phis might be.
         if (!CheckType(phi->type_id())) return;
 
@@ -59,13 +59,13 @@
         // branches. If |then_block| dominates |inc0| or if the true edge
         // branches straight to this block and |common| is |inc0|, then |inc0|
         // is on the true branch. Otherwise the |inc1| is on the true branch.
-        ir::BasicBlock* inc0 = GetIncomingBlock(phi, 0u);
-        ir::Instruction* branch = common->terminator();
+        opt::BasicBlock* inc0 = GetIncomingBlock(phi, 0u);
+        opt::Instruction* branch = common->terminator();
         uint32_t condition = branch->GetSingleWordInOperand(0u);
-        ir::BasicBlock* then_block =
+        opt::BasicBlock* then_block =
             GetBlock(branch->GetSingleWordInOperand(1u));
-        ir::Instruction* true_value = nullptr;
-        ir::Instruction* false_value = nullptr;
+        opt::Instruction* true_value = nullptr;
+        opt::Instruction* false_value = nullptr;
         if ((then_block == &block && inc0 == common) ||
             dominators->Dominates(then_block, inc0)) {
           true_value = GetIncomingValue(phi, 0u);
@@ -75,14 +75,15 @@
           false_value = GetIncomingValue(phi, 0u);
         }
 
-        ir::BasicBlock* true_def_block = context()->get_instr_block(true_value);
-        ir::BasicBlock* false_def_block =
+        opt::BasicBlock* true_def_block =
+            context()->get_instr_block(true_value);
+        opt::BasicBlock* false_def_block =
             context()->get_instr_block(false_value);
 
         uint32_t true_vn = vn_table.GetValueNumber(true_value);
         uint32_t false_vn = vn_table.GetValueNumber(false_value);
         if (true_vn != 0 && true_vn == false_vn) {
-          ir::Instruction* inst_to_use = nullptr;
+          opt::Instruction* inst_to_use = nullptr;
 
           // Try to pick an instruction that is not in a side node.  If we can't
           // pick either the true for false branch as long as they can be
@@ -125,9 +126,9 @@
           condition = SplatCondition(vec_data_ty, condition, &builder);
         }
 
-        ir::Instruction* select = builder.AddSelect(phi->type_id(), condition,
-                                                    true_value->result_id(),
-                                                    false_value->result_id());
+        opt::Instruction* select = builder.AddSelect(phi->type_id(), condition,
+                                                     true_value->result_id(),
+                                                     false_value->result_id());
         context()->ReplaceAllUsesWith(phi->result_id(), select->result_id());
         to_kill.push_back(phi);
         modified = true;
@@ -144,18 +145,18 @@
   return modified ? Status::SuccessWithChange : Status::SuccessWithoutChange;
 }
 
-bool IfConversion::CheckBlock(ir::BasicBlock* block,
+bool IfConversion::CheckBlock(opt::BasicBlock* block,
                               DominatorAnalysis* dominators,
-                              ir::BasicBlock** common) {
+                              opt::BasicBlock** common) {
   const std::vector<uint32_t>& preds = cfg()->preds(block->id());
 
   // TODO(alan-baker): Extend to more than two predecessors
   if (preds.size() != 2) return false;
 
-  ir::BasicBlock* inc0 = context()->get_instr_block(preds[0]);
+  opt::BasicBlock* inc0 = context()->get_instr_block(preds[0]);
   if (dominators->Dominates(block, inc0)) return false;
 
-  ir::BasicBlock* inc1 = context()->get_instr_block(preds[1]);
+  opt::BasicBlock* inc1 = context()->get_instr_block(preds[1]);
   if (dominators->Dominates(block, inc1)) return false;
 
   // All phis will have the same common dominator, so cache the result
@@ -163,15 +164,16 @@
   // any phi in this basic block.
   *common = dominators->CommonDominator(inc0, inc1);
   if (!*common || cfg()->IsPseudoEntryBlock(*common)) return false;
-  ir::Instruction* branch = (*common)->terminator();
+  opt::Instruction* branch = (*common)->terminator();
   if (branch->opcode() != SpvOpBranchConditional) return false;
 
   return true;
 }
 
-bool IfConversion::CheckPhiUsers(ir::Instruction* phi, ir::BasicBlock* block) {
+bool IfConversion::CheckPhiUsers(opt::Instruction* phi,
+                                 opt::BasicBlock* block) {
   return get_def_use_mgr()->WhileEachUser(phi, [block,
-                                                this](ir::Instruction* user) {
+                                                this](opt::Instruction* user) {
     if (user->opcode() == SpvOpPhi && context()->get_instr_block(user) == block)
       return false;
     return true;
@@ -194,7 +196,7 @@
 }
 
 bool IfConversion::CheckType(uint32_t id) {
-  ir::Instruction* type = get_def_use_mgr()->GetDef(id);
+  opt::Instruction* type = get_def_use_mgr()->GetDef(id);
   SpvOp op = type->opcode();
   if (spvOpcodeIsScalarType(op) || op == SpvOpTypePointer ||
       op == SpvOpTypeVector)
@@ -202,26 +204,26 @@
   return false;
 }
 
-ir::BasicBlock* IfConversion::GetBlock(uint32_t id) {
+opt::BasicBlock* IfConversion::GetBlock(uint32_t id) {
   return context()->get_instr_block(get_def_use_mgr()->GetDef(id));
 }
 
-ir::BasicBlock* IfConversion::GetIncomingBlock(ir::Instruction* phi,
-                                               uint32_t predecessor) {
+opt::BasicBlock* IfConversion::GetIncomingBlock(opt::Instruction* phi,
+                                                uint32_t predecessor) {
   uint32_t in_index = 2 * predecessor + 1;
   return GetBlock(phi->GetSingleWordInOperand(in_index));
 }
 
-ir::Instruction* IfConversion::GetIncomingValue(ir::Instruction* phi,
-                                                uint32_t predecessor) {
+opt::Instruction* IfConversion::GetIncomingValue(opt::Instruction* phi,
+                                                 uint32_t predecessor) {
   uint32_t in_index = 2 * predecessor;
   return get_def_use_mgr()->GetDef(phi->GetSingleWordInOperand(in_index));
 }
 
-void IfConversion::HoistInstruction(ir::Instruction* inst,
-                                    ir::BasicBlock* target_block,
+void IfConversion::HoistInstruction(opt::Instruction* inst,
+                                    opt::BasicBlock* target_block,
                                     DominatorAnalysis* dominators) {
-  ir::BasicBlock* inst_block = context()->get_instr_block(inst);
+  opt::BasicBlock* inst_block = context()->get_instr_block(inst);
   if (!inst_block) {
     // This is in the header, and dominates everything.
     return;
@@ -239,23 +241,23 @@
   analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr();
   inst->ForEachInId(
       [this, target_block, def_use_mgr, dominators](uint32_t* id) {
-        ir::Instruction* operand_inst = def_use_mgr->GetDef(*id);
+        opt::Instruction* operand_inst = def_use_mgr->GetDef(*id);
         HoistInstruction(operand_inst, target_block, dominators);
       });
 
-  ir::Instruction* insertion_pos = target_block->terminator();
+  opt::Instruction* insertion_pos = target_block->terminator();
   if ((insertion_pos)->PreviousNode()->opcode() == SpvOpSelectionMerge) {
     insertion_pos = insertion_pos->PreviousNode();
   }
   inst->RemoveFromList();
-  insertion_pos->InsertBefore(std::unique_ptr<ir::Instruction>(inst));
+  insertion_pos->InsertBefore(std::unique_ptr<opt::Instruction>(inst));
   context()->set_instr_block(inst, target_block);
 }
 
-bool IfConversion::CanHoistInstruction(ir::Instruction* inst,
-                                       ir::BasicBlock* target_block,
+bool IfConversion::CanHoistInstruction(opt::Instruction* inst,
+                                       opt::BasicBlock* target_block,
                                        DominatorAnalysis* dominators) {
-  ir::BasicBlock* inst_block = context()->get_instr_block(inst);
+  opt::BasicBlock* inst_block = context()->get_instr_block(inst);
   if (!inst_block) {
     // This is in the header, and dominates everything.
     return true;
@@ -274,7 +276,7 @@
   analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr();
   return inst->WhileEachInId(
       [this, target_block, def_use_mgr, dominators](uint32_t* id) {
-        ir::Instruction* operand_inst = def_use_mgr->GetDef(*id);
+        opt::Instruction* operand_inst = def_use_mgr->GetDef(*id);
         return CanHoistInstruction(operand_inst, target_block, dominators);
       });
 }
diff --git a/source/opt/if_conversion.h b/source/opt/if_conversion.h
index e19af0b..de15a24 100644
--- a/source/opt/if_conversion.h
+++ b/source/opt/if_conversion.h
@@ -27,13 +27,13 @@
 class IfConversion : public Pass {
  public:
   const char* name() const override { return "if-conversion"; }
-  Status Process(ir::IRContext* context) override;
+  Status Process(opt::IRContext* context) override;
 
-  ir::IRContext::Analysis GetPreservedAnalyses() override {
-    return ir::IRContext::kAnalysisDefUse |
-           ir::IRContext::kAnalysisDominatorAnalysis |
-           ir::IRContext::kAnalysisInstrToBlockMapping |
-           ir::IRContext::kAnalysisCFG | ir::IRContext::kAnalysisNameMap;
+  opt::IRContext::Analysis GetPreservedAnalyses() override {
+    return opt::IRContext::kAnalysisDefUse |
+           opt::IRContext::kAnalysisDominatorAnalysis |
+           opt::IRContext::kAnalysisInstrToBlockMapping |
+           opt::IRContext::kAnalysisCFG | opt::IRContext::kAnalysisNameMap;
   }
 
  private:
@@ -42,14 +42,16 @@
   bool CheckType(uint32_t id);
 
   // Returns the basic block containing |id|.
-  ir::BasicBlock* GetBlock(uint32_t id);
+  opt::BasicBlock* GetBlock(uint32_t id);
 
   // Returns the basic block for the |predecessor|'th index predecessor of
   // |phi|.
-  ir::BasicBlock* GetIncomingBlock(ir::Instruction* phi, uint32_t predecessor);
+  opt::BasicBlock* GetIncomingBlock(opt::Instruction* phi,
+                                    uint32_t predecessor);
 
   // Returns the instruction defining the |predecessor|'th index of |phi|.
-  ir::Instruction* GetIncomingValue(ir::Instruction* phi, uint32_t predecessor);
+  opt::Instruction* GetIncomingValue(opt::Instruction* phi,
+                                     uint32_t predecessor);
 
   // Returns the id of a OpCompositeConstruct boolean vector. The composite has
   // the same number of elements as |vec_data_ty| and each member is |cond|.
@@ -60,26 +62,27 @@
                           InstructionBuilder* builder);
 
   // Returns true if none of |phi|'s users are in |block|.
-  bool CheckPhiUsers(ir::Instruction* phi, ir::BasicBlock* block);
+  bool CheckPhiUsers(opt::Instruction* phi, opt::BasicBlock* block);
 
   // Returns |false| if |block| is not appropriate to transform. Only
   // transforms blocks with two predecessors. Neither incoming block can be
   // dominated by |block|. Both predecessors must share a common dominator that
   // is terminated by a conditional branch.
-  bool CheckBlock(ir::BasicBlock* block, DominatorAnalysis* dominators,
-                  ir::BasicBlock** common);
+  bool CheckBlock(opt::BasicBlock* block, DominatorAnalysis* dominators,
+                  opt::BasicBlock** common);
 
   // Moves |inst| to |target_block| if it does not already dominate the block.
   // Any instructions that |inst| depends on are move if necessary.  It is
   // assumed that |inst| can be hoisted to |target_block| as defined by
   // |CanHoistInstruction|.  |dominators| is the dominator analysis for the
   // function that contains |target_block|.
-  void HoistInstruction(ir::Instruction* inst, ir::BasicBlock* target_block,
+  void HoistInstruction(opt::Instruction* inst, opt::BasicBlock* target_block,
                         DominatorAnalysis* dominators);
 
   // Returns true if it is legal to move |inst| and the instructions it depends
   // on to |target_block| if they do not already dominate |target_block|.
-  bool CanHoistInstruction(ir::Instruction* inst, ir::BasicBlock* target_block,
+  bool CanHoistInstruction(opt::Instruction* inst,
+                           opt::BasicBlock* target_block,
                            DominatorAnalysis* dominators);
 };
 
diff --git a/source/opt/inline_exhaustive_pass.cpp b/source/opt/inline_exhaustive_pass.cpp
index a5bc9f3..745534b 100644
--- a/source/opt/inline_exhaustive_pass.cpp
+++ b/source/opt/inline_exhaustive_pass.cpp
@@ -19,15 +19,15 @@
 namespace spvtools {
 namespace opt {
 
-bool InlineExhaustivePass::InlineExhaustive(ir::Function* func) {
+bool InlineExhaustivePass::InlineExhaustive(opt::Function* func) {
   bool modified = false;
   // Using block iterators here because of block erasures and insertions.
   for (auto bi = func->begin(); bi != func->end(); ++bi) {
     for (auto ii = bi->begin(); ii != bi->end();) {
       if (IsInlinableFunctionCall(&*ii)) {
         // Inline call.
-        std::vector<std::unique_ptr<ir::BasicBlock>> newBlocks;
-        std::vector<std::unique_ptr<ir::Instruction>> newVars;
+        std::vector<std::unique_ptr<opt::BasicBlock>> newBlocks;
+        std::vector<std::unique_ptr<opt::Instruction>> newVars;
         GenInlineCode(&newBlocks, &newVars, ii, bi);
         // If call block is replaced with more than one block, point
         // succeeding phis at new last block.
@@ -59,11 +59,13 @@
   return modified;
 }
 
-void InlineExhaustivePass::Initialize(ir::IRContext* c) { InitializeInline(c); }
+void InlineExhaustivePass::Initialize(opt::IRContext* c) {
+  InitializeInline(c);
+}
 
 Pass::Status InlineExhaustivePass::ProcessImpl() {
   // Attempt exhaustive inlining on each entry point function in module
-  ProcessFunction pfn = [this](ir::Function* fp) {
+  ProcessFunction pfn = [this](opt::Function* fp) {
     return InlineExhaustive(fp);
   };
   bool modified = ProcessEntryPointCallTree(pfn, get_module());
@@ -72,7 +74,7 @@
 
 InlineExhaustivePass::InlineExhaustivePass() {}
 
-Pass::Status InlineExhaustivePass::Process(ir::IRContext* c) {
+Pass::Status InlineExhaustivePass::Process(opt::IRContext* c) {
   Initialize(c);
   return ProcessImpl();
 }
diff --git a/source/opt/inline_exhaustive_pass.h b/source/opt/inline_exhaustive_pass.h
index 08b4387..6f3eedc 100644
--- a/source/opt/inline_exhaustive_pass.h
+++ b/source/opt/inline_exhaustive_pass.h
@@ -34,16 +34,16 @@
 class InlineExhaustivePass : public InlinePass {
  public:
   InlineExhaustivePass();
-  Status Process(ir::IRContext* c) override;
+  Status Process(opt::IRContext* c) override;
 
   const char* name() const override { return "inline-entry-points-exhaustive"; }
 
  private:
   // Exhaustively inline all function calls in func as well as in
   // all code that is inlined into func. Return true if func is modified.
-  bool InlineExhaustive(ir::Function* func);
+  bool InlineExhaustive(opt::Function* func);
 
-  void Initialize(ir::IRContext* c);
+  void Initialize(opt::IRContext* c);
   Pass::Status ProcessImpl();
 };
 
diff --git a/source/opt/inline_opaque_pass.cpp b/source/opt/inline_opaque_pass.cpp
index 1388050..70f4a99 100644
--- a/source/opt/inline_opaque_pass.cpp
+++ b/source/opt/inline_opaque_pass.cpp
@@ -26,7 +26,7 @@
 }  // anonymous namespace
 
 bool InlineOpaquePass::IsOpaqueType(uint32_t typeId) {
-  const ir::Instruction* typeInst = get_def_use_mgr()->GetDef(typeId);
+  const opt::Instruction* typeInst = get_def_use_mgr()->GetDef(typeId);
   switch (typeInst->opcode()) {
     case SpvOpTypeSampler:
     case SpvOpTypeImage:
@@ -47,14 +47,14 @@
   });
 }
 
-bool InlineOpaquePass::HasOpaqueArgsOrReturn(const ir::Instruction* callInst) {
+bool InlineOpaquePass::HasOpaqueArgsOrReturn(const opt::Instruction* callInst) {
   // Check return type
   if (IsOpaqueType(callInst->type_id())) return true;
   // Check args
   int icnt = 0;
   return !callInst->WhileEachInId([&icnt, this](const uint32_t* iid) {
     if (icnt > 0) {
-      const ir::Instruction* argInst = get_def_use_mgr()->GetDef(*iid);
+      const opt::Instruction* argInst = get_def_use_mgr()->GetDef(*iid);
       if (IsOpaqueType(argInst->type_id())) return false;
     }
     ++icnt;
@@ -62,15 +62,15 @@
   });
 }
 
-bool InlineOpaquePass::InlineOpaque(ir::Function* func) {
+bool InlineOpaquePass::InlineOpaque(opt::Function* func) {
   bool modified = false;
   // Using block iterators here because of block erasures and insertions.
   for (auto bi = func->begin(); bi != func->end(); ++bi) {
     for (auto ii = bi->begin(); ii != bi->end();) {
       if (IsInlinableFunctionCall(&*ii) && HasOpaqueArgsOrReturn(&*ii)) {
         // Inline call.
-        std::vector<std::unique_ptr<ir::BasicBlock>> newBlocks;
-        std::vector<std::unique_ptr<ir::Instruction>> newVars;
+        std::vector<std::unique_ptr<opt::BasicBlock>> newBlocks;
+        std::vector<std::unique_ptr<opt::Instruction>> newVars;
         GenInlineCode(&newBlocks, &newVars, ii, bi);
         // If call block is replaced with more than one block, point
         // succeeding phis at new last block.
@@ -92,18 +92,18 @@
   return modified;
 }
 
-void InlineOpaquePass::Initialize(ir::IRContext* c) { InitializeInline(c); }
+void InlineOpaquePass::Initialize(opt::IRContext* c) { InitializeInline(c); }
 
 Pass::Status InlineOpaquePass::ProcessImpl() {
   // Do opaque inlining on each function in entry point call tree
-  ProcessFunction pfn = [this](ir::Function* fp) { return InlineOpaque(fp); };
+  ProcessFunction pfn = [this](opt::Function* fp) { return InlineOpaque(fp); };
   bool modified = ProcessEntryPointCallTree(pfn, get_module());
   return modified ? Status::SuccessWithChange : Status::SuccessWithoutChange;
 }
 
 InlineOpaquePass::InlineOpaquePass() {}
 
-Pass::Status InlineOpaquePass::Process(ir::IRContext* c) {
+Pass::Status InlineOpaquePass::Process(opt::IRContext* c) {
   Initialize(c);
   return ProcessImpl();
 }
diff --git a/source/opt/inline_opaque_pass.h b/source/opt/inline_opaque_pass.h
index 0a6cf0e..6cb083f 100644
--- a/source/opt/inline_opaque_pass.h
+++ b/source/opt/inline_opaque_pass.h
@@ -34,7 +34,7 @@
 class InlineOpaquePass : public InlinePass {
  public:
   InlineOpaquePass();
-  Status Process(ir::IRContext* c) override;
+  Status Process(opt::IRContext* c) override;
 
   const char* name() const override { return "inline-entry-points-opaque"; }
 
@@ -43,14 +43,14 @@
   bool IsOpaqueType(uint32_t typeId);
 
   // Return true if function call |callInst| has opaque argument or return type
-  bool HasOpaqueArgsOrReturn(const ir::Instruction* callInst);
+  bool HasOpaqueArgsOrReturn(const opt::Instruction* callInst);
 
   // Inline all function calls in |func| that have opaque params or return
   // type. Inline similarly all code that is inlined into func. Return true
   // if func is modified.
-  bool InlineOpaque(ir::Function* func);
+  bool InlineOpaque(opt::Function* func);
 
-  void Initialize(ir::IRContext* c);
+  void Initialize(opt::IRContext* c);
   Pass::Status ProcessImpl();
 };
 
diff --git a/source/opt/inline_pass.cpp b/source/opt/inline_pass.cpp
index c774441..e37fc38 100644
--- a/source/opt/inline_pass.cpp
+++ b/source/opt/inline_pass.cpp
@@ -32,7 +32,7 @@
 uint32_t InlinePass::AddPointerToType(uint32_t type_id,
                                       SpvStorageClass storage_class) {
   uint32_t resultId = TakeNextId();
-  std::unique_ptr<ir::Instruction> type_inst(new ir::Instruction(
+  std::unique_ptr<opt::Instruction> type_inst(new opt::Instruction(
       context(), SpvOpTypePointer, 0, resultId,
       {{spv_operand_type_t::SPV_OPERAND_TYPE_STORAGE_CLASS,
         {uint32_t(storage_class)}},
@@ -48,8 +48,8 @@
 }
 
 void InlinePass::AddBranch(uint32_t label_id,
-                           std::unique_ptr<ir::BasicBlock>* block_ptr) {
-  std::unique_ptr<ir::Instruction> newBranch(new ir::Instruction(
+                           std::unique_ptr<opt::BasicBlock>* block_ptr) {
+  std::unique_ptr<opt::Instruction> newBranch(new opt::Instruction(
       context(), SpvOpBranch, 0, 0,
       {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {label_id}}}));
   (*block_ptr)->AddInstruction(std::move(newBranch));
@@ -57,8 +57,8 @@
 
 void InlinePass::AddBranchCond(uint32_t cond_id, uint32_t true_id,
                                uint32_t false_id,
-                               std::unique_ptr<ir::BasicBlock>* block_ptr) {
-  std::unique_ptr<ir::Instruction> newBranch(new ir::Instruction(
+                               std::unique_ptr<opt::BasicBlock>* block_ptr) {
+  std::unique_ptr<opt::Instruction> newBranch(new opt::Instruction(
       context(), SpvOpBranchConditional, 0, 0,
       {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {cond_id}},
        {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {true_id}},
@@ -67,8 +67,8 @@
 }
 
 void InlinePass::AddLoopMerge(uint32_t merge_id, uint32_t continue_id,
-                              std::unique_ptr<ir::BasicBlock>* block_ptr) {
-  std::unique_ptr<ir::Instruction> newLoopMerge(new ir::Instruction(
+                              std::unique_ptr<opt::BasicBlock>* block_ptr) {
+  std::unique_ptr<opt::Instruction> newLoopMerge(new opt::Instruction(
       context(), SpvOpLoopMerge, 0, 0,
       {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {merge_id}},
        {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {continue_id}},
@@ -77,8 +77,8 @@
 }
 
 void InlinePass::AddStore(uint32_t ptr_id, uint32_t val_id,
-                          std::unique_ptr<ir::BasicBlock>* block_ptr) {
-  std::unique_ptr<ir::Instruction> newStore(new ir::Instruction(
+                          std::unique_ptr<opt::BasicBlock>* block_ptr) {
+  std::unique_ptr<opt::Instruction> newStore(new opt::Instruction(
       context(), SpvOpStore, 0, 0,
       {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {ptr_id}},
        {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {val_id}}}));
@@ -86,16 +86,16 @@
 }
 
 void InlinePass::AddLoad(uint32_t type_id, uint32_t resultId, uint32_t ptr_id,
-                         std::unique_ptr<ir::BasicBlock>* block_ptr) {
-  std::unique_ptr<ir::Instruction> newLoad(new ir::Instruction(
+                         std::unique_ptr<opt::BasicBlock>* block_ptr) {
+  std::unique_ptr<opt::Instruction> newLoad(new opt::Instruction(
       context(), SpvOpLoad, type_id, resultId,
       {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {ptr_id}}}));
   (*block_ptr)->AddInstruction(std::move(newLoad));
 }
 
-std::unique_ptr<ir::Instruction> InlinePass::NewLabel(uint32_t label_id) {
-  std::unique_ptr<ir::Instruction> newLabel(
-      new ir::Instruction(context(), SpvOpLabel, 0, label_id, {}));
+std::unique_ptr<opt::Instruction> InlinePass::NewLabel(uint32_t label_id) {
+  std::unique_ptr<opt::Instruction> newLabel(
+      new opt::Instruction(context(), SpvOpLabel, 0, label_id, {}));
   return newLabel;
 }
 
@@ -114,26 +114,26 @@
 }
 
 void InlinePass::MapParams(
-    ir::Function* calleeFn, ir::BasicBlock::iterator call_inst_itr,
+    opt::Function* calleeFn, opt::BasicBlock::iterator call_inst_itr,
     std::unordered_map<uint32_t, uint32_t>* callee2caller) {
   int param_idx = 0;
-  calleeFn->ForEachParam(
-      [&call_inst_itr, &param_idx, &callee2caller](const ir::Instruction* cpi) {
-        const uint32_t pid = cpi->result_id();
-        (*callee2caller)[pid] = call_inst_itr->GetSingleWordOperand(
-            kSpvFunctionCallArgumentId + param_idx);
-        ++param_idx;
-      });
+  calleeFn->ForEachParam([&call_inst_itr, &param_idx,
+                          &callee2caller](const opt::Instruction* cpi) {
+    const uint32_t pid = cpi->result_id();
+    (*callee2caller)[pid] = call_inst_itr->GetSingleWordOperand(
+        kSpvFunctionCallArgumentId + param_idx);
+    ++param_idx;
+  });
 }
 
 void InlinePass::CloneAndMapLocals(
-    ir::Function* calleeFn,
-    std::vector<std::unique_ptr<ir::Instruction>>* new_vars,
+    opt::Function* calleeFn,
+    std::vector<std::unique_ptr<opt::Instruction>>* new_vars,
     std::unordered_map<uint32_t, uint32_t>* callee2caller) {
   auto callee_block_itr = calleeFn->begin();
   auto callee_var_itr = callee_block_itr->begin();
   while (callee_var_itr->opcode() == SpvOp::SpvOpVariable) {
-    std::unique_ptr<ir::Instruction> var_inst(
+    std::unique_ptr<opt::Instruction> var_inst(
         callee_var_itr->Clone(callee_var_itr->context()));
     uint32_t newId = TakeNextId();
     get_decoration_mgr()->CloneDecorations(callee_var_itr->result_id(), newId);
@@ -145,8 +145,8 @@
 }
 
 uint32_t InlinePass::CreateReturnVar(
-    ir::Function* calleeFn,
-    std::vector<std::unique_ptr<ir::Instruction>>* new_vars) {
+    opt::Function* calleeFn,
+    std::vector<std::unique_ptr<opt::Instruction>>* new_vars) {
   uint32_t returnVarId = 0;
   const uint32_t calleeTypeId = calleeFn->type_id();
   analysis::Type* calleeType = context()->get_type_mgr()->GetType(calleeTypeId);
@@ -158,7 +158,7 @@
       returnVarTypeId = AddPointerToType(calleeTypeId, SpvStorageClassFunction);
     // Add return var to new function scope variables.
     returnVarId = TakeNextId();
-    std::unique_ptr<ir::Instruction> var_inst(new ir::Instruction(
+    std::unique_ptr<opt::Instruction> var_inst(new opt::Instruction(
         context(), SpvOpVariable, returnVarTypeId, returnVarId,
         {{spv_operand_type_t::SPV_OPERAND_TYPE_STORAGE_CLASS,
           {SpvStorageClassFunction}}}));
@@ -168,15 +168,15 @@
   return returnVarId;
 }
 
-bool InlinePass::IsSameBlockOp(const ir::Instruction* inst) const {
+bool InlinePass::IsSameBlockOp(const opt::Instruction* inst) const {
   return inst->opcode() == SpvOpSampledImage || inst->opcode() == SpvOpImage;
 }
 
 void InlinePass::CloneSameBlockOps(
-    std::unique_ptr<ir::Instruction>* inst,
+    std::unique_ptr<opt::Instruction>* inst,
     std::unordered_map<uint32_t, uint32_t>* postCallSB,
-    std::unordered_map<uint32_t, ir::Instruction*>* preCallSB,
-    std::unique_ptr<ir::BasicBlock>* block_ptr) {
+    std::unordered_map<uint32_t, opt::Instruction*>* preCallSB,
+    std::unique_ptr<opt::BasicBlock>* block_ptr) {
   (*inst)->ForEachInId(
       [&postCallSB, &preCallSB, &block_ptr, this](uint32_t* iid) {
         const auto mapItr = (*postCallSB).find(*iid);
@@ -184,8 +184,8 @@
           const auto mapItr2 = (*preCallSB).find(*iid);
           if (mapItr2 != (*preCallSB).end()) {
             // Clone pre-call same-block ops, map result id.
-            const ir::Instruction* inInst = mapItr2->second;
-            std::unique_ptr<ir::Instruction> sb_inst(
+            const opt::Instruction* inInst = mapItr2->second;
+            std::unique_ptr<opt::Instruction> sb_inst(
                 inInst->Clone(inInst->context()));
             CloneSameBlockOps(&sb_inst, postCallSB, preCallSB, block_ptr);
             const uint32_t rid = sb_inst->result_id();
@@ -204,24 +204,24 @@
 }
 
 void InlinePass::GenInlineCode(
-    std::vector<std::unique_ptr<ir::BasicBlock>>* new_blocks,
-    std::vector<std::unique_ptr<ir::Instruction>>* new_vars,
-    ir::BasicBlock::iterator call_inst_itr,
-    ir::UptrVectorIterator<ir::BasicBlock> call_block_itr) {
+    std::vector<std::unique_ptr<opt::BasicBlock>>* new_blocks,
+    std::vector<std::unique_ptr<opt::Instruction>>* new_vars,
+    opt::BasicBlock::iterator call_inst_itr,
+    opt::UptrVectorIterator<opt::BasicBlock> call_block_itr) {
   // Map from all ids in the callee to their equivalent id in the caller
   // as callee instructions are copied into caller.
   std::unordered_map<uint32_t, uint32_t> callee2caller;
   // Pre-call same-block insts
-  std::unordered_map<uint32_t, ir::Instruction*> preCallSB;
+  std::unordered_map<uint32_t, opt::Instruction*> preCallSB;
   // Post-call same-block op ids
   std::unordered_map<uint32_t, uint32_t> postCallSB;
 
   // Invalidate the def-use chains.  They are not kept up to date while
   // inlining.  However, certain calls try to keep them up-to-date if they are
   // valid.  These operations can fail.
-  context()->InvalidateAnalyses(ir::IRContext::kAnalysisDefUse);
+  context()->InvalidateAnalyses(opt::IRContext::kAnalysisDefUse);
 
-  ir::Function* calleeFn = id2function_[call_inst_itr->GetSingleWordOperand(
+  opt::Function* calleeFn = id2function_[call_inst_itr->GetSingleWordOperand(
       kSpvFunctionCallFunctionId)];
 
   // Check for multiple returns in the callee.
@@ -240,7 +240,7 @@
 
   // Create set of callee result ids. Used to detect forward references
   std::unordered_set<uint32_t> callee_result_ids;
-  calleeFn->ForEachInst([&callee_result_ids](const ir::Instruction* cpi) {
+  calleeFn->ForEachInst([&callee_result_ids](const opt::Instruction* cpi) {
     const uint32_t rid = cpi->result_id();
     if (rid != 0) callee_result_ids.insert(rid);
   });
@@ -275,14 +275,15 @@
   // written to it.  It is created when we encounter the OpLabel
   // of the first callee block.  It is appended to new_blocks only when
   // it is complete.
-  std::unique_ptr<ir::BasicBlock> new_blk_ptr;
+  std::unique_ptr<opt::BasicBlock> new_blk_ptr;
   calleeFn->ForEachInst([&new_blocks, &callee2caller, &call_block_itr,
                          &call_inst_itr, &new_blk_ptr, &prevInstWasReturn,
                          &returnLabelId, &returnVarId, caller_is_loop_header,
                          callee_begins_with_structured_header, &calleeTypeId,
                          &multiBlocks, &postCallSB, &preCallSB, multiReturn,
                          &singleTripLoopHeaderId, &singleTripLoopContinueId,
-                         &callee_result_ids, this](const ir::Instruction* cpi) {
+                         &callee_result_ids,
+                         this](const opt::Instruction* cpi) {
     switch (cpi->opcode()) {
       case SpvOpFunction:
       case SpvOpFunctionParameter:
@@ -305,8 +306,8 @@
         // Generate a return label so that we split the block with the function
         // call. Copy the terminator into the new block.
         if (returnLabelId == 0) returnLabelId = this->TakeNextId();
-        std::unique_ptr<ir::Instruction> terminator(
-            new ir::Instruction(context(), cpi->opcode(), 0, 0, {}));
+        std::unique_ptr<opt::Instruction> terminator(
+            new opt::Instruction(context(), cpi->opcode(), 0, 0, {}));
         new_blk_ptr->AddInstruction(std::move(terminator));
         break;
       }
@@ -337,14 +338,14 @@
           firstBlock = true;
         }
         // Create first/next block.
-        new_blk_ptr.reset(new ir::BasicBlock(NewLabel(labelId)));
+        new_blk_ptr.reset(new opt::BasicBlock(NewLabel(labelId)));
         if (firstBlock) {
           // Copy contents of original caller block up to call instruction.
           for (auto cii = call_block_itr->begin(); cii != call_inst_itr;
                cii = call_block_itr->begin()) {
-            ir::Instruction* inst = &*cii;
+            opt::Instruction* inst = &*cii;
             inst->RemoveFromList();
-            std::unique_ptr<ir::Instruction> cp_inst(inst);
+            std::unique_ptr<opt::Instruction> cp_inst(inst);
             // Remember same-block ops for possible regeneration.
             if (IsSameBlockOp(&*cp_inst)) {
               auto* sb_inst_ptr = cp_inst.get();
@@ -363,7 +364,7 @@
             AddBranch(guard_block_id, &new_blk_ptr);
             new_blocks->push_back(std::move(new_blk_ptr));
             // Start the next block.
-            new_blk_ptr.reset(new ir::BasicBlock(NewLabel(guard_block_id)));
+            new_blk_ptr.reset(new opt::BasicBlock(NewLabel(guard_block_id)));
             // Reset the mapping of the callee's entry block to point to
             // the guard block.  Do this so we can fix up phis later on to
             // satisfy dominance.
@@ -385,14 +386,14 @@
             AddBranch(singleTripLoopHeaderId, &new_blk_ptr);
             new_blocks->push_back(std::move(new_blk_ptr));
             new_blk_ptr.reset(
-                new ir::BasicBlock(NewLabel(singleTripLoopHeaderId)));
+                new opt::BasicBlock(NewLabel(singleTripLoopHeaderId)));
             returnLabelId = this->TakeNextId();
             singleTripLoopContinueId = this->TakeNextId();
             AddLoopMerge(returnLabelId, singleTripLoopContinueId, &new_blk_ptr);
             uint32_t postHeaderId = this->TakeNextId();
             AddBranch(postHeaderId, &new_blk_ptr);
             new_blocks->push_back(std::move(new_blk_ptr));
-            new_blk_ptr.reset(new ir::BasicBlock(NewLabel(postHeaderId)));
+            new_blk_ptr.reset(new opt::BasicBlock(NewLabel(postHeaderId)));
             multiBlocks = true;
             // Reset the mapping of the callee's entry block to point to
             // the post-header block.  Do this so we can fix up phis later
@@ -435,13 +436,13 @@
             // target block now, with a false branch back to the loop header.
             new_blocks->push_back(std::move(new_blk_ptr));
             new_blk_ptr.reset(
-                new ir::BasicBlock(NewLabel(singleTripLoopContinueId)));
+                new opt::BasicBlock(NewLabel(singleTripLoopContinueId)));
             AddBranchCond(GetFalseId(), singleTripLoopHeaderId, returnLabelId,
                           &new_blk_ptr);
           }
           // Generate the return block.
           new_blocks->push_back(std::move(new_blk_ptr));
-          new_blk_ptr.reset(new ir::BasicBlock(NewLabel(returnLabelId)));
+          new_blk_ptr.reset(new opt::BasicBlock(NewLabel(returnLabelId)));
           multiBlocks = true;
         }
         // Load return value into result id of call, if it exists.
@@ -451,10 +452,10 @@
           AddLoad(calleeTypeId, resId, returnVarId, &new_blk_ptr);
         }
         // Copy remaining instructions from caller block.
-        for (ir::Instruction* inst = call_inst_itr->NextNode(); inst;
+        for (opt::Instruction* inst = call_inst_itr->NextNode(); inst;
              inst = call_inst_itr->NextNode()) {
           inst->RemoveFromList();
-          std::unique_ptr<ir::Instruction> cp_inst(inst);
+          std::unique_ptr<opt::Instruction> cp_inst(inst);
           // If multiple blocks generated, regenerate any same-block
           // instruction that has not been seen in this last block.
           if (multiBlocks) {
@@ -472,7 +473,7 @@
       } break;
       default: {
         // Copy callee instruction and remap all input Ids.
-        std::unique_ptr<ir::Instruction> cp_inst(cpi->Clone(context()));
+        std::unique_ptr<opt::Instruction> cp_inst(cpi->Clone(context()));
         cp_inst->ForEachInId([&callee2caller, &callee_result_ids,
                               this](uint32_t* iid) {
           const auto mapItr = callee2caller.find(*iid);
@@ -517,7 +518,7 @@
     auto loop_merge_itr = last->tail();
     --loop_merge_itr;
     assert(loop_merge_itr->opcode() == SpvOpLoopMerge);
-    std::unique_ptr<ir::Instruction> cp_inst(loop_merge_itr->Clone(context()));
+    std::unique_ptr<opt::Instruction> cp_inst(loop_merge_itr->Clone(context()));
     if (caller_is_single_block_loop) {
       // Also, update its continue target to point to the last block.
       cp_inst->SetInOperand(kSpvLoopMergeContinueTargetIdInIdx, {last->id()});
@@ -535,7 +536,7 @@
   }
 }
 
-bool InlinePass::IsInlinableFunctionCall(const ir::Instruction* inst) {
+bool InlinePass::IsInlinableFunctionCall(const opt::Instruction* inst) {
   if (inst->opcode() != SpvOp::SpvOpFunctionCall) return false;
   const uint32_t calleeFnId =
       inst->GetSingleWordOperand(kSpvFunctionCallFunctionId);
@@ -544,16 +545,16 @@
 }
 
 void InlinePass::UpdateSucceedingPhis(
-    std::vector<std::unique_ptr<ir::BasicBlock>>& new_blocks) {
+    std::vector<std::unique_ptr<opt::BasicBlock>>& new_blocks) {
   const auto firstBlk = new_blocks.begin();
   const auto lastBlk = new_blocks.end() - 1;
   const uint32_t firstId = (*firstBlk)->id();
   const uint32_t lastId = (*lastBlk)->id();
-  const ir::BasicBlock& const_last_block = *lastBlk->get();
+  const opt::BasicBlock& const_last_block = *lastBlk->get();
   const_last_block.ForEachSuccessorLabel(
       [&firstId, &lastId, this](const uint32_t succ) {
-        ir::BasicBlock* sbp = this->id2block_[succ];
-        sbp->ForEachPhiInst([&firstId, &lastId](ir::Instruction* phi) {
+        opt::BasicBlock* sbp = this->id2block_[succ];
+        sbp->ForEachPhiInst([&firstId, &lastId](opt::Instruction* phi) {
           phi->ForEachInId([&firstId, &lastId](uint32_t* id) {
             if (*id == firstId) *id = lastId;
           });
@@ -561,7 +562,7 @@
       });
 }
 
-bool InlinePass::HasMultipleReturns(ir::Function* func) {
+bool InlinePass::HasMultipleReturns(opt::Function* func) {
   bool seenReturn = false;
   bool multipleReturns = false;
   for (auto& blk : *func) {
@@ -579,7 +580,7 @@
   return multipleReturns;
 }
 
-void InlinePass::ComputeStructuredSuccessors(ir::Function* func) {
+void InlinePass::ComputeStructuredSuccessors(opt::Function* func) {
   // If header, make merge block first successor.
   for (auto& blk : *func) {
     uint32_t mbid = blk.MergeBlockIdIfAny();
@@ -596,12 +597,12 @@
 }
 
 InlinePass::GetBlocksFunction InlinePass::StructuredSuccessorsFunction() {
-  return [this](const ir::BasicBlock* block) {
+  return [this](const opt::BasicBlock* block) {
     return &(block2structured_succs_[block]);
   };
 }
 
-bool InlinePass::HasNoReturnInLoop(ir::Function* func) {
+bool InlinePass::HasNoReturnInLoop(opt::Function* func) {
   // If control not structured, do not do loop/return analysis
   // TODO: Analyze returns in non-structured control flow
   if (!context()->get_feature_mgr()->HasCapability(SpvCapabilityShader))
@@ -612,8 +613,8 @@
   ComputeStructuredSuccessors(func);
   auto ignore_block = [](cbb_ptr) {};
   auto ignore_edge = [](cbb_ptr, cbb_ptr) {};
-  std::list<const ir::BasicBlock*> structuredOrder;
-  CFA<ir::BasicBlock>::DepthFirstTraversal(
+  std::list<const opt::BasicBlock*> structuredOrder;
+  CFA<opt::BasicBlock>::DepthFirstTraversal(
       &*func->begin(), StructuredSuccessorsFunction(), ignore_block,
       [&](cbb_ptr b) { structuredOrder.push_front(b); }, ignore_edge);
   // Search for returns in loops. Only need to track outermost loop
@@ -643,7 +644,7 @@
   return !return_in_loop;
 }
 
-void InlinePass::AnalyzeReturns(ir::Function* func) {
+void InlinePass::AnalyzeReturns(opt::Function* func) {
   // Look for multiple returns
   if (!HasMultipleReturns(func)) {
     no_return_in_loop_.insert(func->result_id());
@@ -654,7 +655,7 @@
   if (HasNoReturnInLoop(func)) no_return_in_loop_.insert(func->result_id());
 }
 
-bool InlinePass::IsInlinableFunction(ir::Function* func) {
+bool InlinePass::IsInlinableFunction(opt::Function* func) {
   // We can only inline a function if it has blocks.
   if (func->cbegin() == func->cend()) return false;
   // Do not inline functions with returns in loops. Currently early return
@@ -667,7 +668,7 @@
          no_return_in_loop_.cend();
 }
 
-void InlinePass::InitializeInline(ir::IRContext* c) {
+void InlinePass::InitializeInline(opt::IRContext* c) {
   InitializeProcessing(c);
 
   false_id_ = 0;
diff --git a/source/opt/inline_pass.h b/source/opt/inline_pass.h
index dd2d0c7..2a560b4 100644
--- a/source/opt/inline_pass.h
+++ b/source/opt/inline_pass.h
@@ -32,11 +32,11 @@
 
 // See optimizer.hpp for documentation.
 class InlinePass : public Pass {
-  using cbb_ptr = const ir::BasicBlock*;
+  using cbb_ptr = const opt::BasicBlock*;
 
  public:
   using GetBlocksFunction =
-      std::function<std::vector<ir::BasicBlock*>*(const ir::BasicBlock*)>;
+      std::function<std::vector<opt::BasicBlock*>*(const opt::BasicBlock*)>;
 
   InlinePass();
   virtual ~InlinePass() = default;
@@ -47,60 +47,61 @@
   uint32_t AddPointerToType(uint32_t type_id, SpvStorageClass storage_class);
 
   // Add unconditional branch to labelId to end of block block_ptr.
-  void AddBranch(uint32_t labelId, std::unique_ptr<ir::BasicBlock>* block_ptr);
+  void AddBranch(uint32_t labelId, std::unique_ptr<opt::BasicBlock>* block_ptr);
 
   // Add conditional branch to end of block |block_ptr|.
   void AddBranchCond(uint32_t cond_id, uint32_t true_id, uint32_t false_id,
-                     std::unique_ptr<ir::BasicBlock>* block_ptr);
+                     std::unique_ptr<opt::BasicBlock>* block_ptr);
 
   // Add unconditional branch to labelId to end of block block_ptr.
   void AddLoopMerge(uint32_t merge_id, uint32_t continue_id,
-                    std::unique_ptr<ir::BasicBlock>* block_ptr);
+                    std::unique_ptr<opt::BasicBlock>* block_ptr);
 
   // Add store of valId to ptrId to end of block block_ptr.
   void AddStore(uint32_t ptrId, uint32_t valId,
-                std::unique_ptr<ir::BasicBlock>* block_ptr);
+                std::unique_ptr<opt::BasicBlock>* block_ptr);
 
   // Add load of ptrId into resultId to end of block block_ptr.
   void AddLoad(uint32_t typeId, uint32_t resultId, uint32_t ptrId,
-               std::unique_ptr<ir::BasicBlock>* block_ptr);
+               std::unique_ptr<opt::BasicBlock>* block_ptr);
 
   // Return new label.
-  std::unique_ptr<ir::Instruction> NewLabel(uint32_t label_id);
+  std::unique_ptr<opt::Instruction> NewLabel(uint32_t label_id);
 
   // Returns the id for the boolean false value. Looks in the module first
   // and creates it if not found. Remembers it for future calls.
   uint32_t GetFalseId();
 
   // Map callee params to caller args
-  void MapParams(ir::Function* calleeFn, ir::BasicBlock::iterator call_inst_itr,
+  void MapParams(opt::Function* calleeFn,
+                 opt::BasicBlock::iterator call_inst_itr,
                  std::unordered_map<uint32_t, uint32_t>* callee2caller);
 
   // Clone and map callee locals
   void CloneAndMapLocals(
-      ir::Function* calleeFn,
-      std::vector<std::unique_ptr<ir::Instruction>>* new_vars,
+      opt::Function* calleeFn,
+      std::vector<std::unique_ptr<opt::Instruction>>* new_vars,
       std::unordered_map<uint32_t, uint32_t>* callee2caller);
 
   // Create return variable for callee clone code if needed. Return id
   // if created, otherwise 0.
   uint32_t CreateReturnVar(
-      ir::Function* calleeFn,
-      std::vector<std::unique_ptr<ir::Instruction>>* new_vars);
+      opt::Function* calleeFn,
+      std::vector<std::unique_ptr<opt::Instruction>>* new_vars);
 
   // Return true if instruction must be in the same block that its result
   // is used.
-  bool IsSameBlockOp(const ir::Instruction* inst) const;
+  bool IsSameBlockOp(const opt::Instruction* inst) const;
 
   // Clone operands which must be in same block as consumer instructions.
   // Look in preCallSB for instructions that need cloning. Look in
   // postCallSB for instructions already cloned. Add cloned instruction
   // to postCallSB.
   void CloneSameBlockOps(
-      std::unique_ptr<ir::Instruction>* inst,
+      std::unique_ptr<opt::Instruction>* inst,
       std::unordered_map<uint32_t, uint32_t>* postCallSB,
-      std::unordered_map<uint32_t, ir::Instruction*>* preCallSB,
-      std::unique_ptr<ir::BasicBlock>* block_ptr);
+      std::unordered_map<uint32_t, opt::Instruction*>* preCallSB,
+      std::unique_ptr<opt::BasicBlock>* block_ptr);
 
   // Return in new_blocks the result of inlining the call at call_inst_itr
   // within its block at call_block_itr. The block at call_block_itr can
@@ -116,13 +117,13 @@
   // Also return in new_vars additional OpVariable instructions required by
   // and to be inserted into the caller function after the block at
   // call_block_itr is replaced with new_blocks.
-  void GenInlineCode(std::vector<std::unique_ptr<ir::BasicBlock>>* new_blocks,
-                     std::vector<std::unique_ptr<ir::Instruction>>* new_vars,
-                     ir::BasicBlock::iterator call_inst_itr,
-                     ir::UptrVectorIterator<ir::BasicBlock> call_block_itr);
+  void GenInlineCode(std::vector<std::unique_ptr<opt::BasicBlock>>* new_blocks,
+                     std::vector<std::unique_ptr<opt::Instruction>>* new_vars,
+                     opt::BasicBlock::iterator call_inst_itr,
+                     opt::UptrVectorIterator<opt::BasicBlock> call_block_itr);
 
   // Return true if |inst| is a function call that can be inlined.
-  bool IsInlinableFunctionCall(const ir::Instruction* inst);
+  bool IsInlinableFunctionCall(const opt::Instruction* inst);
 
   // Compute structured successors for function |func|.
   // A block's structured successors are the blocks it branches to
@@ -131,39 +132,39 @@
   // This assures correct depth first search in the presence of early
   // returns and kills. If the successor vector contain duplicates
   // if the merge block, they are safely ignored by DFS.
-  void ComputeStructuredSuccessors(ir::Function* func);
+  void ComputeStructuredSuccessors(opt::Function* func);
 
   // Return function to return ordered structure successors for a given block
   // Assumes ComputeStructuredSuccessors() has been called.
   GetBlocksFunction StructuredSuccessorsFunction();
 
   // Return true if |func| has multiple returns
-  bool HasMultipleReturns(ir::Function* func);
+  bool HasMultipleReturns(opt::Function* func);
 
   // Return true if |func| has no return in a loop. The current analysis
   // requires structured control flow, so return false if control flow not
   // structured ie. module is not a shader.
-  bool HasNoReturnInLoop(ir::Function* func);
+  bool HasNoReturnInLoop(opt::Function* func);
 
   // Find all functions with multiple returns and no returns in loops
-  void AnalyzeReturns(ir::Function* func);
+  void AnalyzeReturns(opt::Function* func);
 
   // Return true if |func| is a function that can be inlined.
-  bool IsInlinableFunction(ir::Function* func);
+  bool IsInlinableFunction(opt::Function* func);
 
   // Update phis in succeeding blocks to point to new last block
   void UpdateSucceedingPhis(
-      std::vector<std::unique_ptr<ir::BasicBlock>>& new_blocks);
+      std::vector<std::unique_ptr<opt::BasicBlock>>& new_blocks);
 
   // Initialize state for optimization of |module|
-  void InitializeInline(ir::IRContext* c);
+  void InitializeInline(opt::IRContext* c);
 
   // Map from function's result id to function.
-  std::unordered_map<uint32_t, ir::Function*> id2function_;
+  std::unordered_map<uint32_t, opt::Function*> id2function_;
 
   // Map from block's label id to block. TODO(dnovillo): This is superfluous wrt
   // opt::CFG. It has functionality not present in opt::CFG. Consolidate.
-  std::unordered_map<uint32_t, ir::BasicBlock*> id2block_;
+  std::unordered_map<uint32_t, opt::BasicBlock*> id2block_;
 
   // Set of ids of functions with multiple returns.
   std::set<uint32_t> multi_return_funcs_;
@@ -181,7 +182,7 @@
   // ComputeStructuredSuccessors() for definition. TODO(dnovillo): This is
   // superfluous wrt opt::CFG, but it seems to be computed in a slightly
   // different way in the inliner. Can these be consolidated?
-  std::unordered_map<const ir::BasicBlock*, std::vector<ir::BasicBlock*>>
+  std::unordered_map<const opt::BasicBlock*, std::vector<opt::BasicBlock*>>
       block2structured_succs_;
 };
 
diff --git a/source/opt/instruction.cpp b/source/opt/instruction.cpp
index 1999b76..37ff035 100644
--- a/source/opt/instruction.cpp
+++ b/source/opt/instruction.cpp
@@ -22,7 +22,7 @@
 #include "reflect.h"
 
 namespace spvtools {
-namespace ir {
+namespace opt {
 
 namespace {
 // Indices used to get particular operands out of instructions using InOperand.
@@ -145,7 +145,7 @@
 
 bool Instruction::IsReadOnlyLoad() const {
   if (IsLoad()) {
-    ir::Instruction* address_def = GetBaseAddress();
+    opt::Instruction* address_def = GetBaseAddress();
     if (!address_def || address_def->opcode() != SpvOpVariable) {
       return false;
     }
@@ -161,7 +161,7 @@
          "GetBaseAddress should only be called on instructions that take a "
          "pointer or image.");
   uint32_t base = GetSingleWordInOperand(kLoadBaseIndex);
-  ir::Instruction* base_inst = context()->get_def_use_mgr()->GetDef(base);
+  opt::Instruction* base_inst = context()->get_def_use_mgr()->GetDef(base);
   bool done = false;
   while (!done) {
     switch (base_inst->opcode()) {
@@ -217,7 +217,7 @@
     return false;
   }
 
-  ir::Instruction* base_type =
+  opt::Instruction* base_type =
       context()->get_def_use_mgr()->GetDef(GetSingleWordInOperand(1));
   if (base_type->opcode() != SpvOpTypeImage) {
     return false;
@@ -243,7 +243,7 @@
     return false;
   }
 
-  ir::Instruction* base_type =
+  opt::Instruction* base_type =
       context()->get_def_use_mgr()->GetDef(GetSingleWordInOperand(1));
   if (base_type->opcode() != SpvOpTypeImage) {
     return false;
@@ -269,7 +269,7 @@
     return false;
   }
 
-  ir::Instruction* base_type =
+  opt::Instruction* base_type =
       context()->get_def_use_mgr()->GetDef(GetSingleWordInOperand(1));
   if (base_type->opcode() != SpvOpTypeImage) {
     return false;
@@ -291,7 +291,7 @@
     return false;
   }
 
-  ir::Instruction* base_type =
+  opt::Instruction* base_type =
       context()->get_def_use_mgr()->GetDef(GetSingleWordInOperand(1));
 
   if (base_type->opcode() != SpvOpTypeStruct) {
@@ -303,13 +303,15 @@
     bool is_buffer_block = false;
     context()->get_decoration_mgr()->ForEachDecoration(
         base_type->result_id(), SpvDecorationBufferBlock,
-        [&is_buffer_block](const ir::Instruction&) { is_buffer_block = true; });
+        [&is_buffer_block](const opt::Instruction&) {
+          is_buffer_block = true;
+        });
     return is_buffer_block;
   } else if (storage_class == SpvStorageClassStorageBuffer) {
     bool is_block = false;
     context()->get_decoration_mgr()->ForEachDecoration(
         base_type->result_id(), SpvDecorationBlock,
-        [&is_block](const ir::Instruction&) { is_block = true; });
+        [&is_block](const opt::Instruction&) { is_block = true; });
     return is_block;
   }
   return false;
@@ -325,7 +327,7 @@
     return false;
   }
 
-  ir::Instruction* base_type =
+  opt::Instruction* base_type =
       context()->get_def_use_mgr()->GetDef(GetSingleWordInOperand(1));
   if (base_type->opcode() != SpvOpTypeStruct) {
     return false;
@@ -334,7 +336,7 @@
   bool is_block = false;
   context()->get_decoration_mgr()->ForEachDecoration(
       base_type->result_id(), SpvDecorationBlock,
-      [&is_block](const ir::Instruction&) { is_block = true; });
+      [&is_block](const opt::Instruction&) { is_block = true; });
   return is_block;
 }
 
@@ -414,7 +416,7 @@
     return false;
   }
 
-  ir::Instruction* type = context()->get_def_use_mgr()->GetDef(tid);
+  opt::Instruction* type = context()->get_def_use_mgr()->GetDef(tid);
   if (type->opcode() != SpvOpTypePointer) {
     return false;
   }
@@ -429,7 +431,7 @@
   }
 
   uint32_t pointee_type_id = type->GetSingleWordInOperand(1);
-  ir::Instruction* pointee_type_inst =
+  opt::Instruction* pointee_type_inst =
       context()->get_def_use_mgr()->GetDef(pointee_type_id);
 
   if (pointee_type_inst->IsOpaqueType()) {
@@ -444,7 +446,7 @@
     return false;
   }
 
-  ir::Instruction* type = context()->get_def_use_mgr()->GetDef(tid);
+  opt::Instruction* type = context()->get_def_use_mgr()->GetDef(tid);
   return (type->opcode() == SpvOpTypeImage ||
           type->opcode() == SpvOpTypeSampledImage);
 }
@@ -453,13 +455,14 @@
   if (opcode() == SpvOpTypeStruct) {
     bool is_opaque = false;
     ForEachInOperand([&is_opaque, this](const uint32_t* op_id) {
-      ir::Instruction* type_inst = context()->get_def_use_mgr()->GetDef(*op_id);
+      opt::Instruction* type_inst =
+          context()->get_def_use_mgr()->GetDef(*op_id);
       is_opaque |= type_inst->IsOpaqueType();
     });
     return is_opaque;
   } else if (opcode() == SpvOpTypeArray) {
     uint32_t sub_type_id = GetSingleWordInOperand(0);
-    ir::Instruction* sub_type_inst =
+    opt::Instruction* sub_type_inst =
         context()->get_def_use_mgr()->GetDef(sub_type_id);
     return sub_type_inst->IsOpaqueType();
   } else {
@@ -491,7 +494,7 @@
   bool is_nocontract = false;
   context_->get_decoration_mgr()->WhileEachDecoration(
       opcode_, SpvDecorationNoContraction,
-      [&is_nocontract](const ir::Instruction&) {
+      [&is_nocontract](const opt::Instruction&) {
         is_nocontract = true;
         return false;
       });
@@ -515,7 +518,7 @@
       options | SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
 }
 
-std::ostream& operator<<(std::ostream& str, const ir::Instruction& inst) {
+std::ostream& operator<<(std::ostream& str, const opt::Instruction& inst) {
   str << inst.PrettyPrint();
   return str;
 }
@@ -722,5 +725,5 @@
   }
 }
 
-}  // namespace ir
+}  // namespace opt
 }  // namespace spvtools
diff --git a/source/opt/instruction.h b/source/opt/instruction.h
index fa30415..807e7ae 100644
--- a/source/opt/instruction.h
+++ b/source/opt/instruction.h
@@ -31,7 +31,7 @@
 #include "spirv-tools/libspirv.h"
 
 namespace spvtools {
-namespace ir {
+namespace opt {
 
 class Function;
 class IRContext;
@@ -458,7 +458,7 @@
 // to provide the correct interpretation of types, constants, etc.
 //
 // Disassembly uses raw ids (not pretty printed names).
-std::ostream& operator<<(std::ostream& str, const ir::Instruction& inst);
+std::ostream& operator<<(std::ostream& str, const opt::Instruction& inst);
 
 inline bool Instruction::operator==(const Instruction& other) const {
   return unique_id() == other.unique_id();
@@ -709,7 +709,7 @@
 bool Instruction::IsConstant() const {
   return IsCompileTimeConstantInst(opcode());
 }
-}  // namespace ir
+}  // namespace opt
 }  // namespace spvtools
 
 #endif  // LIBSPIRV_OPT_INSTRUCTION_H_
diff --git a/source/opt/instruction_list.cpp b/source/opt/instruction_list.cpp
index d8ddb84..dfaaba4 100644
--- a/source/opt/instruction_list.cpp
+++ b/source/opt/instruction_list.cpp
@@ -15,7 +15,7 @@
 #include "instruction_list.h"
 
 namespace spvtools {
-namespace ir {
+namespace opt {
 
 InstructionList::iterator InstructionList::iterator::InsertBefore(
     std::vector<std::unique_ptr<Instruction>>&& list) {
@@ -32,5 +32,5 @@
   i.get()->InsertBefore(node_);
   return iterator(i.release());
 }
-}  // namespace ir
-}  // namespace spvtools
\ No newline at end of file
+}  // namespace opt
+}  // namespace spvtools
diff --git a/source/opt/instruction_list.h b/source/opt/instruction_list.h
index 182317f..1fb4d87 100644
--- a/source/opt/instruction_list.h
+++ b/source/opt/instruction_list.h
@@ -29,7 +29,7 @@
 #include "spirv-tools/libspirv.h"
 
 namespace spvtools {
-namespace ir {
+namespace opt {
 
 // This class is intended to be the container for Instructions.  This container
 // owns the instructions that are in it.  When removing an Instruction from the
@@ -124,7 +124,7 @@
   }
 }
 
-}  // namespace ir
+}  // namespace opt
 }  // namespace spvtools
 
 #endif  // LIBSPIRV_OPT_INSTRUCTION_LIST_H_
diff --git a/source/opt/ir_builder.h b/source/opt/ir_builder.h
index fe03c17..b0e0d30 100644
--- a/source/opt/ir_builder.h
+++ b/source/opt/ir_builder.h
@@ -34,31 +34,31 @@
 //   - Instruction to block analysis
 class InstructionBuilder {
  public:
-  using InsertionPointTy = ir::BasicBlock::iterator;
+  using InsertionPointTy = opt::BasicBlock::iterator;
 
   // Creates an InstructionBuilder, all new instructions will be inserted before
   // the instruction |insert_before|.
-  InstructionBuilder(
-      ir::IRContext* context, ir::Instruction* insert_before,
-      ir::IRContext::Analysis preserved_analyses = ir::IRContext::kAnalysisNone)
+  InstructionBuilder(opt::IRContext* context, opt::Instruction* insert_before,
+                     opt::IRContext::Analysis preserved_analyses =
+                         opt::IRContext::kAnalysisNone)
       : InstructionBuilder(context, context->get_instr_block(insert_before),
                            InsertionPointTy(insert_before),
                            preserved_analyses) {}
 
   // Creates an InstructionBuilder, all new instructions will be inserted at the
   // end of the basic block |parent_block|.
-  InstructionBuilder(
-      ir::IRContext* context, ir::BasicBlock* parent_block,
-      ir::IRContext::Analysis preserved_analyses = ir::IRContext::kAnalysisNone)
+  InstructionBuilder(opt::IRContext* context, opt::BasicBlock* parent_block,
+                     opt::IRContext::Analysis preserved_analyses =
+                         opt::IRContext::kAnalysisNone)
       : InstructionBuilder(context, parent_block, parent_block->end(),
                            preserved_analyses) {}
 
   // Creates a new selection merge instruction.
   // The id |merge_id| is the merge basic block id.
-  ir::Instruction* AddSelectionMerge(
+  opt::Instruction* AddSelectionMerge(
       uint32_t merge_id,
       uint32_t selection_control = SpvSelectionControlMaskNone) {
-    std::unique_ptr<ir::Instruction> new_branch_merge(new ir::Instruction(
+    std::unique_ptr<opt::Instruction> new_branch_merge(new opt::Instruction(
         GetContext(), SpvOpSelectionMerge, 0, 0,
         {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {merge_id}},
          {spv_operand_type_t::SPV_OPERAND_TYPE_SELECTION_CONTROL,
@@ -69,8 +69,8 @@
   // Creates a new branch instruction to |label_id|.
   // Note that the user must make sure the final basic block is
   // well formed.
-  ir::Instruction* AddBranch(uint32_t label_id) {
-    std::unique_ptr<ir::Instruction> new_branch(new ir::Instruction(
+  opt::Instruction* AddBranch(uint32_t label_id) {
+    std::unique_ptr<opt::Instruction> new_branch(new opt::Instruction(
         GetContext(), SpvOpBranch, 0, 0,
         {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {label_id}}}));
     return AddInstruction(std::move(new_branch));
@@ -91,14 +91,14 @@
   // selection merge instruction.
   // Note that the user must make sure the final basic block is
   // well formed.
-  ir::Instruction* AddConditionalBranch(
+  opt::Instruction* AddConditionalBranch(
       uint32_t cond_id, uint32_t true_id, uint32_t false_id,
       uint32_t merge_id = kInvalidId,
       uint32_t selection_control = SpvSelectionControlMaskNone) {
     if (merge_id != kInvalidId) {
       AddSelectionMerge(merge_id, selection_control);
     }
-    std::unique_ptr<ir::Instruction> new_branch(new ir::Instruction(
+    std::unique_ptr<opt::Instruction> new_branch(new opt::Instruction(
         GetContext(), SpvOpBranchConditional, 0, 0,
         {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {cond_id}},
          {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {true_id}},
@@ -119,28 +119,29 @@
   // selection merge instruction.
   // Note that the user must make sure the final basic block is
   // well formed.
-  ir::Instruction* AddSwitch(
+  opt::Instruction* AddSwitch(
       uint32_t selector_id, uint32_t default_id,
-      const std::vector<std::pair<ir::Operand::OperandData, uint32_t>>& targets,
+      const std::vector<std::pair<opt::Operand::OperandData, uint32_t>>&
+          targets,
       uint32_t merge_id = kInvalidId,
       uint32_t selection_control = SpvSelectionControlMaskNone) {
     if (merge_id != kInvalidId) {
       AddSelectionMerge(merge_id, selection_control);
     }
-    std::vector<ir::Operand> operands;
+    std::vector<opt::Operand> operands;
     operands.emplace_back(
-        ir::Operand{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {selector_id}});
+        opt::Operand{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {selector_id}});
     operands.emplace_back(
-        ir::Operand{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {default_id}});
+        opt::Operand{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {default_id}});
     for (auto& target : targets) {
-      operands.emplace_back(
-          ir::Operand{spv_operand_type_t::SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER,
-                      target.first});
-      operands.emplace_back(ir::Operand{spv_operand_type_t::SPV_OPERAND_TYPE_ID,
-                                        {target.second}});
+      operands.emplace_back(opt::Operand{
+          spv_operand_type_t::SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER,
+          target.first});
+      operands.emplace_back(opt::Operand{
+          spv_operand_type_t::SPV_OPERAND_TYPE_ID, {target.second}});
     }
-    std::unique_ptr<ir::Instruction> new_switch(
-        new ir::Instruction(GetContext(), SpvOpSwitch, 0, 0, operands));
+    std::unique_ptr<opt::Instruction> new_switch(
+        new opt::Instruction(GetContext(), SpvOpSwitch, 0, 0, operands));
     return AddInstruction(std::move(new_switch));
   }
 
@@ -148,14 +149,14 @@
   // The id |type| must be the id of the phi instruction's type.
   // The vector |incomings| must be a sequence of pairs of <definition id,
   // parent id>.
-  ir::Instruction* AddPhi(uint32_t type,
-                          const std::vector<uint32_t>& incomings) {
+  opt::Instruction* AddPhi(uint32_t type,
+                           const std::vector<uint32_t>& incomings) {
     assert(incomings.size() % 2 == 0 && "A sequence of pairs is expected");
-    std::vector<ir::Operand> phi_ops;
+    std::vector<opt::Operand> phi_ops;
     for (size_t i = 0; i < incomings.size(); i++) {
       phi_ops.push_back({SPV_OPERAND_TYPE_ID, {incomings[i]}});
     }
-    std::unique_ptr<ir::Instruction> phi_inst(new ir::Instruction(
+    std::unique_ptr<opt::Instruction> phi_inst(new opt::Instruction(
         GetContext(), SpvOpPhi, type, GetContext()->TakeNextId(), phi_ops));
     return AddInstruction(std::move(phi_inst));
   }
@@ -165,8 +166,8 @@
   // |op1| and |op2| types.
   // The id |op1| is the left hand side of the operation.
   // The id |op2| is the right hand side of the operation.
-  ir::Instruction* AddIAdd(uint32_t type, uint32_t op1, uint32_t op2) {
-    std::unique_ptr<ir::Instruction> inst(new ir::Instruction(
+  opt::Instruction* AddIAdd(uint32_t type, uint32_t op1, uint32_t op2) {
+    std::unique_ptr<opt::Instruction> inst(new opt::Instruction(
         GetContext(), SpvOpIAdd, type, GetContext()->TakeNextId(),
         {{SPV_OPERAND_TYPE_ID, {op1}}, {SPV_OPERAND_TYPE_ID, {op2}}}));
     return AddInstruction(std::move(inst));
@@ -176,10 +177,10 @@
   // The id |op1| is the left hand side of the operation.
   // The id |op2| is the right hand side of the operation.
   // It is assumed that |op1| and |op2| have the same underlying type.
-  ir::Instruction* AddULessThan(uint32_t op1, uint32_t op2) {
+  opt::Instruction* AddULessThan(uint32_t op1, uint32_t op2) {
     analysis::Bool bool_type;
     uint32_t type = GetContext()->get_type_mgr()->GetId(&bool_type);
-    std::unique_ptr<ir::Instruction> inst(new ir::Instruction(
+    std::unique_ptr<opt::Instruction> inst(new opt::Instruction(
         GetContext(), SpvOpULessThan, type, GetContext()->TakeNextId(),
         {{SPV_OPERAND_TYPE_ID, {op1}}, {SPV_OPERAND_TYPE_ID, {op2}}}));
     return AddInstruction(std::move(inst));
@@ -189,10 +190,10 @@
   // The id |op1| is the left hand side of the operation.
   // The id |op2| is the right hand side of the operation.
   // It is assumed that |op1| and |op2| have the same underlying type.
-  ir::Instruction* AddSLessThan(uint32_t op1, uint32_t op2) {
+  opt::Instruction* AddSLessThan(uint32_t op1, uint32_t op2) {
     analysis::Bool bool_type;
     uint32_t type = GetContext()->get_type_mgr()->GetId(&bool_type);
-    std::unique_ptr<ir::Instruction> inst(new ir::Instruction(
+    std::unique_ptr<opt::Instruction> inst(new opt::Instruction(
         GetContext(), SpvOpSLessThan, type, GetContext()->TakeNextId(),
         {{SPV_OPERAND_TYPE_ID, {op1}}, {SPV_OPERAND_TYPE_ID, {op2}}}));
     return AddInstruction(std::move(inst));
@@ -202,8 +203,8 @@
   // |op1|. The id |op1| is the left hand side of the operation. The id |op2| is
   // the right hand side of the operation. It is assumed that |op1| and |op2|
   // have the same underlying type.
-  ir::Instruction* AddLessThan(uint32_t op1, uint32_t op2) {
-    ir::Instruction* op1_insn = context_->get_def_use_mgr()->GetDef(op1);
+  opt::Instruction* AddLessThan(uint32_t op1, uint32_t op2) {
+    opt::Instruction* op1_insn = context_->get_def_use_mgr()->GetDef(op1);
     analysis::Type* type =
         GetContext()->get_type_mgr()->GetType(op1_insn->type_id());
     analysis::Integer* int_type = type->AsInteger();
@@ -219,11 +220,11 @@
   // |type| must match the types of |true_value| and |false_value|. It is up to
   // the caller to ensure that |cond| is a correct type (bool or vector of
   // bool) for |type|.
-  ir::Instruction* AddSelect(uint32_t type, uint32_t cond, uint32_t true_value,
-                             uint32_t false_value) {
-    std::unique_ptr<ir::Instruction> select(new ir::Instruction(
+  opt::Instruction* AddSelect(uint32_t type, uint32_t cond, uint32_t true_value,
+                              uint32_t false_value) {
+    std::unique_ptr<opt::Instruction> select(new opt::Instruction(
         GetContext(), SpvOpSelect, type, GetContext()->TakeNextId(),
-        std::initializer_list<ir::Operand>{
+        std::initializer_list<opt::Operand>{
             {SPV_OPERAND_TYPE_ID, {cond}},
             {SPV_OPERAND_TYPE_ID, {true_value}},
             {SPV_OPERAND_TYPE_ID, {false_value}}}));
@@ -232,28 +233,28 @@
 
   // Adds a signed int32 constant to the binary.
   // The |value| parameter is the constant value to be added.
-  ir::Instruction* Add32BitSignedIntegerConstant(int32_t value) {
+  opt::Instruction* Add32BitSignedIntegerConstant(int32_t value) {
     return Add32BitConstantInteger<int32_t>(value, true);
   }
 
   // Create a composite construct.
   // |type| should be a composite type and the number of elements it has should
   // match the size od |ids|.
-  ir::Instruction* AddCompositeConstruct(uint32_t type,
-                                         const std::vector<uint32_t>& ids) {
-    std::vector<ir::Operand> ops;
+  opt::Instruction* AddCompositeConstruct(uint32_t type,
+                                          const std::vector<uint32_t>& ids) {
+    std::vector<opt::Operand> ops;
     for (auto id : ids) {
       ops.emplace_back(SPV_OPERAND_TYPE_ID,
                        std::initializer_list<uint32_t>{id});
     }
-    std::unique_ptr<ir::Instruction> construct(
-        new ir::Instruction(GetContext(), SpvOpCompositeConstruct, type,
-                            GetContext()->TakeNextId(), ops));
+    std::unique_ptr<opt::Instruction> construct(
+        new opt::Instruction(GetContext(), SpvOpCompositeConstruct, type,
+                             GetContext()->TakeNextId(), ops));
     return AddInstruction(std::move(construct));
   }
   // Adds an unsigned int32 constant to the binary.
   // The |value| parameter is the constant value to be added.
-  ir::Instruction* Add32BitUnsignedIntegerConstant(uint32_t value) {
+  opt::Instruction* Add32BitUnsignedIntegerConstant(uint32_t value) {
     return Add32BitConstantInteger<uint32_t>(value, false);
   }
 
@@ -262,7 +263,7 @@
   // signed constant otherwise as an unsigned constant. If |sign| is false the
   // value must not be a negative number.
   template <typename T>
-  ir::Instruction* Add32BitConstantInteger(T value, bool sign) {
+  opt::Instruction* Add32BitConstantInteger(T value, bool sign) {
     // Assert that we are not trying to store a negative number in an unsigned
     // type.
     if (!sign)
@@ -293,58 +294,58 @@
     return GetContext()->get_constant_mgr()->GetDefiningInstruction(constant);
   }
 
-  ir::Instruction* AddCompositeExtract(
+  opt::Instruction* AddCompositeExtract(
       uint32_t type, uint32_t id_of_composite,
       const std::vector<uint32_t>& index_list) {
-    std::vector<ir::Operand> operands;
+    std::vector<opt::Operand> operands;
     operands.push_back({SPV_OPERAND_TYPE_ID, {id_of_composite}});
 
     for (uint32_t index : index_list) {
       operands.push_back({SPV_OPERAND_TYPE_LITERAL_INTEGER, {index}});
     }
 
-    std::unique_ptr<ir::Instruction> new_inst(
-        new ir::Instruction(GetContext(), SpvOpCompositeExtract, type,
-                            GetContext()->TakeNextId(), operands));
+    std::unique_ptr<opt::Instruction> new_inst(
+        new opt::Instruction(GetContext(), SpvOpCompositeExtract, type,
+                             GetContext()->TakeNextId(), operands));
     return AddInstruction(std::move(new_inst));
   }
 
   // Creates an unreachable instruction.
-  ir::Instruction* AddUnreachable() {
-    std::unique_ptr<ir::Instruction> select(
-        new ir::Instruction(GetContext(), SpvOpUnreachable, 0, 0,
-                            std::initializer_list<ir::Operand>{}));
+  opt::Instruction* AddUnreachable() {
+    std::unique_ptr<opt::Instruction> select(
+        new opt::Instruction(GetContext(), SpvOpUnreachable, 0, 0,
+                             std::initializer_list<opt::Operand>{}));
     return AddInstruction(std::move(select));
   }
 
-  ir::Instruction* AddAccessChain(uint32_t type_id, uint32_t base_ptr_id,
-                                  std::vector<uint32_t> ids) {
-    std::vector<ir::Operand> operands;
+  opt::Instruction* AddAccessChain(uint32_t type_id, uint32_t base_ptr_id,
+                                   std::vector<uint32_t> ids) {
+    std::vector<opt::Operand> operands;
     operands.push_back({SPV_OPERAND_TYPE_ID, {base_ptr_id}});
 
     for (uint32_t index_id : ids) {
       operands.push_back({SPV_OPERAND_TYPE_ID, {index_id}});
     }
 
-    std::unique_ptr<ir::Instruction> new_inst(
-        new ir::Instruction(GetContext(), SpvOpAccessChain, type_id,
-                            GetContext()->TakeNextId(), operands));
+    std::unique_ptr<opt::Instruction> new_inst(
+        new opt::Instruction(GetContext(), SpvOpAccessChain, type_id,
+                             GetContext()->TakeNextId(), operands));
     return AddInstruction(std::move(new_inst));
   }
 
-  ir::Instruction* AddLoad(uint32_t type_id, uint32_t base_ptr_id) {
-    std::vector<ir::Operand> operands;
+  opt::Instruction* AddLoad(uint32_t type_id, uint32_t base_ptr_id) {
+    std::vector<opt::Operand> operands;
     operands.push_back({SPV_OPERAND_TYPE_ID, {base_ptr_id}});
 
-    std::unique_ptr<ir::Instruction> new_inst(
-        new ir::Instruction(GetContext(), SpvOpLoad, type_id,
-                            GetContext()->TakeNextId(), operands));
+    std::unique_ptr<opt::Instruction> new_inst(
+        new opt::Instruction(GetContext(), SpvOpLoad, type_id,
+                             GetContext()->TakeNextId(), operands));
     return AddInstruction(std::move(new_inst));
   }
 
   // Inserts the new instruction before the insertion point.
-  ir::Instruction* AddInstruction(std::unique_ptr<ir::Instruction>&& insn) {
-    ir::Instruction* insn_ptr = &*insert_before_.InsertBefore(std::move(insn));
+  opt::Instruction* AddInstruction(std::unique_ptr<opt::Instruction>&& insn) {
+    opt::Instruction* insn_ptr = &*insert_before_.InsertBefore(std::move(insn));
     UpdateInstrToBlockMapping(insn_ptr);
     UpdateDefUseMgr(insn_ptr);
     return insn_ptr;
@@ -355,65 +356,65 @@
 
   // Change the insertion point to insert before the instruction
   // |insert_before|.
-  void SetInsertPoint(ir::Instruction* insert_before) {
+  void SetInsertPoint(opt::Instruction* insert_before) {
     parent_ = context_->get_instr_block(insert_before);
     insert_before_ = InsertionPointTy(insert_before);
   }
 
   // Change the insertion point to insert at the end of the basic block
   // |parent_block|.
-  void SetInsertPoint(ir::BasicBlock* parent_block) {
+  void SetInsertPoint(opt::BasicBlock* parent_block) {
     parent_ = parent_block;
     insert_before_ = parent_block->end();
   }
 
   // Returns the context which instructions are constructed for.
-  ir::IRContext* GetContext() const { return context_; }
+  opt::IRContext* GetContext() const { return context_; }
 
   // Returns the set of preserved analyses.
-  inline ir::IRContext::Analysis GetPreservedAnalysis() const {
+  inline opt::IRContext::Analysis GetPreservedAnalysis() const {
     return preserved_analyses_;
   }
 
  private:
-  InstructionBuilder(ir::IRContext* context, ir::BasicBlock* parent,
+  InstructionBuilder(opt::IRContext* context, opt::BasicBlock* parent,
                      InsertionPointTy insert_before,
-                     ir::IRContext::Analysis preserved_analyses)
+                     opt::IRContext::Analysis preserved_analyses)
       : context_(context),
         parent_(parent),
         insert_before_(insert_before),
         preserved_analyses_(preserved_analyses) {
     assert(!(preserved_analyses_ &
-             ~(ir::IRContext::kAnalysisDefUse |
-               ir::IRContext::kAnalysisInstrToBlockMapping)));
+             ~(opt::IRContext::kAnalysisDefUse |
+               opt::IRContext::kAnalysisInstrToBlockMapping)));
   }
 
   // Returns true if the users requested to update |analysis|.
   inline bool IsAnalysisUpdateRequested(
-      ir::IRContext::Analysis analysis) const {
+      opt::IRContext::Analysis analysis) const {
     return preserved_analyses_ & analysis;
   }
 
   // Updates the def/use manager if the user requested it. If he did not request
   // an update, this function does nothing.
-  inline void UpdateDefUseMgr(ir::Instruction* insn) {
-    if (IsAnalysisUpdateRequested(ir::IRContext::kAnalysisDefUse))
+  inline void UpdateDefUseMgr(opt::Instruction* insn) {
+    if (IsAnalysisUpdateRequested(opt::IRContext::kAnalysisDefUse))
       GetContext()->get_def_use_mgr()->AnalyzeInstDefUse(insn);
   }
 
   // Updates the instruction to block analysis if the user requested it. If he
   // did not request an update, this function does nothing.
-  inline void UpdateInstrToBlockMapping(ir::Instruction* insn) {
+  inline void UpdateInstrToBlockMapping(opt::Instruction* insn) {
     if (IsAnalysisUpdateRequested(
-            ir::IRContext::kAnalysisInstrToBlockMapping) &&
+            opt::IRContext::kAnalysisInstrToBlockMapping) &&
         parent_)
       GetContext()->set_instr_block(insn, parent_);
   }
 
-  ir::IRContext* context_;
-  ir::BasicBlock* parent_;
+  opt::IRContext* context_;
+  opt::BasicBlock* parent_;
   InsertionPointTy insert_before_;
-  const ir::IRContext::Analysis preserved_analyses_;
+  const opt::IRContext::Analysis preserved_analyses_;
 };
 
 }  // namespace opt
diff --git a/source/opt/ir_context.cpp b/source/opt/ir_context.cpp
index 0d20a84..96aa2f4 100644
--- a/source/opt/ir_context.cpp
+++ b/source/opt/ir_context.cpp
@@ -21,7 +21,7 @@
 #include <cstring>
 
 namespace spvtools {
-namespace ir {
+namespace opt {
 
 void IRContext::BuildInvalidAnalyses(IRContext::Analysis set) {
   if (set & kAnalysisDefUse) {
@@ -92,7 +92,7 @@
   valid_analyses_ = Analysis(valid_analyses_ & ~analyses_to_invalidate);
 }
 
-Instruction* IRContext::KillInst(ir::Instruction* inst) {
+Instruction* IRContext::KillInst(opt::Instruction* inst) {
   if (!inst) {
     return nullptr;
   }
@@ -114,11 +114,11 @@
     }
   }
 
-  if (type_mgr_ && ir::IsTypeInst(inst->opcode())) {
+  if (type_mgr_ && opt::IsTypeInst(inst->opcode())) {
     type_mgr_->RemoveId(inst->result_id());
   }
 
-  if (constant_mgr_ && ir::IsConstantInst(inst->opcode())) {
+  if (constant_mgr_ && opt::IsConstantInst(inst->opcode())) {
     constant_mgr_->RemoveId(inst->result_id());
   }
 
@@ -138,7 +138,7 @@
 }
 
 bool IRContext::KillDef(uint32_t id) {
-  ir::Instruction* def = get_def_use_mgr()->GetDef(id);
+  opt::Instruction* def = get_def_use_mgr()->GetDef(id);
   if (def != nullptr) {
     KillInst(def);
     return true;
@@ -153,15 +153,15 @@
   assert(get_def_use_mgr()->GetDef(after) &&
          "'after' is not a registered def.");
 
-  std::vector<std::pair<ir::Instruction*, uint32_t>> uses_to_update;
+  std::vector<std::pair<opt::Instruction*, uint32_t>> uses_to_update;
   get_def_use_mgr()->ForEachUse(
-      before, [&uses_to_update](ir::Instruction* user, uint32_t index) {
+      before, [&uses_to_update](opt::Instruction* user, uint32_t index) {
         uses_to_update.emplace_back(user, index);
       });
 
-  ir::Instruction* prev = nullptr;
+  opt::Instruction* prev = nullptr;
   for (auto p : uses_to_update) {
-    ir::Instruction* user = p.first;
+    opt::Instruction* user = p.first;
     uint32_t index = p.second;
     if (prev == nullptr || prev != user) {
       ForgetUses(user);
@@ -211,7 +211,7 @@
   if (AreAnalysesValid(kAnalysisInstrToBlockMapping)) {
     for (auto& func : *module()) {
       for (auto& block : func) {
-        if (!block.WhileEachInst([this, &block](ir::Instruction* inst) {
+        if (!block.WhileEachInst([this, &block](opt::Instruction* inst) {
               if (get_instr_block(inst) != &block) {
                 return false;
               }
@@ -257,18 +257,18 @@
 }
 
 void IRContext::KillNamesAndDecorates(uint32_t id) {
-  std::vector<ir::Instruction*> decorations =
+  std::vector<opt::Instruction*> decorations =
       get_decoration_mgr()->GetDecorationsFor(id, true);
 
   for (Instruction* inst : decorations) {
     KillInst(inst);
   }
 
-  std::vector<ir::Instruction*> name_to_kill;
+  std::vector<opt::Instruction*> name_to_kill;
   for (auto name : GetNames(id)) {
     name_to_kill.push_back(name.second);
   }
-  for (ir::Instruction* name_inst : name_to_kill) {
+  for (opt::Instruction* name_inst : name_to_kill) {
     KillInst(name_inst);
   }
 }
@@ -442,7 +442,7 @@
   }
 }
 
-void IRContext::AddCombinatorsForExtension(ir::Instruction* extension) {
+void IRContext::AddCombinatorsForExtension(opt::Instruction* extension) {
   assert(extension->opcode() == SpvOpExtInstImport &&
          "Expecting an import of an extension's instruction set.");
   const char* extension_name =
@@ -557,15 +557,15 @@
   }
 }
 
-ir::LoopDescriptor* IRContext::GetLoopDescriptor(const ir::Function* f) {
+opt::LoopDescriptor* IRContext::GetLoopDescriptor(const opt::Function* f) {
   if (!AreAnalysesValid(kAnalysisLoopAnalysis)) {
     ResetLoopAnalysis();
   }
 
-  std::unordered_map<const ir::Function*, ir::LoopDescriptor>::iterator it =
+  std::unordered_map<const opt::Function*, opt::LoopDescriptor>::iterator it =
       loop_descriptors_.find(f);
   if (it == loop_descriptors_.end()) {
-    return &loop_descriptors_.emplace(std::make_pair(f, ir::LoopDescriptor(f)))
+    return &loop_descriptors_.emplace(std::make_pair(f, opt::LoopDescriptor(f)))
                 .first->second;
   }
 
@@ -573,7 +573,8 @@
 }
 
 // Gets the dominator analysis for function |f|.
-opt::DominatorAnalysis* IRContext::GetDominatorAnalysis(const ir::Function* f) {
+opt::DominatorAnalysis* IRContext::GetDominatorAnalysis(
+    const opt::Function* f) {
   if (!AreAnalysesValid(kAnalysisDominatorAnalysis)) {
     ResetDominatorAnalysis();
   }
@@ -587,7 +588,7 @@
 
 // Gets the postdominator analysis for function |f|.
 opt::PostDominatorAnalysis* IRContext::GetPostDominatorAnalysis(
-    const ir::Function* f) {
+    const opt::Function* f) {
   if (!AreAnalysesValid(kAnalysisDominatorAnalysis)) {
     ResetDominatorAnalysis();
   }
@@ -599,13 +600,13 @@
   return &post_dominator_trees_[f];
 }
 
-bool ir::IRContext::CheckCFG() {
+bool opt::IRContext::CheckCFG() {
   std::unordered_map<uint32_t, std::vector<uint32_t>> real_preds;
   if (!AreAnalysesValid(kAnalysisCFG)) {
     return true;
   }
 
-  for (ir::Function& function : *module()) {
+  for (opt::Function& function : *module()) {
     for (const auto& bb : function) {
       bb.ForEachSuccessorLabel([&bb, &real_preds](const uint32_t lab_id) {
         real_preds[lab_id].push_back(bb.id());
@@ -650,5 +651,5 @@
 
   return true;
 }
-}  // namespace ir
+}  // namespace opt
 }  // namespace spvtools
diff --git a/source/opt/ir_context.h b/source/opt/ir_context.h
index 2daa92b..5d37fcb 100644
--- a/source/opt/ir_context.h
+++ b/source/opt/ir_context.h
@@ -36,7 +36,7 @@
 #include <unordered_set>
 
 namespace spvtools {
-namespace ir {
+namespace opt {
 
 class IRContext {
  public:
@@ -126,8 +126,8 @@
   inline IteratorRange<Module::const_inst_iterator> capabilities() const;
 
   // Iterators for types, constants and global variables instructions.
-  inline ir::Module::inst_iterator types_values_begin();
-  inline ir::Module::inst_iterator types_values_end();
+  inline opt::Module::inst_iterator types_values_begin();
+  inline opt::Module::inst_iterator types_values_end();
   inline IteratorRange<Module::inst_iterator> types_values();
   inline IteratorRange<Module::const_inst_iterator> types_values() const;
 
@@ -230,7 +230,7 @@
 
   // Returns the basic block for instruction |instr|. Re-builds the instruction
   // block map, if needed.
-  ir::BasicBlock* get_instr_block(ir::Instruction* instr) {
+  opt::BasicBlock* get_instr_block(opt::Instruction* instr) {
     if (!AreAnalysesValid(kAnalysisInstrToBlockMapping)) {
       BuildInstrToBlockMapping();
     }
@@ -242,14 +242,14 @@
   // needed.
   //
   // |id| must be a registered definition.
-  ir::BasicBlock* get_instr_block(uint32_t id) {
-    ir::Instruction* def = get_def_use_mgr()->GetDef(id);
+  opt::BasicBlock* get_instr_block(uint32_t id) {
+    opt::Instruction* def = get_def_use_mgr()->GetDef(id);
     return get_instr_block(def);
   }
 
   // Sets the basic block for |inst|. Re-builds the mapping if it has become
   // invalid.
-  void set_instr_block(ir::Instruction* inst, ir::BasicBlock* block) {
+  void set_instr_block(opt::Instruction* inst, opt::BasicBlock* block) {
     if (AreAnalysesValid(kAnalysisInstrToBlockMapping)) {
       instr_to_block_[inst] = block;
     }
@@ -337,7 +337,7 @@
   //
   // Returns a pointer to the instruction after |inst| or |nullptr| if no such
   // instruction exists.
-  Instruction* KillInst(ir::Instruction* inst);
+  Instruction* KillInst(opt::Instruction* inst);
 
   // Returns true if all of the given analyses are valid.
   bool AreAnalysesValid(Analysis set) { return (set & valid_analyses_) == set; }
@@ -371,7 +371,7 @@
   void KillNamesAndDecorates(uint32_t id);
 
   // Kill all name and decorate ops targeting the result id of |inst|.
-  void KillNamesAndDecorates(ir::Instruction* inst);
+  void KillNamesAndDecorates(opt::Instruction* inst);
 
   // Returns the next unique id for use by an instruction.
   inline uint32_t TakeNextUniqueId() {
@@ -400,7 +400,7 @@
   }
 
   // Returns a pointer to the CFG for all the functions in |module_|.
-  ir::CFG* cfg() {
+  opt::CFG* cfg() {
     if (!AreAnalysesValid(kAnalysisCFG)) {
       BuildCFG();
     }
@@ -408,21 +408,21 @@
   }
 
   // Gets the loop descriptor for function |f|.
-  ir::LoopDescriptor* GetLoopDescriptor(const ir::Function* f);
+  opt::LoopDescriptor* GetLoopDescriptor(const opt::Function* f);
 
   // Gets the dominator analysis for function |f|.
-  opt::DominatorAnalysis* GetDominatorAnalysis(const ir::Function* f);
+  opt::DominatorAnalysis* GetDominatorAnalysis(const opt::Function* f);
 
   // Gets the postdominator analysis for function |f|.
-  opt::PostDominatorAnalysis* GetPostDominatorAnalysis(const ir::Function* f);
+  opt::PostDominatorAnalysis* GetPostDominatorAnalysis(const opt::Function* f);
 
   // Remove the dominator tree of |f| from the cache.
-  inline void RemoveDominatorAnalysis(const ir::Function* f) {
+  inline void RemoveDominatorAnalysis(const opt::Function* f) {
     dominator_trees_.erase(f);
   }
 
   // Remove the postdominator tree of |f| from the cache.
-  inline void RemovePostDominatorAnalysis(const ir::Function* f) {
+  inline void RemovePostDominatorAnalysis(const opt::Function* f) {
     post_dominator_trees_.erase(f);
   }
 
@@ -462,7 +462,7 @@
     instr_to_block_.clear();
     for (auto& fn : *module_) {
       for (auto& block : fn) {
-        block.ForEachInst([this, &block](ir::Instruction* inst) {
+        block.ForEachInst([this, &block](opt::Instruction* inst) {
           instr_to_block_[inst] = &block;
         });
       }
@@ -476,7 +476,7 @@
   }
 
   void BuildCFG() {
-    cfg_.reset(new ir::CFG(module()));
+    cfg_.reset(new opt::CFG(module()));
     valid_analyses_ = valid_analyses_ | kAnalysisCFG;
   }
 
@@ -528,7 +528,7 @@
   void AddCombinatorsForCapability(uint32_t capability);
 
   // Add the combinator opcode for the given extension to combinator_ops_.
-  void AddCombinatorsForExtension(ir::Instruction* extension);
+  void AddCombinatorsForExtension(opt::Instruction* extension);
 
   // Remove |inst| from |id_to_name_| if it is in map.
   void RemoveFromIdToName(const Instruction* inst);
@@ -569,7 +569,7 @@
   //
   // NOTE: Do not traverse this map. Ever. Use the function and basic block
   // iterators to traverse instructions.
-  std::unordered_map<ir::Instruction*, ir::BasicBlock*> instr_to_block_;
+  std::unordered_map<opt::Instruction*, opt::BasicBlock*> instr_to_block_;
 
   // A bitset indicating which analyes are currently valid.
   Analysis valid_analyses_;
@@ -579,16 +579,17 @@
   std::unordered_map<uint32_t, std::unordered_set<uint32_t>> combinator_ops_;
 
   // The CFG for all the functions in |module_|.
-  std::unique_ptr<ir::CFG> cfg_;
+  std::unique_ptr<opt::CFG> cfg_;
 
   // Each function in the module will create its own dominator tree. We cache
   // the result so it doesn't need to be rebuilt each time.
-  std::map<const ir::Function*, opt::DominatorAnalysis> dominator_trees_;
-  std::map<const ir::Function*, opt::PostDominatorAnalysis>
+  std::map<const opt::Function*, opt::DominatorAnalysis> dominator_trees_;
+  std::map<const opt::Function*, opt::PostDominatorAnalysis>
       post_dominator_trees_;
 
   // Cache of loop descriptors for each function.
-  std::unordered_map<const ir::Function*, ir::LoopDescriptor> loop_descriptors_;
+  std::unordered_map<const opt::Function*, opt::LoopDescriptor>
+      loop_descriptors_;
 
   // Constant manager for |module_|.
   std::unique_ptr<opt::analysis::ConstantManager> constant_mgr_;
@@ -610,27 +611,27 @@
   std::unique_ptr<opt::InstructionFolder> inst_folder_;
 };
 
-inline ir::IRContext::Analysis operator|(ir::IRContext::Analysis lhs,
-                                         ir::IRContext::Analysis rhs) {
-  return static_cast<ir::IRContext::Analysis>(static_cast<int>(lhs) |
-                                              static_cast<int>(rhs));
+inline opt::IRContext::Analysis operator|(opt::IRContext::Analysis lhs,
+                                          opt::IRContext::Analysis rhs) {
+  return static_cast<opt::IRContext::Analysis>(static_cast<int>(lhs) |
+                                               static_cast<int>(rhs));
 }
 
-inline ir::IRContext::Analysis& operator|=(ir::IRContext::Analysis& lhs,
-                                           ir::IRContext::Analysis rhs) {
-  lhs = static_cast<ir::IRContext::Analysis>(static_cast<int>(lhs) |
-                                             static_cast<int>(rhs));
+inline opt::IRContext::Analysis& operator|=(opt::IRContext::Analysis& lhs,
+                                            opt::IRContext::Analysis rhs) {
+  lhs = static_cast<opt::IRContext::Analysis>(static_cast<int>(lhs) |
+                                              static_cast<int>(rhs));
   return lhs;
 }
 
-inline ir::IRContext::Analysis operator<<(ir::IRContext::Analysis a,
-                                          int shift) {
-  return static_cast<ir::IRContext::Analysis>(static_cast<int>(a) << shift);
+inline opt::IRContext::Analysis operator<<(opt::IRContext::Analysis a,
+                                           int shift) {
+  return static_cast<opt::IRContext::Analysis>(static_cast<int>(a) << shift);
 }
 
-inline ir::IRContext::Analysis& operator<<=(ir::IRContext::Analysis& a,
-                                            int shift) {
-  a = static_cast<ir::IRContext::Analysis>(static_cast<int>(a) << shift);
+inline opt::IRContext::Analysis& operator<<=(opt::IRContext::Analysis& a,
+                                             int shift) {
+  a = static_cast<opt::IRContext::Analysis>(static_cast<int>(a) << shift);
   return a;
 }
 
@@ -674,11 +675,11 @@
   return ((const Module*)module())->capabilities();
 }
 
-ir::Module::inst_iterator IRContext::types_values_begin() {
+opt::Module::inst_iterator IRContext::types_values_begin() {
   return module()->types_values_begin();
 }
 
-ir::Module::inst_iterator IRContext::types_values_end() {
+opt::Module::inst_iterator IRContext::types_values_end() {
   return module()->types_values_end();
 }
 
@@ -849,7 +850,7 @@
   return make_range(std::move(result.first), std::move(result.second));
 }
 
-}  // namespace ir
+}  // namespace opt
 }  // namespace spvtools
 
 #endif  // SPIRV_TOOLS_IR_CONTEXT_H
diff --git a/source/opt/ir_loader.cpp b/source/opt/ir_loader.cpp
index a526d6f..eb9a055 100644
--- a/source/opt/ir_loader.cpp
+++ b/source/opt/ir_loader.cpp
@@ -18,7 +18,7 @@
 #include "reflect.h"
 
 namespace spvtools {
-namespace ir {
+namespace opt {
 
 IrLoader::IrLoader(const MessageConsumer& consumer, Module* m)
     : consumer_(consumer),
@@ -157,5 +157,5 @@
   }
 }
 
-}  // namespace ir
+}  // namespace opt
 }  // namespace spvtools
diff --git a/source/opt/ir_loader.h b/source/opt/ir_loader.h
index 2f0ca8b..8bf0edb 100644
--- a/source/opt/ir_loader.h
+++ b/source/opt/ir_loader.h
@@ -23,7 +23,7 @@
 #include "spirv-tools/libspirv.hpp"
 
 namespace spvtools {
-namespace ir {
+namespace opt {
 
 // Loader class for constructing SPIR-V in-memory IR representation. Methods in
 // this class are designed to work with the interface for spvBinaryParse() in
@@ -78,7 +78,7 @@
   std::vector<Instruction> dbg_line_info_;
 };
 
-}  // namespace ir
+}  // namespace opt
 }  // namespace spvtools
 
 #endif  // LIBSPIRV_OPT_IR_LOADER_H_
diff --git a/source/opt/iterator.h b/source/opt/iterator.h
index 13ff979..2f011b3 100644
--- a/source/opt/iterator.h
+++ b/source/opt/iterator.h
@@ -22,7 +22,7 @@
 #include <vector>
 
 namespace spvtools {
-namespace ir {
+namespace opt {
 
 // An ad hoc iterator class for std::vector<std::unique_ptr<|ValueType|>>. The
 // purpose of this iterator class is to provide transparent access to those
@@ -351,7 +351,7 @@
   return UptrVectorIterator(container_, container_->begin() + index);
 }
 
-}  // namespace ir
+}  // namespace opt
 }  // namespace spvtools
 
 #endif  // LIBSPIRV_OPT_ITERATOR_H_
diff --git a/source/opt/licm_pass.cpp b/source/opt/licm_pass.cpp
index abefb44..3178671 100644
--- a/source/opt/licm_pass.cpp
+++ b/source/opt/licm_pass.cpp
@@ -22,7 +22,7 @@
 namespace spvtools {
 namespace opt {
 
-Pass::Status LICMPass::Process(ir::IRContext* c) {
+Pass::Status LICMPass::Process(opt::IRContext* c) {
   InitializeProcessing(c);
   bool modified = false;
 
@@ -35,21 +35,21 @@
 
 bool LICMPass::ProcessIRContext() {
   bool modified = false;
-  ir::Module* module = get_module();
+  opt::Module* module = get_module();
 
   // Process each function in the module
-  for (ir::Function& f : *module) {
+  for (opt::Function& f : *module) {
     modified |= ProcessFunction(&f);
   }
   return modified;
 }
 
-bool LICMPass::ProcessFunction(ir::Function* f) {
+bool LICMPass::ProcessFunction(opt::Function* f) {
   bool modified = false;
-  ir::LoopDescriptor* loop_descriptor = context()->GetLoopDescriptor(f);
+  opt::LoopDescriptor* loop_descriptor = context()->GetLoopDescriptor(f);
 
   // Process each loop in the function
-  for (ir::Loop& loop : *loop_descriptor) {
+  for (opt::Loop& loop : *loop_descriptor) {
     // Ignore nested loops, as we will process them in order in ProcessLoop
     if (loop.IsNested()) {
       continue;
@@ -59,19 +59,19 @@
   return modified;
 }
 
-bool LICMPass::ProcessLoop(ir::Loop* loop, ir::Function* f) {
+bool LICMPass::ProcessLoop(opt::Loop* loop, opt::Function* f) {
   bool modified = false;
 
   // Process all nested loops first
-  for (ir::Loop* nested_loop : *loop) {
+  for (opt::Loop* nested_loop : *loop) {
     modified |= ProcessLoop(nested_loop, f);
   }
 
-  std::vector<ir::BasicBlock*> loop_bbs{};
+  std::vector<opt::BasicBlock*> loop_bbs{};
   modified |= AnalyseAndHoistFromBB(loop, f, loop->GetHeaderBlock(), &loop_bbs);
 
   for (size_t i = 0; i < loop_bbs.size(); ++i) {
-    ir::BasicBlock* bb = loop_bbs[i];
+    opt::BasicBlock* bb = loop_bbs[i];
     // do not delete the element
     modified |= AnalyseAndHoistFromBB(loop, f, bb, &loop_bbs);
   }
@@ -79,12 +79,12 @@
   return modified;
 }
 
-bool LICMPass::AnalyseAndHoistFromBB(ir::Loop* loop, ir::Function* f,
-                                     ir::BasicBlock* bb,
-                                     std::vector<ir::BasicBlock*>* loop_bbs) {
+bool LICMPass::AnalyseAndHoistFromBB(opt::Loop* loop, opt::Function* f,
+                                     opt::BasicBlock* bb,
+                                     std::vector<opt::BasicBlock*>* loop_bbs) {
   bool modified = false;
-  std::function<void(ir::Instruction*)> hoist_inst =
-      [this, &loop, &modified](ir::Instruction* inst) {
+  std::function<void(opt::Instruction*)> hoist_inst =
+      [this, &loop, &modified](opt::Instruction* inst) {
         if (loop->ShouldHoistInstruction(this->context(), inst)) {
           HoistInstruction(loop, inst);
           modified = true;
@@ -108,14 +108,14 @@
   return modified;
 }
 
-bool LICMPass::IsImmediatelyContainedInLoop(ir::Loop* loop, ir::Function* f,
-                                            ir::BasicBlock* bb) {
-  ir::LoopDescriptor* loop_descriptor = context()->GetLoopDescriptor(f);
+bool LICMPass::IsImmediatelyContainedInLoop(opt::Loop* loop, opt::Function* f,
+                                            opt::BasicBlock* bb) {
+  opt::LoopDescriptor* loop_descriptor = context()->GetLoopDescriptor(f);
   return loop == (*loop_descriptor)[bb->id()];
 }
 
-void LICMPass::HoistInstruction(ir::Loop* loop, ir::Instruction* inst) {
-  ir::BasicBlock* pre_header_bb = loop->GetOrCreatePreHeaderBlock();
+void LICMPass::HoistInstruction(opt::Loop* loop, opt::Instruction* inst) {
+  opt::BasicBlock* pre_header_bb = loop->GetOrCreatePreHeaderBlock();
   inst->InsertBefore(std::move(&(*pre_header_bb->tail())));
   context()->set_instr_block(inst, pre_header_bb);
 }
diff --git a/source/opt/licm_pass.h b/source/opt/licm_pass.h
index 1d8ae20..105e3a7 100644
--- a/source/opt/licm_pass.h
+++ b/source/opt/licm_pass.h
@@ -30,7 +30,7 @@
   LICMPass() {}
 
   const char* name() const override { return "loop-invariant-code-motion"; }
-  Status Process(ir::IRContext*) override;
+  Status Process(opt::IRContext*) override;
 
  private:
   // Searches the IRContext for functions and processes each, moving invariants
@@ -40,26 +40,26 @@
 
   // Checks the function for loops, calling ProcessLoop on each one found.
   // Returns true if a change was made to the function, false otherwise.
-  bool ProcessFunction(ir::Function* f);
+  bool ProcessFunction(opt::Function* f);
 
   // Checks for invariants in the loop and attempts to move them to the loops
   // preheader. Works from inner loop to outer when nested loops are found.
   // Returns true if a change was made to the loop, false otherwise.
-  bool ProcessLoop(ir::Loop* loop, ir::Function* f);
+  bool ProcessLoop(opt::Loop* loop, opt::Function* f);
 
   // Analyses each instruction in |bb|, hoisting invariants to |pre_header_bb|.
   // Each child of |bb| wrt to |dom_tree| is pushed to |loop_bbs|
-  bool AnalyseAndHoistFromBB(ir::Loop* loop, ir::Function* f,
-                             ir::BasicBlock* bb,
-                             std::vector<ir::BasicBlock*>* loop_bbs);
+  bool AnalyseAndHoistFromBB(opt::Loop* loop, opt::Function* f,
+                             opt::BasicBlock* bb,
+                             std::vector<opt::BasicBlock*>* loop_bbs);
 
   // Returns true if |bb| is immediately contained in |loop|
-  bool IsImmediatelyContainedInLoop(ir::Loop* loop, ir::Function* f,
-                                    ir::BasicBlock* bb);
+  bool IsImmediatelyContainedInLoop(opt::Loop* loop, opt::Function* f,
+                                    opt::BasicBlock* bb);
 
   // Move the instruction to the given BasicBlock
   // This method will update the instruction to block mapping for the context
-  void HoistInstruction(ir::Loop* loop, ir::Instruction* inst);
+  void HoistInstruction(opt::Loop* loop, opt::Instruction* inst);
 };
 
 }  // namespace opt
diff --git a/source/opt/local_access_chain_convert_pass.cpp b/source/opt/local_access_chain_convert_pass.cpp
index f87478a..175d8f4 100644
--- a/source/opt/local_access_chain_convert_pass.cpp
+++ b/source/opt/local_access_chain_convert_pass.cpp
@@ -33,20 +33,20 @@
 
 void LocalAccessChainConvertPass::BuildAndAppendInst(
     SpvOp opcode, uint32_t typeId, uint32_t resultId,
-    const std::vector<ir::Operand>& in_opnds,
-    std::vector<std::unique_ptr<ir::Instruction>>* newInsts) {
-  std::unique_ptr<ir::Instruction> newInst(
-      new ir::Instruction(context(), opcode, typeId, resultId, in_opnds));
+    const std::vector<opt::Operand>& in_opnds,
+    std::vector<std::unique_ptr<opt::Instruction>>* newInsts) {
+  std::unique_ptr<opt::Instruction> newInst(
+      new opt::Instruction(context(), opcode, typeId, resultId, in_opnds));
   get_def_use_mgr()->AnalyzeInstDefUse(&*newInst);
   newInsts->emplace_back(std::move(newInst));
 }
 
 uint32_t LocalAccessChainConvertPass::BuildAndAppendVarLoad(
-    const ir::Instruction* ptrInst, uint32_t* varId, uint32_t* varPteTypeId,
-    std::vector<std::unique_ptr<ir::Instruction>>* newInsts) {
+    const opt::Instruction* ptrInst, uint32_t* varId, uint32_t* varPteTypeId,
+    std::vector<std::unique_ptr<opt::Instruction>>* newInsts) {
   const uint32_t ldResultId = TakeNextId();
   *varId = ptrInst->GetSingleWordInOperand(kAccessChainPtrIdInIdx);
-  const ir::Instruction* varInst = get_def_use_mgr()->GetDef(*varId);
+  const opt::Instruction* varInst = get_def_use_mgr()->GetDef(*varId);
   assert(varInst->opcode() == SpvOpVariable);
   *varPteTypeId = GetPointeeTypeId(varInst);
   BuildAndAppendInst(SpvOpLoad, *varPteTypeId, ldResultId,
@@ -56,11 +56,11 @@
 }
 
 void LocalAccessChainConvertPass::AppendConstantOperands(
-    const ir::Instruction* ptrInst, std::vector<ir::Operand>* in_opnds) {
+    const opt::Instruction* ptrInst, std::vector<opt::Operand>* in_opnds) {
   uint32_t iidIdx = 0;
   ptrInst->ForEachInId([&iidIdx, &in_opnds, this](const uint32_t* iid) {
     if (iidIdx > 0) {
-      const ir::Instruction* cInst = get_def_use_mgr()->GetDef(*iid);
+      const opt::Instruction* cInst = get_def_use_mgr()->GetDef(*iid);
       uint32_t val = cInst->GetSingleWordInOperand(kConstantValueInIdx);
       in_opnds->push_back(
           {spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER, {val}});
@@ -70,8 +70,8 @@
 }
 
 uint32_t LocalAccessChainConvertPass::GenAccessChainLoadReplacement(
-    const ir::Instruction* ptrInst,
-    std::vector<std::unique_ptr<ir::Instruction>>* newInsts) {
+    const opt::Instruction* ptrInst,
+    std::vector<std::unique_ptr<opt::Instruction>>* newInsts) {
   // Build and append load of variable in ptrInst
   uint32_t varId;
   uint32_t varPteTypeId;
@@ -81,7 +81,7 @@
   // Build and append Extract
   const uint32_t extResultId = TakeNextId();
   const uint32_t ptrPteTypeId = GetPointeeTypeId(ptrInst);
-  std::vector<ir::Operand> ext_in_opnds = {
+  std::vector<opt::Operand> ext_in_opnds = {
       {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {ldResultId}}};
   AppendConstantOperands(ptrInst, &ext_in_opnds);
   BuildAndAppendInst(SpvOpCompositeExtract, ptrPteTypeId, extResultId,
@@ -90,8 +90,8 @@
 }
 
 void LocalAccessChainConvertPass::GenAccessChainStoreReplacement(
-    const ir::Instruction* ptrInst, uint32_t valId,
-    std::vector<std::unique_ptr<ir::Instruction>>* newInsts) {
+    const opt::Instruction* ptrInst, uint32_t valId,
+    std::vector<std::unique_ptr<opt::Instruction>>* newInsts) {
   // Build and append load of variable in ptrInst
   uint32_t varId;
   uint32_t varPteTypeId;
@@ -100,7 +100,7 @@
 
   // Build and append Insert
   const uint32_t insResultId = TakeNextId();
-  std::vector<ir::Operand> ins_in_opnds = {
+  std::vector<opt::Operand> ins_in_opnds = {
       {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {valId}},
       {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {ldResultId}}};
   AppendConstantOperands(ptrInst, &ins_in_opnds);
@@ -115,11 +115,11 @@
 }
 
 bool LocalAccessChainConvertPass::IsConstantIndexAccessChain(
-    const ir::Instruction* acp) const {
+    const opt::Instruction* acp) const {
   uint32_t inIdx = 0;
   return acp->WhileEachInId([&inIdx, this](const uint32_t* tid) {
     if (inIdx > 0) {
-      ir::Instruction* opInst = get_def_use_mgr()->GetDef(*tid);
+      opt::Instruction* opInst = get_def_use_mgr()->GetDef(*tid);
       if (opInst->opcode() != SpvOpConstant) return false;
     }
     ++inIdx;
@@ -129,7 +129,7 @@
 
 bool LocalAccessChainConvertPass::HasOnlySupportedRefs(uint32_t ptrId) {
   if (supported_ref_ptrs_.find(ptrId) != supported_ref_ptrs_.end()) return true;
-  if (get_def_use_mgr()->WhileEachUser(ptrId, [this](ir::Instruction* user) {
+  if (get_def_use_mgr()->WhileEachUser(ptrId, [this](opt::Instruction* user) {
         SpvOp op = user->opcode();
         if (IsNonPtrAccessChain(op) || op == SpvOpCopyObject) {
           if (!HasOnlySupportedRefs(user->result_id())) {
@@ -147,14 +147,14 @@
   return false;
 }
 
-void LocalAccessChainConvertPass::FindTargetVars(ir::Function* func) {
+void LocalAccessChainConvertPass::FindTargetVars(opt::Function* func) {
   for (auto bi = func->begin(); bi != func->end(); ++bi) {
     for (auto ii = bi->begin(); ii != bi->end(); ++ii) {
       switch (ii->opcode()) {
         case SpvOpStore:
         case SpvOpLoad: {
           uint32_t varId;
-          ir::Instruction* ptrInst = GetPtr(&*ii, &varId);
+          opt::Instruction* ptrInst = GetPtr(&*ii, &varId);
           if (!IsTargetVar(varId)) break;
           const SpvOp op = ptrInst->opcode();
           // Rule out variables with non-supported refs eg function calls
@@ -185,21 +185,22 @@
   }
 }
 
-bool LocalAccessChainConvertPass::ConvertLocalAccessChains(ir::Function* func) {
+bool LocalAccessChainConvertPass::ConvertLocalAccessChains(
+    opt::Function* func) {
   FindTargetVars(func);
   // Replace access chains of all targeted variables with equivalent
   // extract and insert sequences
   bool modified = false;
   for (auto bi = func->begin(); bi != func->end(); ++bi) {
-    std::vector<ir::Instruction*> dead_instructions;
+    std::vector<opt::Instruction*> dead_instructions;
     for (auto ii = bi->begin(); ii != bi->end(); ++ii) {
       switch (ii->opcode()) {
         case SpvOpLoad: {
           uint32_t varId;
-          ir::Instruction* ptrInst = GetPtr(&*ii, &varId);
+          opt::Instruction* ptrInst = GetPtr(&*ii, &varId);
           if (!IsNonPtrAccessChain(ptrInst->opcode())) break;
           if (!IsTargetVar(varId)) break;
-          std::vector<std::unique_ptr<ir::Instruction>> newInsts;
+          std::vector<std::unique_ptr<opt::Instruction>> newInsts;
           uint32_t replId = GenAccessChainLoadReplacement(ptrInst, &newInsts);
           context()->KillNamesAndDecorates(&*ii);
           context()->ReplaceAllUsesWith(ii->result_id(), replId);
@@ -211,10 +212,10 @@
         } break;
         case SpvOpStore: {
           uint32_t varId;
-          ir::Instruction* ptrInst = GetPtr(&*ii, &varId);
+          opt::Instruction* ptrInst = GetPtr(&*ii, &varId);
           if (!IsNonPtrAccessChain(ptrInst->opcode())) break;
           if (!IsTargetVar(varId)) break;
-          std::vector<std::unique_ptr<ir::Instruction>> newInsts;
+          std::vector<std::unique_ptr<opt::Instruction>> newInsts;
           uint32_t valId = ii->GetSingleWordInOperand(kStoreValIdInIdx);
           GenAccessChainStoreReplacement(ptrInst, valId, &newInsts);
           dead_instructions.push_back(&*ii);
@@ -230,9 +231,9 @@
     }
 
     while (!dead_instructions.empty()) {
-      ir::Instruction* inst = dead_instructions.back();
+      opt::Instruction* inst = dead_instructions.back();
       dead_instructions.pop_back();
-      DCEInst(inst, [&dead_instructions](ir::Instruction* other_inst) {
+      DCEInst(inst, [&dead_instructions](opt::Instruction* other_inst) {
         auto i = std::find(dead_instructions.begin(), dead_instructions.end(),
                            other_inst);
         if (i != dead_instructions.end()) {
@@ -244,7 +245,7 @@
   return modified;
 }
 
-void LocalAccessChainConvertPass::Initialize(ir::IRContext* c) {
+void LocalAccessChainConvertPass::Initialize(opt::IRContext* c) {
   InitializeProcessing(c);
 
   // Initialize Target Variable Caches
@@ -272,7 +273,7 @@
 Pass::Status LocalAccessChainConvertPass::ProcessImpl() {
   // If non-32-bit integer type in module, terminate processing
   // TODO(): Handle non-32-bit integer constants in access chains
-  for (const ir::Instruction& inst : get_module()->types_values())
+  for (const opt::Instruction& inst : get_module()->types_values())
     if (inst.opcode() == SpvOpTypeInt &&
         inst.GetSingleWordInOperand(kTypeIntWidthInIdx) != 32)
       return Status::SuccessWithoutChange;
@@ -284,7 +285,7 @@
   // Do not process if any disallowed extensions are enabled
   if (!AllExtensionsSupported()) return Status::SuccessWithoutChange;
   // Process all entry point functions.
-  ProcessFunction pfn = [this](ir::Function* fp) {
+  ProcessFunction pfn = [this](opt::Function* fp) {
     return ConvertLocalAccessChains(fp);
   };
   bool modified = ProcessEntryPointCallTree(pfn, get_module());
@@ -293,7 +294,7 @@
 
 LocalAccessChainConvertPass::LocalAccessChainConvertPass() {}
 
-Pass::Status LocalAccessChainConvertPass::Process(ir::IRContext* c) {
+Pass::Status LocalAccessChainConvertPass::Process(opt::IRContext* c) {
   Initialize(c);
   return ProcessImpl();
 }
diff --git a/source/opt/local_access_chain_convert_pass.h b/source/opt/local_access_chain_convert_pass.h
index 98f009a..ea720f2 100644
--- a/source/opt/local_access_chain_convert_pass.h
+++ b/source/opt/local_access_chain_convert_pass.h
@@ -37,13 +37,13 @@
  public:
   LocalAccessChainConvertPass();
   const char* name() const override { return "convert-local-access-chains"; }
-  Status Process(ir::IRContext* c) override;
+  Status Process(opt::IRContext* c) override;
 
-  ir::IRContext::Analysis GetPreservedAnalyses() override {
-    return ir::IRContext::kAnalysisDefUse;
+  opt::IRContext::Analysis GetPreservedAnalyses() override {
+    return opt::IRContext::kAnalysisDefUse;
   }
 
-  using ProcessFunction = std::function<bool(ir::Function*)>;
+  using ProcessFunction = std::function<bool(opt::Function*)>;
 
  private:
   // Return true if all refs through |ptrId| are only loads or stores and
@@ -55,42 +55,42 @@
   // Search |func| and cache function scope variables of target type that are
   // not accessed with non-constant-index access chains. Also cache non-target
   // variables.
-  void FindTargetVars(ir::Function* func);
+  void FindTargetVars(opt::Function* func);
 
   // Build instruction from |opcode|, |typeId|, |resultId|, and |in_opnds|.
   // Append to |newInsts|.
   void BuildAndAppendInst(
       SpvOp opcode, uint32_t typeId, uint32_t resultId,
-      const std::vector<ir::Operand>& in_opnds,
-      std::vector<std::unique_ptr<ir::Instruction>>* newInsts);
+      const std::vector<opt::Operand>& in_opnds,
+      std::vector<std::unique_ptr<opt::Instruction>>* newInsts);
 
   // Build load of variable in |ptrInst| and append to |newInsts|.
   // Return var in |varId| and its pointee type in |varPteTypeId|.
   uint32_t BuildAndAppendVarLoad(
-      const ir::Instruction* ptrInst, uint32_t* varId, uint32_t* varPteTypeId,
-      std::vector<std::unique_ptr<ir::Instruction>>* newInsts);
+      const opt::Instruction* ptrInst, uint32_t* varId, uint32_t* varPteTypeId,
+      std::vector<std::unique_ptr<opt::Instruction>>* newInsts);
 
   // Append literal integer operands to |in_opnds| corresponding to constant
   // integer operands from access chain |ptrInst|. Assumes all indices in
   // access chains are OpConstant.
-  void AppendConstantOperands(const ir::Instruction* ptrInst,
-                              std::vector<ir::Operand>* in_opnds);
+  void AppendConstantOperands(const opt::Instruction* ptrInst,
+                              std::vector<opt::Operand>* in_opnds);
 
   // Create a load/insert/store equivalent to a store of
   // |valId| through (constant index) access chaing |ptrInst|.
   // Append to |newInsts|.
   void GenAccessChainStoreReplacement(
-      const ir::Instruction* ptrInst, uint32_t valId,
-      std::vector<std::unique_ptr<ir::Instruction>>* newInsts);
+      const opt::Instruction* ptrInst, uint32_t valId,
+      std::vector<std::unique_ptr<opt::Instruction>>* newInsts);
 
   // For the (constant index) access chain |ptrInst|, create an
   // equivalent load and extract. Append to |newInsts|.
   uint32_t GenAccessChainLoadReplacement(
-      const ir::Instruction* ptrInst,
-      std::vector<std::unique_ptr<ir::Instruction>>* newInsts);
+      const opt::Instruction* ptrInst,
+      std::vector<std::unique_ptr<opt::Instruction>>* newInsts);
 
   // Return true if all indices of access chain |acp| are OpConstant integers
-  bool IsConstantIndexAccessChain(const ir::Instruction* acp) const;
+  bool IsConstantIndexAccessChain(const opt::Instruction* acp) const;
 
   // Identify all function scope variables of target type which are
   // accessed only with loads, stores and access chains with constant
@@ -101,7 +101,7 @@
   //
   // Nested access chains and pointer access chains are not currently
   // converted.
-  bool ConvertLocalAccessChains(ir::Function* func);
+  bool ConvertLocalAccessChains(opt::Function* func);
 
   // Initialize extensions whitelist
   void InitExtensions();
@@ -109,7 +109,7 @@
   // Return true if all extensions in this module are allowed by this pass.
   bool AllExtensionsSupported() const;
 
-  void Initialize(ir::IRContext* c);
+  void Initialize(opt::IRContext* c);
   Pass::Status ProcessImpl();
 
   // Variables with only supported references, ie. loads and stores using
diff --git a/source/opt/local_redundancy_elimination.cpp b/source/opt/local_redundancy_elimination.cpp
index d6fb48c..4af76a9 100644
--- a/source/opt/local_redundancy_elimination.cpp
+++ b/source/opt/local_redundancy_elimination.cpp
@@ -19,7 +19,7 @@
 namespace spvtools {
 namespace opt {
 
-Pass::Status LocalRedundancyEliminationPass::Process(ir::IRContext* c) {
+Pass::Status LocalRedundancyEliminationPass::Process(opt::IRContext* c) {
   InitializeProcessing(c);
 
   bool modified = false;
@@ -39,11 +39,12 @@
 }
 
 bool LocalRedundancyEliminationPass::EliminateRedundanciesInBB(
-    ir::BasicBlock* block, const ValueNumberTable& vnTable,
+    opt::BasicBlock* block, const ValueNumberTable& vnTable,
     std::map<uint32_t, uint32_t>* value_to_ids) {
   bool modified = false;
 
-  auto func = [this, &vnTable, &modified, value_to_ids](ir::Instruction* inst) {
+  auto func = [this, &vnTable, &modified,
+               value_to_ids](opt::Instruction* inst) {
     if (inst->result_id() == 0) {
       return;
     }
diff --git a/source/opt/local_redundancy_elimination.h b/source/opt/local_redundancy_elimination.h
index cc83b60..e7b42a7 100644
--- a/source/opt/local_redundancy_elimination.h
+++ b/source/opt/local_redundancy_elimination.h
@@ -32,14 +32,14 @@
 class LocalRedundancyEliminationPass : public Pass {
  public:
   const char* name() const override { return "local-redundancy-elimination"; }
-  Status Process(ir::IRContext*) override;
-  virtual ir::IRContext::Analysis GetPreservedAnalyses() override {
-    return ir::IRContext::kAnalysisDefUse |
-           ir::IRContext::kAnalysisInstrToBlockMapping |
-           ir::IRContext::kAnalysisDecorations |
-           ir::IRContext::kAnalysisCombinators | ir::IRContext::kAnalysisCFG |
-           ir::IRContext::kAnalysisDominatorAnalysis |
-           ir::IRContext::kAnalysisNameMap;
+  Status Process(opt::IRContext*) override;
+  virtual opt::IRContext::Analysis GetPreservedAnalyses() override {
+    return opt::IRContext::kAnalysisDefUse |
+           opt::IRContext::kAnalysisInstrToBlockMapping |
+           opt::IRContext::kAnalysisDecorations |
+           opt::IRContext::kAnalysisCombinators | opt::IRContext::kAnalysisCFG |
+           opt::IRContext::kAnalysisDominatorAnalysis |
+           opt::IRContext::kAnalysisNameMap;
   }
 
  protected:
@@ -54,7 +54,7 @@
   // dominates |bb|.
   //
   // Returns true if the module is changed.
-  bool EliminateRedundanciesInBB(ir::BasicBlock* block,
+  bool EliminateRedundanciesInBB(opt::BasicBlock* block,
                                  const ValueNumberTable& vnTable,
                                  std::map<uint32_t, uint32_t>* value_to_ids);
 };
diff --git a/source/opt/local_single_block_elim_pass.cpp b/source/opt/local_single_block_elim_pass.cpp
index 72e4275..7380c06 100644
--- a/source/opt/local_single_block_elim_pass.cpp
+++ b/source/opt/local_single_block_elim_pass.cpp
@@ -29,7 +29,7 @@
 
 bool LocalSingleBlockLoadStoreElimPass::HasOnlySupportedRefs(uint32_t ptrId) {
   if (supported_ref_ptrs_.find(ptrId) != supported_ref_ptrs_.end()) return true;
-  if (get_def_use_mgr()->WhileEachUser(ptrId, [this](ir::Instruction* user) {
+  if (get_def_use_mgr()->WhileEachUser(ptrId, [this](opt::Instruction* user) {
         SpvOp op = user->opcode();
         if (IsNonPtrAccessChain(op) || op == SpvOpCopyObject) {
           if (!HasOnlySupportedRefs(user->result_id())) {
@@ -48,12 +48,12 @@
 }
 
 bool LocalSingleBlockLoadStoreElimPass::LocalSingleBlockLoadStoreElim(
-    ir::Function* func) {
+    opt::Function* func) {
   // Perform local store/load, load/load and store/store elimination
   // on each block
   bool modified = false;
-  std::vector<ir::Instruction*> instructions_to_kill;
-  std::unordered_set<ir::Instruction*> instructions_to_save;
+  std::vector<opt::Instruction*> instructions_to_kill;
+  std::unordered_set<opt::Instruction*> instructions_to_save;
   for (auto bi = func->begin(); bi != func->end(); ++bi) {
     var2store_.clear();
     var2load_.clear();
@@ -64,7 +64,7 @@
         case SpvOpStore: {
           // Verify store variable is target type
           uint32_t varId;
-          ir::Instruction* ptrInst = GetPtr(&*ii, &varId);
+          opt::Instruction* ptrInst = GetPtr(&*ii, &varId);
           if (!IsTargetVar(varId)) continue;
           if (!HasOnlySupportedRefs(varId)) continue;
           // If a store to the whole variable, remember it for succeeding
@@ -106,7 +106,7 @@
         case SpvOpLoad: {
           // Verify store variable is target type
           uint32_t varId;
-          ir::Instruction* ptrInst = GetPtr(&*ii, &varId);
+          opt::Instruction* ptrInst = GetPtr(&*ii, &varId);
           if (!IsTargetVar(varId)) continue;
           if (!HasOnlySupportedRefs(varId)) continue;
           uint32_t replId = 0;
@@ -151,14 +151,14 @@
     }
   }
 
-  for (ir::Instruction* inst : instructions_to_kill) {
+  for (opt::Instruction* inst : instructions_to_kill) {
     context()->KillInst(inst);
   }
 
   return modified;
 }
 
-void LocalSingleBlockLoadStoreElimPass::Initialize(ir::IRContext* c) {
+void LocalSingleBlockLoadStoreElimPass::Initialize(opt::IRContext* c) {
   InitializeProcessing(c);
 
   // Initialize Target Type Caches
@@ -196,7 +196,7 @@
   // return unmodified.
   if (!AllExtensionsSupported()) return Status::SuccessWithoutChange;
   // Process all entry point functions
-  ProcessFunction pfn = [this](ir::Function* fp) {
+  ProcessFunction pfn = [this](opt::Function* fp) {
     return LocalSingleBlockLoadStoreElim(fp);
   };
 
@@ -206,7 +206,7 @@
 
 LocalSingleBlockLoadStoreElimPass::LocalSingleBlockLoadStoreElimPass() {}
 
-Pass::Status LocalSingleBlockLoadStoreElimPass::Process(ir::IRContext* c) {
+Pass::Status LocalSingleBlockLoadStoreElimPass::Process(opt::IRContext* c) {
   Initialize(c);
   return ProcessImpl();
 }
diff --git a/source/opt/local_single_block_elim_pass.h b/source/opt/local_single_block_elim_pass.h
index 5179cbc..b939042 100644
--- a/source/opt/local_single_block_elim_pass.h
+++ b/source/opt/local_single_block_elim_pass.h
@@ -37,11 +37,11 @@
  public:
   LocalSingleBlockLoadStoreElimPass();
   const char* name() const override { return "eliminate-local-single-block"; }
-  Status Process(ir::IRContext* c) override;
+  Status Process(opt::IRContext* c) override;
 
-  ir::IRContext::Analysis GetPreservedAnalyses() override {
-    return ir::IRContext::kAnalysisDefUse |
-           ir::IRContext::kAnalysisInstrToBlockMapping;
+  opt::IRContext::Analysis GetPreservedAnalyses() override {
+    return opt::IRContext::kAnalysisDefUse |
+           opt::IRContext::kAnalysisInstrToBlockMapping;
   }
 
  private:
@@ -58,7 +58,7 @@
   // load id with previous id and delete load. Finally, check if
   // remaining stores are useless, and delete store and variable
   // where possible. Assumes logical addressing.
-  bool LocalSingleBlockLoadStoreElim(ir::Function* func);
+  bool LocalSingleBlockLoadStoreElim(opt::Function* func);
 
   // Initialize extensions whitelist
   void InitExtensions();
@@ -66,7 +66,7 @@
   // Return true if all extensions in this module are supported by this pass.
   bool AllExtensionsSupported() const;
 
-  void Initialize(ir::IRContext* c);
+  void Initialize(opt::IRContext* c);
   Pass::Status ProcessImpl();
 
   // Map from function scope variable to a store of that variable in the
@@ -74,14 +74,14 @@
   // at the start of each block and incrementally updated as the block
   // is scanned. The stores are candidates for elimination. The map is
   // conservatively cleared when a function call is encountered.
-  std::unordered_map<uint32_t, ir::Instruction*> var2store_;
+  std::unordered_map<uint32_t, opt::Instruction*> var2store_;
 
   // Map from function scope variable to a load of that variable in the
   // current block whose value is currently valid. This map is cleared
   // at the start of each block and incrementally updated as the block
   // is scanned. The stores are candidates for elimination. The map is
   // conservatively cleared when a function call is encountered.
-  std::unordered_map<uint32_t, ir::Instruction*> var2load_;
+  std::unordered_map<uint32_t, opt::Instruction*> var2load_;
 
   // Set of variables whose most recent store in the current block cannot be
   // deleted, for example, if there is a load of the variable which is
diff --git a/source/opt/local_single_store_elim_pass.cpp b/source/opt/local_single_store_elim_pass.cpp
index 92d6a52..893ce08 100644
--- a/source/opt/local_single_store_elim_pass.cpp
+++ b/source/opt/local_single_store_elim_pass.cpp
@@ -30,12 +30,12 @@
 
 }  // anonymous namespace
 
-bool LocalSingleStoreElimPass::LocalSingleStoreElim(ir::Function* func) {
+bool LocalSingleStoreElimPass::LocalSingleStoreElim(opt::Function* func) {
   bool modified = false;
 
   // Check all function scope variables in |func|.
-  ir::BasicBlock* entry_block = &*func->begin();
-  for (ir::Instruction& inst : *entry_block) {
+  opt::BasicBlock* entry_block = &*func->begin();
+  for (opt::Instruction& inst : *entry_block) {
     if (inst.opcode() != SpvOpVariable) {
       break;
     }
@@ -45,7 +45,7 @@
   return modified;
 }
 
-void LocalSingleStoreElimPass::Initialize(ir::IRContext* irContext) {
+void LocalSingleStoreElimPass::Initialize(opt::IRContext* irContext) {
   InitializeProcessing(irContext);
   InitExtensionWhiteList();
 }
@@ -69,7 +69,7 @@
   // Do not process if any disallowed extensions are enabled
   if (!AllExtensionsSupported()) return Status::SuccessWithoutChange;
   // Process all entry point functions
-  ProcessFunction pfn = [this](ir::Function* fp) {
+  ProcessFunction pfn = [this](opt::Function* fp) {
     return LocalSingleStoreElim(fp);
   };
   bool modified = ProcessEntryPointCallTree(pfn, get_module());
@@ -78,7 +78,7 @@
 
 LocalSingleStoreElimPass::LocalSingleStoreElimPass() {}
 
-Pass::Status LocalSingleStoreElimPass::Process(ir::IRContext* irContext) {
+Pass::Status LocalSingleStoreElimPass::Process(opt::IRContext* irContext) {
   Initialize(irContext);
   return ProcessImpl();
 }
@@ -120,11 +120,11 @@
       "SPV_EXT_descriptor_indexing",
   });
 }
-bool LocalSingleStoreElimPass::ProcessVariable(ir::Instruction* var_inst) {
-  vector<ir::Instruction*> users;
+bool LocalSingleStoreElimPass::ProcessVariable(opt::Instruction* var_inst) {
+  vector<opt::Instruction*> users;
   FindUses(var_inst, &users);
 
-  ir::Instruction* store_inst = FindSingleStoreAndCheckUses(var_inst, users);
+  opt::Instruction* store_inst = FindSingleStoreAndCheckUses(var_inst, users);
 
   if (store_inst == nullptr) {
     return false;
@@ -133,17 +133,17 @@
   return RewriteLoads(store_inst, users);
 }
 
-ir::Instruction* LocalSingleStoreElimPass::FindSingleStoreAndCheckUses(
-    ir::Instruction* var_inst, const vector<ir::Instruction*>& users) const {
+opt::Instruction* LocalSingleStoreElimPass::FindSingleStoreAndCheckUses(
+    opt::Instruction* var_inst, const vector<opt::Instruction*>& users) const {
   // Make sure there is exactly 1 store.
-  ir::Instruction* store_inst = nullptr;
+  opt::Instruction* store_inst = nullptr;
 
   // If |var_inst| has an initializer, then that will count as a store.
   if (var_inst->NumInOperands() > 1) {
     store_inst = var_inst;
   }
 
-  for (ir::Instruction* user : users) {
+  for (opt::Instruction* user : users) {
     switch (user->opcode()) {
       case SpvOpStore:
         // Since we are in the relaxed addressing mode, the use has to be the
@@ -182,10 +182,10 @@
 }
 
 void LocalSingleStoreElimPass::FindUses(
-    const ir::Instruction* var_inst,
-    std::vector<ir::Instruction*>* users) const {
+    const opt::Instruction* var_inst,
+    std::vector<opt::Instruction*>* users) const {
   analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr();
-  def_use_mgr->ForEachUser(var_inst, [users, this](ir::Instruction* user) {
+  def_use_mgr->ForEachUser(var_inst, [users, this](opt::Instruction* user) {
     users->push_back(user);
     if (user->opcode() == SpvOpCopyObject) {
       FindUses(user, users);
@@ -193,9 +193,9 @@
   });
 }
 
-bool LocalSingleStoreElimPass::FeedsAStore(ir::Instruction* inst) const {
+bool LocalSingleStoreElimPass::FeedsAStore(opt::Instruction* inst) const {
   analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr();
-  return !def_use_mgr->WhileEachUser(inst, [this](ir::Instruction* user) {
+  return !def_use_mgr->WhileEachUser(inst, [this](opt::Instruction* user) {
     switch (user->opcode()) {
       case SpvOpStore:
         return false;
@@ -216,8 +216,8 @@
 }
 
 bool LocalSingleStoreElimPass::RewriteLoads(
-    ir::Instruction* store_inst, const std::vector<ir::Instruction*>& uses) {
-  ir::BasicBlock* store_block = context()->get_instr_block(store_inst);
+    opt::Instruction* store_inst, const std::vector<opt::Instruction*>& uses) {
+  opt::BasicBlock* store_block = context()->get_instr_block(store_inst);
   opt::DominatorAnalysis* dominator_analysis =
       context()->GetDominatorAnalysis(store_block->GetParent());
 
@@ -227,9 +227,9 @@
   else
     stored_id = store_inst->GetSingleWordInOperand(kVariableInitIdInIdx);
 
-  std::vector<ir::Instruction*> uses_in_store_block;
+  std::vector<opt::Instruction*> uses_in_store_block;
   bool modified = false;
-  for (ir::Instruction* use : uses) {
+  for (opt::Instruction* use : uses) {
     if (use->opcode() == SpvOpLoad) {
       if (dominator_analysis->Dominates(store_inst, use)) {
         modified = true;
diff --git a/source/opt/local_single_store_elim_pass.h b/source/opt/local_single_store_elim_pass.h
index 6f23b98..8f8e0bf 100644
--- a/source/opt/local_single_store_elim_pass.h
+++ b/source/opt/local_single_store_elim_pass.h
@@ -34,16 +34,16 @@
 
 // See optimizer.hpp for documentation.
 class LocalSingleStoreElimPass : public Pass {
-  using cbb_ptr = const ir::BasicBlock*;
+  using cbb_ptr = const opt::BasicBlock*;
 
  public:
   LocalSingleStoreElimPass();
   const char* name() const override { return "eliminate-local-single-store"; }
-  Status Process(ir::IRContext* irContext) override;
+  Status Process(opt::IRContext* irContext) override;
 
-  ir::IRContext::Analysis GetPreservedAnalyses() override {
-    return ir::IRContext::kAnalysisDefUse |
-           ir::IRContext::kAnalysisInstrToBlockMapping;
+  opt::IRContext::Analysis GetPreservedAnalyses() override {
+    return opt::IRContext::kAnalysisDefUse |
+           opt::IRContext::kAnalysisInstrToBlockMapping;
   }
 
  private:
@@ -51,7 +51,7 @@
   // with a single non-access-chain store in |func|. Replace all their
   // non-access-chain loads with the value that is stored and eliminate
   // any resulting dead code.
-  bool LocalSingleStoreElim(ir::Function* func);
+  bool LocalSingleStoreElim(opt::Function* func);
 
   // Initialize extensions whitelist
   void InitExtensionWhiteList();
@@ -59,37 +59,37 @@
   // Return true if all extensions in this module are allowed by this pass.
   bool AllExtensionsSupported() const;
 
-  void Initialize(ir::IRContext* irContext);
+  void Initialize(opt::IRContext* irContext);
   Pass::Status ProcessImpl();
 
   // If there is a single store to |var_inst|, and it covers the entire
   // variable, then replace all of the loads of the entire variable that are
   // dominated by the store by the value that was stored.  Returns true if the
   // module was changed.
-  bool ProcessVariable(ir::Instruction* var_inst);
+  bool ProcessVariable(opt::Instruction* var_inst);
 
   // Collects all of the uses of |var_inst| into |uses|.  This looks through
   // OpObjectCopy's that copy the address of the variable, and collects those
   // uses as well.
-  void FindUses(const ir::Instruction* var_inst,
-                std::vector<ir::Instruction*>* uses) const;
+  void FindUses(const opt::Instruction* var_inst,
+                std::vector<opt::Instruction*>* uses) const;
 
   // Returns a store to |var_inst| if
   //   - it is a store to the entire variable,
   //   - and there are no other instructions that may modify |var_inst|.
-  ir::Instruction* FindSingleStoreAndCheckUses(
-      ir::Instruction* var_inst,
-      const std::vector<ir::Instruction*>& users) const;
+  opt::Instruction* FindSingleStoreAndCheckUses(
+      opt::Instruction* var_inst,
+      const std::vector<opt::Instruction*>& users) const;
 
   // Returns true if the address that results from |inst| may be used as a base
   // address in a store instruction or may be used to compute the base address
   // of a store instruction.
-  bool FeedsAStore(ir::Instruction* inst) const;
+  bool FeedsAStore(opt::Instruction* inst) const;
 
   // Replaces all of the loads in |uses| by the value stored in |store_inst|.
   // The load instructions are then killed.
-  bool RewriteLoads(ir::Instruction* store_inst,
-                    const std::vector<ir::Instruction*>& uses);
+  bool RewriteLoads(opt::Instruction* store_inst,
+                    const std::vector<opt::Instruction*>& uses);
 
   // Extensions supported by this pass.
   std::unordered_set<std::string> extensions_whitelist_;
diff --git a/source/opt/local_ssa_elim_pass.cpp b/source/opt/local_ssa_elim_pass.cpp
index 14c14bd..1f903b5 100644
--- a/source/opt/local_ssa_elim_pass.cpp
+++ b/source/opt/local_ssa_elim_pass.cpp
@@ -23,7 +23,7 @@
 namespace spvtools {
 namespace opt {
 
-void LocalMultiStoreElimPass::Initialize(ir::IRContext* c) {
+void LocalMultiStoreElimPass::Initialize(opt::IRContext* c) {
   InitializeProcessing(c);
 
   // Initialize extension whitelist
@@ -54,7 +54,7 @@
   // Do not process if any disallowed extensions are enabled
   if (!AllExtensionsSupported()) return Status::SuccessWithoutChange;
   // Process functions
-  ProcessFunction pfn = [this](ir::Function* fp) {
+  ProcessFunction pfn = [this](opt::Function* fp) {
     return SSARewriter(this).RewriteFunctionIntoSSA(fp);
   };
   bool modified = ProcessEntryPointCallTree(pfn, get_module());
@@ -63,7 +63,7 @@
 
 LocalMultiStoreElimPass::LocalMultiStoreElimPass() {}
 
-Pass::Status LocalMultiStoreElimPass::Process(ir::IRContext* c) {
+Pass::Status LocalMultiStoreElimPass::Process(opt::IRContext* c) {
   Initialize(c);
   return ProcessImpl();
 }
diff --git a/source/opt/local_ssa_elim_pass.h b/source/opt/local_ssa_elim_pass.h
index c3f70f6..195aa0a 100644
--- a/source/opt/local_ssa_elim_pass.h
+++ b/source/opt/local_ssa_elim_pass.h
@@ -34,19 +34,19 @@
 
 // See optimizer.hpp for documentation.
 class LocalMultiStoreElimPass : public MemPass {
-  using cbb_ptr = const ir::BasicBlock*;
+  using cbb_ptr = const opt::BasicBlock*;
 
  public:
   using GetBlocksFunction =
-      std::function<std::vector<ir::BasicBlock*>*(const ir::BasicBlock*)>;
+      std::function<std::vector<opt::BasicBlock*>*(const opt::BasicBlock*)>;
 
   LocalMultiStoreElimPass();
   const char* name() const override { return "eliminate-local-multi-store"; }
-  Status Process(ir::IRContext* c) override;
+  Status Process(opt::IRContext* c) override;
 
-  ir::IRContext::Analysis GetPreservedAnalyses() override {
-    return ir::IRContext::kAnalysisDefUse |
-           ir::IRContext::kAnalysisInstrToBlockMapping;
+  opt::IRContext::Analysis GetPreservedAnalyses() override {
+    return opt::IRContext::kAnalysisDefUse |
+           opt::IRContext::kAnalysisInstrToBlockMapping;
   }
 
  private:
@@ -56,7 +56,7 @@
   // Return true if all extensions in this module are allowed by this pass.
   bool AllExtensionsSupported() const;
 
-  void Initialize(ir::IRContext* c);
+  void Initialize(opt::IRContext* c);
   Pass::Status ProcessImpl();
 
   // Extensions supported by this pass.
diff --git a/source/opt/loop_dependence.cpp b/source/opt/loop_dependence.cpp
index 3f67d63..0b1b2d2 100644
--- a/source/opt/loop_dependence.cpp
+++ b/source/opt/loop_dependence.cpp
@@ -181,15 +181,15 @@
 
 }  // namespace
 
-bool LoopDependenceAnalysis::GetDependence(const ir::Instruction* source,
-                                           const ir::Instruction* destination,
+bool LoopDependenceAnalysis::GetDependence(const opt::Instruction* source,
+                                           const opt::Instruction* destination,
                                            DistanceVector* distance_vector) {
   // Start off by finding and marking all the loops in |loops_| that are
   // irrelevant to the dependence analysis.
   MarkUnsusedDistanceEntriesAsIrrelevant(source, destination, distance_vector);
 
-  ir::Instruction* source_access_chain = GetOperandDefinition(source, 0);
-  ir::Instruction* destination_access_chain =
+  opt::Instruction* source_access_chain = GetOperandDefinition(source, 0);
+  opt::Instruction* destination_access_chain =
       GetOperandDefinition(destination, 0);
 
   auto num_access_chains =
@@ -234,8 +234,8 @@
 
   // If the access chains aren't collecting from the same structure there is no
   // dependence.
-  ir::Instruction* source_array = GetOperandDefinition(source_access_chain, 0);
-  ir::Instruction* destination_array =
+  opt::Instruction* source_array = GetOperandDefinition(source_access_chain, 0);
+  opt::Instruction* destination_array =
       GetOperandDefinition(destination_access_chain, 0);
 
   // Nested access chains are not supported yet, bail out.
@@ -254,8 +254,8 @@
 
   // To handle multiple subscripts we must get every operand in the access
   // chains past the first.
-  std::vector<ir::Instruction*> source_subscripts = GetSubscripts(source);
-  std::vector<ir::Instruction*> destination_subscripts =
+  std::vector<opt::Instruction*> source_subscripts = GetSubscripts(source);
+  std::vector<opt::Instruction*> destination_subscripts =
       GetSubscripts(destination);
 
   auto sets_of_subscripts =
@@ -263,7 +263,7 @@
 
   auto first_coupled = std::partition(
       std::begin(sets_of_subscripts), std::end(sets_of_subscripts),
-      [](const std::set<std::pair<ir::Instruction*, ir::Instruction*>>& set) {
+      [](const std::set<std::pair<opt::Instruction*, opt::Instruction*>>& set) {
         return set.size() == 1;
       });
 
@@ -284,7 +284,7 @@
     // Check the loops are in a form we support.
     auto subscript_pair = std::make_pair(source_node, destination_node);
 
-    const ir::Loop* loop = GetLoopForSubscriptPair(subscript_pair);
+    const opt::Loop* loop = GetLoopForSubscriptPair(subscript_pair);
     if (loop) {
       if (!IsSupportedLoop(loop)) {
         PrintDebug(
@@ -371,9 +371,9 @@
     for (const auto& subscript : coupled_subscripts) {
       auto loops = CollectLoops(std::get<0>(subscript), std::get<1>(subscript));
 
-      auto is_subscript_supported =
-          std::all_of(std::begin(loops), std::end(loops),
-                      [this](const ir::Loop* l) { return IsSupportedLoop(l); });
+      auto is_subscript_supported = std::all_of(
+          std::begin(loops), std::end(loops),
+          [this](const opt::Loop* l) { return IsSupportedLoop(l); });
 
       supported = supported && is_subscript_supported;
     }
@@ -541,7 +541,7 @@
   // Build an SENode for distance.
   std::pair<SENode*, SENode*> subscript_pair =
       std::make_pair(source, destination);
-  const ir::Loop* subscript_loop = GetLoopForSubscriptPair(subscript_pair);
+  const opt::Loop* subscript_loop = GetLoopForSubscriptPair(subscript_pair);
   SENode* source_constant_term =
       GetConstantTerm(subscript_loop, source->AsSERecurrentNode());
   SENode* destination_constant_term =
@@ -676,7 +676,7 @@
   // outwith the bounds.
   std::pair<SENode*, SENode*> subscript_pair =
       std::make_pair(source, destination);
-  const ir::Loop* subscript_loop = GetLoopForSubscriptPair(subscript_pair);
+  const opt::Loop* subscript_loop = GetLoopForSubscriptPair(subscript_pair);
   if (IsProvablyOutsideOfLoopBounds(subscript_loop, source_destination_delta,
                                     coefficient)) {
     PrintDebug(
@@ -701,7 +701,7 @@
   PrintDebug("Performing WeakZeroSourceSIVTest.");
   std::pair<SENode*, SENode*> subscript_pair =
       std::make_pair(source, destination);
-  const ir::Loop* subscript_loop = GetLoopForSubscriptPair(subscript_pair);
+  const opt::Loop* subscript_loop = GetLoopForSubscriptPair(subscript_pair);
   // Build an SENode for distance.
   SENode* destination_constant_term =
       GetConstantTerm(subscript_loop, destination);
@@ -855,7 +855,7 @@
   // Build an SENode for distance.
   std::pair<SENode*, SENode*> subscript_pair =
       std::make_pair(source, destination);
-  const ir::Loop* subscript_loop = GetLoopForSubscriptPair(subscript_pair);
+  const opt::Loop* subscript_loop = GetLoopForSubscriptPair(subscript_pair);
   SENode* source_constant_term = GetConstantTerm(subscript_loop, source);
   SENode* delta = scalar_evolution_.SimplifyExpression(
       scalar_evolution_.CreateSubtraction(destination, source_constant_term));
@@ -1115,10 +1115,10 @@
 }
 
 using PartitionedSubscripts =
-    std::vector<std::set<std::pair<ir::Instruction*, ir::Instruction*>>>;
+    std::vector<std::set<std::pair<opt::Instruction*, opt::Instruction*>>>;
 PartitionedSubscripts LoopDependenceAnalysis::PartitionSubscripts(
-    const std::vector<ir::Instruction*>& source_subscripts,
-    const std::vector<ir::Instruction*>& destination_subscripts) {
+    const std::vector<opt::Instruction*>& source_subscripts,
+    const std::vector<opt::Instruction*>& destination_subscripts) {
   PartitionedSubscripts partitions{};
 
   auto num_subscripts = source_subscripts.size();
@@ -1139,7 +1139,7 @@
       auto it = std::find_if(
           current_partition.begin(), current_partition.end(),
           [loop,
-           this](const std::pair<ir::Instruction*, ir::Instruction*>& elem)
+           this](const std::pair<opt::Instruction*, opt::Instruction*>& elem)
               -> bool {
             auto source_recurrences =
                 scalar_evolution_.AnalyzeInstruction(std::get<0>(elem))
@@ -1177,7 +1177,7 @@
   partitions.erase(
       std::remove_if(
           partitions.begin(), partitions.end(),
-          [](const std::set<std::pair<ir::Instruction*, ir::Instruction*>>&
+          [](const std::set<std::pair<opt::Instruction*, opt::Instruction*>>&
                  partition) { return partition.empty(); }),
       partitions.end());
 
diff --git a/source/opt/loop_dependence.h b/source/opt/loop_dependence.h
index 9537ff8..b0aed6f 100644
--- a/source/opt/loop_dependence.h
+++ b/source/opt/loop_dependence.h
@@ -167,7 +167,7 @@
 
 class Constraint {
  public:
-  explicit Constraint(const ir::Loop* loop) : loop_(loop) {}
+  explicit Constraint(const opt::Loop* loop) : loop_(loop) {}
   enum ConstraintType { Line, Distance, Point, None, Empty };
 
   virtual ConstraintType GetType() const = 0;
@@ -175,7 +175,7 @@
   virtual ~Constraint() {}
 
   // Get the loop this constraint belongs to.
-  const ir::Loop* GetLoop() const { return loop_; }
+  const opt::Loop* GetLoop() const { return loop_; }
 
   bool operator==(const Constraint& other) const;
 
@@ -192,12 +192,12 @@
 #undef DeclareCastMethod
 
  protected:
-  const ir::Loop* loop_;
+  const opt::Loop* loop_;
 };
 
 class DependenceLine : public Constraint {
  public:
-  DependenceLine(SENode* a, SENode* b, SENode* c, const ir::Loop* loop)
+  DependenceLine(SENode* a, SENode* b, SENode* c, const opt::Loop* loop)
       : Constraint(loop), a_(a), b_(b), c_(c) {}
 
   ConstraintType GetType() const final { return Line; }
@@ -217,7 +217,7 @@
 
 class DependenceDistance : public Constraint {
  public:
-  DependenceDistance(SENode* distance, const ir::Loop* loop)
+  DependenceDistance(SENode* distance, const opt::Loop* loop)
       : Constraint(loop), distance_(distance) {}
 
   ConstraintType GetType() const final { return Distance; }
@@ -233,7 +233,7 @@
 
 class DependencePoint : public Constraint {
  public:
-  DependencePoint(SENode* source, SENode* destination, const ir::Loop* loop)
+  DependencePoint(SENode* source, SENode* destination, const opt::Loop* loop)
       : Constraint(loop), source_(source), destination_(destination) {}
 
   ConstraintType GetType() const final { return Point; }
@@ -294,8 +294,8 @@
 // is present in the pair.
 class LoopDependenceAnalysis {
  public:
-  LoopDependenceAnalysis(ir::IRContext* context,
-                         std::vector<const ir::Loop*> loops)
+  LoopDependenceAnalysis(opt::IRContext* context,
+                         std::vector<const opt::Loop*> loops)
       : context_(context),
         loops_(loops),
         scalar_evolution_(context),
@@ -308,8 +308,8 @@
   // Any direction and distance information found will be stored in
   // |distance_vector|.
   // Returns true if independence is found, false otherwise.
-  bool GetDependence(const ir::Instruction* source,
-                     const ir::Instruction* destination,
+  bool GetDependence(const opt::Instruction* source,
+                     const opt::Instruction* destination,
                      DistanceVector* distance_vector);
 
   // Returns true if |subscript_pair| represents a Zero Index Variable pair
@@ -326,11 +326,11 @@
 
   // Finds the lower bound of |loop| as an SENode* and returns the result.
   // The lower bound is the starting value of the loops induction variable
-  SENode* GetLowerBound(const ir::Loop* loop);
+  SENode* GetLowerBound(const opt::Loop* loop);
 
   // Finds the upper bound of |loop| as an SENode* and returns the result.
   // The upper bound is the last value before the loop exit condition is met.
-  SENode* GetUpperBound(const ir::Loop* loop);
+  SENode* GetUpperBound(const opt::Loop* loop);
 
   // Returns true if |value| is between |bound_one| and |bound_two| (inclusive).
   bool IsWithinBounds(int64_t value, int64_t bound_one, int64_t bound_two);
@@ -338,32 +338,32 @@
   // Finds the bounds of |loop| as upper_bound - lower_bound and returns the
   // resulting SENode.
   // If the operations can not be completed a nullptr is returned.
-  SENode* GetTripCount(const ir::Loop* loop);
+  SENode* GetTripCount(const opt::Loop* loop);
 
   // Returns the SENode* produced by building an SENode from the result of
   // calling GetInductionInitValue on |loop|.
   // If the operation can not be completed a nullptr is returned.
-  SENode* GetFirstTripInductionNode(const ir::Loop* loop);
+  SENode* GetFirstTripInductionNode(const opt::Loop* loop);
 
   // Returns the SENode* produced by building an SENode from the result of
   // GetFirstTripInductionNode + (GetTripCount - 1) * induction_coefficient.
   // If the operation can not be completed a nullptr is returned.
-  SENode* GetFinalTripInductionNode(const ir::Loop* loop,
+  SENode* GetFinalTripInductionNode(const opt::Loop* loop,
                                     SENode* induction_coefficient);
 
   // Returns all the distinct loops that appear in |nodes|.
-  std::set<const ir::Loop*> CollectLoops(
+  std::set<const opt::Loop*> CollectLoops(
       const std::vector<SERecurrentNode*>& nodes);
 
   // Returns all the distinct loops that appear in |source| and |destination|.
-  std::set<const ir::Loop*> CollectLoops(SENode* source, SENode* destination);
+  std::set<const opt::Loop*> CollectLoops(SENode* source, SENode* destination);
 
   // Returns true if |distance| is provably outside the loop bounds.
   // |coefficient| must be an SENode representing the coefficient of the
   // induction variable of |loop|.
   // This method is able to handle some symbolic cases which IsWithinBounds
   // can't handle.
-  bool IsProvablyOutsideOfLoopBounds(const ir::Loop* loop, SENode* distance,
+  bool IsProvablyOutsideOfLoopBounds(const opt::Loop* loop, SENode* distance,
                                      SENode* coefficient);
 
   // Sets the ostream for debug information for the analysis.
@@ -393,14 +393,14 @@
   // Returns the partitioning of subscript pairs. Sets of size 1 indicates an
   // independent subscript-pair and others indicate coupled sets.
   using PartitionedSubscripts =
-      std::vector<std::set<std::pair<ir::Instruction*, ir::Instruction*>>>;
+      std::vector<std::set<std::pair<opt::Instruction*, opt::Instruction*>>>;
   PartitionedSubscripts PartitionSubscripts(
-      const std::vector<ir::Instruction*>& source_subscripts,
-      const std::vector<ir::Instruction*>& destination_subscripts);
+      const std::vector<opt::Instruction*>& source_subscripts,
+      const std::vector<opt::Instruction*>& destination_subscripts);
 
-  // Returns the ir::Loop* matching the loop for |subscript_pair|.
+  // Returns the opt::Loop* matching the loop for |subscript_pair|.
   // |subscript_pair| must be an SIV pair.
-  const ir::Loop* GetLoopForSubscriptPair(
+  const opt::Loop* GetLoopForSubscriptPair(
       const std::pair<SENode*, SENode*>& subscript_pair);
 
   // Returns the DistanceEntry matching the loop for |subscript_pair|.
@@ -410,13 +410,13 @@
       DistanceVector* distance_vector);
 
   // Returns the DistanceEntry matching |loop|.
-  DistanceEntry* GetDistanceEntryForLoop(const ir::Loop* loop,
+  DistanceEntry* GetDistanceEntryForLoop(const opt::Loop* loop,
                                          DistanceVector* distance_vector);
 
   // Returns a vector of Instruction* which form the subscripts of the array
   // access defined by the access chain |instruction|.
-  std::vector<ir::Instruction*> GetSubscripts(
-      const ir::Instruction* instruction);
+  std::vector<opt::Instruction*> GetSubscripts(
+      const opt::Instruction* instruction);
 
   // Delta test as described in Figure 3 of 'Practical Dependence
   // Testing' by Gina Goff, Ken Kennedy, and Chau-Wen Tseng from PLDI '91.
@@ -441,18 +441,18 @@
   // analysis.
   // A loop is supported if it has a single induction variable and that
   // induction variable has a step of +1 or -1 per loop iteration.
-  bool CheckSupportedLoops(std::vector<const ir::Loop*> loops);
+  bool CheckSupportedLoops(std::vector<const opt::Loop*> loops);
 
   // Returns true if |loop| is in a form supported by this analysis.
   // A loop is supported if it has a single induction variable and that
   // induction variable has a step of +1 or -1 per loop iteration.
-  bool IsSupportedLoop(const ir::Loop* loop);
+  bool IsSupportedLoop(const opt::Loop* loop);
 
  private:
-  ir::IRContext* context_;
+  opt::IRContext* context_;
 
   // The loop nest we are analysing the dependence of.
-  std::vector<const ir::Loop*> loops_;
+  std::vector<const opt::Loop*> loops_;
 
   // The ScalarEvolutionAnalysis used by this analysis to store and perform much
   // of its logic.
@@ -514,8 +514,8 @@
 
   // Uses the def_use_mgr to get the instruction referenced by
   // SingleWordInOperand(|id|) when called on |instruction|.
-  ir::Instruction* GetOperandDefinition(const ir::Instruction* instruction,
-                                        int id);
+  opt::Instruction* GetOperandDefinition(const opt::Instruction* instruction,
+                                         int id);
 
   // Perform the GCD test if both, the source and the destination nodes, are in
   // the form a0*i0 + a1*i1 + ... an*in + c.
@@ -533,13 +533,13 @@
   // Takes the offset from the induction variable and subtracts the lower bound
   // from it to get the constant term added to the induction.
   // Returns the resuting constant term, or nullptr if it could not be produced.
-  SENode* GetConstantTerm(const ir::Loop* loop, SERecurrentNode* induction);
+  SENode* GetConstantTerm(const opt::Loop* loop, SERecurrentNode* induction);
 
   // Marks all the distance entries in |distance_vector| that were relate to
   // loops in |loops_| but were not used in any subscripts as irrelevant to the
   // to the dependence test.
   void MarkUnsusedDistanceEntriesAsIrrelevant(
-      const ir::Instruction* source, const ir::Instruction* destination,
+      const opt::Instruction* source, const opt::Instruction* destination,
       DistanceVector* distance_vector);
 
   // Converts |value| to a std::string and returns the result.
diff --git a/source/opt/loop_dependence_helpers.cpp b/source/opt/loop_dependence_helpers.cpp
index 5420221..3d00136 100644
--- a/source/opt/loop_dependence_helpers.cpp
+++ b/source/opt/loop_dependence_helpers.cpp
@@ -47,12 +47,12 @@
          1;
 }
 
-SENode* LoopDependenceAnalysis::GetLowerBound(const ir::Loop* loop) {
-  ir::Instruction* cond_inst = loop->GetConditionInst();
+SENode* LoopDependenceAnalysis::GetLowerBound(const opt::Loop* loop) {
+  opt::Instruction* cond_inst = loop->GetConditionInst();
   if (!cond_inst) {
     return nullptr;
   }
-  ir::Instruction* lower_inst = GetOperandDefinition(cond_inst, 0);
+  opt::Instruction* lower_inst = GetOperandDefinition(cond_inst, 0);
   switch (cond_inst->opcode()) {
     case SpvOpULessThan:
     case SpvOpSLessThan:
@@ -79,12 +79,12 @@
   }
 }
 
-SENode* LoopDependenceAnalysis::GetUpperBound(const ir::Loop* loop) {
-  ir::Instruction* cond_inst = loop->GetConditionInst();
+SENode* LoopDependenceAnalysis::GetUpperBound(const opt::Loop* loop) {
+  opt::Instruction* cond_inst = loop->GetConditionInst();
   if (!cond_inst) {
     return nullptr;
   }
-  ir::Instruction* upper_inst = GetOperandDefinition(cond_inst, 1);
+  opt::Instruction* upper_inst = GetOperandDefinition(cond_inst, 1);
   switch (cond_inst->opcode()) {
     case SpvOpULessThan:
     case SpvOpSLessThan: {
@@ -135,7 +135,7 @@
 }
 
 bool LoopDependenceAnalysis::IsProvablyOutsideOfLoopBounds(
-    const ir::Loop* loop, SENode* distance, SENode* coefficient) {
+    const opt::Loop* loop, SENode* distance, SENode* coefficient) {
   // We test to see if we can reduce the coefficient to an integral constant.
   SEConstantNode* coefficient_constant = coefficient->AsSEConstantNode();
   if (!coefficient_constant) {
@@ -196,7 +196,7 @@
   return false;
 }
 
-const ir::Loop* LoopDependenceAnalysis::GetLoopForSubscriptPair(
+const opt::Loop* LoopDependenceAnalysis::GetLoopForSubscriptPair(
     const std::pair<SENode*, SENode*>& subscript_pair) {
   // Collect all the SERecurrentNodes.
   std::vector<SERecurrentNode*> source_nodes =
@@ -205,7 +205,7 @@
       std::get<1>(subscript_pair)->CollectRecurrentNodes();
 
   // Collect all the loops stored by the SERecurrentNodes.
-  std::unordered_set<const ir::Loop*> loops{};
+  std::unordered_set<const opt::Loop*> loops{};
   for (auto source_nodes_it = source_nodes.begin();
        source_nodes_it != source_nodes.end(); ++source_nodes_it) {
     loops.insert((*source_nodes_it)->GetLoop());
@@ -226,7 +226,7 @@
 }
 
 DistanceEntry* LoopDependenceAnalysis::GetDistanceEntryForLoop(
-    const ir::Loop* loop, DistanceVector* distance_vector) {
+    const opt::Loop* loop, DistanceVector* distance_vector) {
   if (!loop) {
     return nullptr;
   }
@@ -245,22 +245,22 @@
 DistanceEntry* LoopDependenceAnalysis::GetDistanceEntryForSubscriptPair(
     const std::pair<SENode*, SENode*>& subscript_pair,
     DistanceVector* distance_vector) {
-  const ir::Loop* loop = GetLoopForSubscriptPair(subscript_pair);
+  const opt::Loop* loop = GetLoopForSubscriptPair(subscript_pair);
 
   return GetDistanceEntryForLoop(loop, distance_vector);
 }
 
-SENode* LoopDependenceAnalysis::GetTripCount(const ir::Loop* loop) {
-  ir::BasicBlock* condition_block = loop->FindConditionBlock();
+SENode* LoopDependenceAnalysis::GetTripCount(const opt::Loop* loop) {
+  opt::BasicBlock* condition_block = loop->FindConditionBlock();
   if (!condition_block) {
     return nullptr;
   }
-  ir::Instruction* induction_instr =
+  opt::Instruction* induction_instr =
       loop->FindConditionVariable(condition_block);
   if (!induction_instr) {
     return nullptr;
   }
-  ir::Instruction* cond_instr = loop->GetConditionInst();
+  opt::Instruction* cond_instr = loop->GetConditionInst();
   if (!cond_instr) {
     return nullptr;
   }
@@ -281,12 +281,12 @@
 }
 
 SENode* LoopDependenceAnalysis::GetFirstTripInductionNode(
-    const ir::Loop* loop) {
-  ir::BasicBlock* condition_block = loop->FindConditionBlock();
+    const opt::Loop* loop) {
+  opt::BasicBlock* condition_block = loop->FindConditionBlock();
   if (!condition_block) {
     return nullptr;
   }
-  ir::Instruction* induction_instr =
+  opt::Instruction* induction_instr =
       loop->FindConditionVariable(condition_block);
   if (!induction_instr) {
     return nullptr;
@@ -302,7 +302,7 @@
 }
 
 SENode* LoopDependenceAnalysis::GetFinalTripInductionNode(
-    const ir::Loop* loop, SENode* induction_coefficient) {
+    const opt::Loop* loop, SENode* induction_coefficient) {
   SENode* first_trip_induction_node = GetFirstTripInductionNode(loop);
   if (!first_trip_induction_node) {
     return nullptr;
@@ -319,12 +319,12 @@
       scalar_evolution_.CreateMultiplyNode(trip_count, induction_coefficient)));
 }
 
-std::set<const ir::Loop*> LoopDependenceAnalysis::CollectLoops(
+std::set<const opt::Loop*> LoopDependenceAnalysis::CollectLoops(
     const std::vector<SERecurrentNode*>& recurrent_nodes) {
   // We don't handle loops with more than one induction variable. Therefore we
   // can identify the number of induction variables by collecting all of the
   // loops the collected recurrent nodes belong to.
-  std::set<const ir::Loop*> loops{};
+  std::set<const opt::Loop*> loops{};
   for (auto recurrent_nodes_it = recurrent_nodes.begin();
        recurrent_nodes_it != recurrent_nodes.end(); ++recurrent_nodes_it) {
     loops.insert((*recurrent_nodes_it)->GetLoop());
@@ -343,23 +343,24 @@
   // We don't handle loops with more than one induction variable. Therefore we
   // can identify the number of induction variables by collecting all of the
   // loops the collected recurrent nodes belong to.
-  std::set<const ir::Loop*> loops = CollectLoops(recurrent_nodes);
+  std::set<const opt::Loop*> loops = CollectLoops(recurrent_nodes);
 
   return static_cast<int64_t>(loops.size());
 }
 
-std::set<const ir::Loop*> LoopDependenceAnalysis::CollectLoops(
+std::set<const opt::Loop*> LoopDependenceAnalysis::CollectLoops(
     SENode* source, SENode* destination) {
   if (!source || !destination) {
-    return std::set<const ir::Loop*>{};
+    return std::set<const opt::Loop*>{};
   }
 
   std::vector<SERecurrentNode*> source_nodes = source->CollectRecurrentNodes();
   std::vector<SERecurrentNode*> destination_nodes =
       destination->CollectRecurrentNodes();
 
-  std::set<const ir::Loop*> loops = CollectLoops(source_nodes);
-  std::set<const ir::Loop*> destination_loops = CollectLoops(destination_nodes);
+  std::set<const opt::Loop*> loops = CollectLoops(source_nodes);
+  std::set<const opt::Loop*> destination_loops =
+      CollectLoops(destination_nodes);
 
   loops.insert(std::begin(destination_loops), std::end(destination_loops));
 
@@ -372,22 +373,22 @@
     return -1;
   }
 
-  std::set<const ir::Loop*> loops = CollectLoops(source, destination);
+  std::set<const opt::Loop*> loops = CollectLoops(source, destination);
 
   return static_cast<int64_t>(loops.size());
 }
 
-ir::Instruction* LoopDependenceAnalysis::GetOperandDefinition(
-    const ir::Instruction* instruction, int id) {
+opt::Instruction* LoopDependenceAnalysis::GetOperandDefinition(
+    const opt::Instruction* instruction, int id) {
   return context_->get_def_use_mgr()->GetDef(
       instruction->GetSingleWordInOperand(id));
 }
 
-std::vector<ir::Instruction*> LoopDependenceAnalysis::GetSubscripts(
-    const ir::Instruction* instruction) {
-  ir::Instruction* access_chain = GetOperandDefinition(instruction, 0);
+std::vector<opt::Instruction*> LoopDependenceAnalysis::GetSubscripts(
+    const opt::Instruction* instruction) {
+  opt::Instruction* access_chain = GetOperandDefinition(instruction, 0);
 
-  std::vector<ir::Instruction*> subscripts;
+  std::vector<opt::Instruction*> subscripts;
 
   for (auto i = 1u; i < access_chain->NumInOperandWords(); ++i) {
     subscripts.push_back(GetOperandDefinition(access_chain, i));
@@ -396,7 +397,7 @@
   return subscripts;
 }
 
-SENode* LoopDependenceAnalysis::GetConstantTerm(const ir::Loop* loop,
+SENode* LoopDependenceAnalysis::GetConstantTerm(const opt::Loop* loop,
                                                 SERecurrentNode* induction) {
   SENode* offset = induction->GetOffset();
   SENode* lower_bound = GetLowerBound(loop);
@@ -409,7 +410,7 @@
 }
 
 bool LoopDependenceAnalysis::CheckSupportedLoops(
-    std::vector<const ir::Loop*> loops) {
+    std::vector<const opt::Loop*> loops) {
   for (auto loop : loops) {
     if (!IsSupportedLoop(loop)) {
       return false;
@@ -419,15 +420,15 @@
 }
 
 void LoopDependenceAnalysis::MarkUnsusedDistanceEntriesAsIrrelevant(
-    const ir::Instruction* source, const ir::Instruction* destination,
+    const opt::Instruction* source, const opt::Instruction* destination,
     DistanceVector* distance_vector) {
-  std::vector<ir::Instruction*> source_subscripts = GetSubscripts(source);
-  std::vector<ir::Instruction*> destination_subscripts =
+  std::vector<opt::Instruction*> source_subscripts = GetSubscripts(source);
+  std::vector<opt::Instruction*> destination_subscripts =
       GetSubscripts(destination);
 
-  std::set<const ir::Loop*> used_loops{};
+  std::set<const opt::Loop*> used_loops{};
 
-  for (ir::Instruction* source_inst : source_subscripts) {
+  for (opt::Instruction* source_inst : source_subscripts) {
     SENode* source_node = scalar_evolution_.SimplifyExpression(
         scalar_evolution_.AnalyzeInstruction(source_inst));
     std::vector<SERecurrentNode*> recurrent_nodes =
@@ -437,7 +438,7 @@
     }
   }
 
-  for (ir::Instruction* destination_inst : destination_subscripts) {
+  for (opt::Instruction* destination_inst : destination_subscripts) {
     SENode* destination_node = scalar_evolution_.SimplifyExpression(
         scalar_evolution_.AnalyzeInstruction(destination_inst));
     std::vector<SERecurrentNode*> recurrent_nodes =
@@ -455,13 +456,13 @@
   }
 }
 
-bool LoopDependenceAnalysis::IsSupportedLoop(const ir::Loop* loop) {
-  std::vector<ir::Instruction*> inductions{};
+bool LoopDependenceAnalysis::IsSupportedLoop(const opt::Loop* loop) {
+  std::vector<opt::Instruction*> inductions{};
   loop->GetInductionVariables(inductions);
   if (inductions.size() != 1) {
     return false;
   }
-  ir::Instruction* induction = inductions[0];
+  opt::Instruction* induction = inductions[0];
   SENode* induction_node = scalar_evolution_.SimplifyExpression(
       scalar_evolution_.AnalyzeInstruction(induction));
   if (!induction_node->AsSERecurrentNode()) {
diff --git a/source/opt/loop_descriptor.cpp b/source/opt/loop_descriptor.cpp
index 9393ff7..003f364 100644
--- a/source/opt/loop_descriptor.cpp
+++ b/source/opt/loop_descriptor.cpp
@@ -29,16 +29,16 @@
 #include "opt/tree_iterator.h"
 
 namespace spvtools {
-namespace ir {
+namespace opt {
 
 // Takes in a phi instruction |induction| and the loop |header| and returns the
 // step operation of the loop.
-ir::Instruction* Loop::GetInductionStepOperation(
-    const ir::Instruction* induction) const {
+opt::Instruction* Loop::GetInductionStepOperation(
+    const opt::Instruction* induction) const {
   // Induction must be a phi instruction.
   assert(induction->opcode() == SpvOpPhi);
 
-  ir::Instruction* step = nullptr;
+  opt::Instruction* step = nullptr;
 
   opt::analysis::DefUseManager* def_use_manager = context_->get_def_use_mgr();
 
@@ -46,7 +46,7 @@
   for (uint32_t operand_id = 1; operand_id < induction->NumInOperands();
        operand_id += 2) {
     // Incoming edge.
-    ir::BasicBlock* incoming_block =
+    opt::BasicBlock* incoming_block =
         context_->cfg()->block(induction->GetSingleWordInOperand(operand_id));
 
     // Check if the block is dominated by header, and thus coming from within
@@ -142,17 +142,17 @@
   return remainder;
 }
 
-ir::Instruction* Loop::GetConditionInst() const {
-  ir::BasicBlock* condition_block = FindConditionBlock();
+opt::Instruction* Loop::GetConditionInst() const {
+  opt::BasicBlock* condition_block = FindConditionBlock();
   if (!condition_block) {
     return nullptr;
   }
-  ir::Instruction* branch_conditional = &*condition_block->tail();
+  opt::Instruction* branch_conditional = &*condition_block->tail();
   if (!branch_conditional ||
       branch_conditional->opcode() != SpvOpBranchConditional) {
     return nullptr;
   }
-  ir::Instruction* condition_inst = context_->get_def_use_mgr()->GetDef(
+  opt::Instruction* condition_inst = context_->get_def_use_mgr()->GetDef(
       branch_conditional->GetSingleWordInOperand(0));
   if (IsSupportedCondition(condition_inst->opcode())) {
     return condition_inst;
@@ -164,14 +164,14 @@
 // Extract the initial value from the |induction| OpPhi instruction and store it
 // in |value|. If the function couldn't find the initial value of |induction|
 // return false.
-bool Loop::GetInductionInitValue(const ir::Instruction* induction,
+bool Loop::GetInductionInitValue(const opt::Instruction* induction,
                                  int64_t* value) const {
-  ir::Instruction* constant_instruction = nullptr;
+  opt::Instruction* constant_instruction = nullptr;
   opt::analysis::DefUseManager* def_use_manager = context_->get_def_use_mgr();
 
   for (uint32_t operand_id = 0; operand_id < induction->NumInOperands();
        operand_id += 2) {
-    ir::BasicBlock* bb = context_->cfg()->block(
+    opt::BasicBlock* bb = context_->cfg()->block(
         induction->GetSingleWordInOperand(operand_id + 1));
 
     if (!IsInsideLoop(bb)) {
@@ -327,8 +327,8 @@
   loop_preheader_ = preheader;
 }
 
-ir::BasicBlock* Loop::FindLatchBlock() {
-  ir::CFG* cfg = context_->cfg();
+opt::BasicBlock* Loop::FindLatchBlock() {
+  opt::CFG* cfg = context_->cfg();
 
   opt::DominatorAnalysis* dominator_analysis =
       context_->GetDominatorAnalysis(loop_header_->GetParent());
@@ -350,7 +350,7 @@
 }
 
 void Loop::GetExitBlocks(std::unordered_set<uint32_t>* exit_blocks) const {
-  ir::CFG* cfg = context_->cfg();
+  opt::CFG* cfg = context_->cfg();
   exit_blocks->clear();
 
   for (uint32_t bb_id : GetBlocks()) {
@@ -366,13 +366,13 @@
 void Loop::GetMergingBlocks(
     std::unordered_set<uint32_t>* merging_blocks) const {
   assert(GetMergeBlock() && "This loop is not structured");
-  ir::CFG* cfg = context_->cfg();
+  opt::CFG* cfg = context_->cfg();
   merging_blocks->clear();
 
-  std::stack<const ir::BasicBlock*> to_visit;
+  std::stack<const opt::BasicBlock*> to_visit;
   to_visit.push(GetMergeBlock());
   while (!to_visit.empty()) {
-    const ir::BasicBlock* bb = to_visit.top();
+    const opt::BasicBlock* bb = to_visit.top();
     to_visit.pop();
     merging_blocks->insert(bb->id());
     for (uint32_t pred_id : cfg->preds(bb->id())) {
@@ -386,7 +386,7 @@
 namespace {
 
 static inline bool IsBasicBlockSafeToClone(IRContext* context, BasicBlock* bb) {
-  for (ir::Instruction& inst : *bb) {
+  for (opt::Instruction& inst : *bb) {
     if (!inst.IsBranch() && !context->IsCombinatorInstruction(&inst))
       return false;
   }
@@ -397,7 +397,7 @@
 }  // namespace
 
 bool Loop::IsSafeToClone() const {
-  ir::CFG& cfg = *context_->cfg();
+  opt::CFG& cfg = *context_->cfg();
 
   for (uint32_t bb_id : GetBlocks()) {
     BasicBlock* bb = cfg.block(bb_id);
@@ -421,14 +421,14 @@
 }
 
 bool Loop::IsLCSSA() const {
-  ir::CFG* cfg = context_->cfg();
+  opt::CFG* cfg = context_->cfg();
   opt::analysis::DefUseManager* def_use_mgr = context_->get_def_use_mgr();
 
   std::unordered_set<uint32_t> exit_blocks;
   GetExitBlocks(&exit_blocks);
 
   // Declare ir_context so we can capture context_ in the below lambda
-  ir::IRContext* ir_context = context_;
+  opt::IRContext* ir_context = context_;
 
   for (uint32_t bb_id : GetBlocks()) {
     for (Instruction& insn : *cfg->block(bb_id)) {
@@ -437,7 +437,7 @@
       //  - In an exit block and in a phi instruction.
       if (!def_use_mgr->WhileEachUser(
               &insn,
-              [&exit_blocks, ir_context, this](ir::Instruction* use) -> bool {
+              [&exit_blocks, ir_context, this](opt::Instruction* use) -> bool {
                 BasicBlock* parent = ir_context->get_instr_block(use);
                 assert(parent && "Invalid analysis");
                 if (IsInsideLoop(parent)) return true;
@@ -472,9 +472,9 @@
 }
 
 void Loop::ComputeLoopStructuredOrder(
-    std::vector<ir::BasicBlock*>* ordered_loop_blocks, bool include_pre_header,
+    std::vector<opt::BasicBlock*>* ordered_loop_blocks, bool include_pre_header,
     bool include_merge) const {
-  ir::CFG& cfg = *context_->cfg();
+  opt::CFG& cfg = *context_->cfg();
 
   // Reserve the memory: all blocks in the loop + extra if needed.
   ordered_loop_blocks->reserve(GetBlocks().size() + include_pre_header +
@@ -508,7 +508,7 @@
   // instructions.
   opt::DominatorTree& dom_tree = dom_analysis->GetDomTree();
   for (opt::DominatorTreeNode& node :
-       ir::make_range(dom_tree.post_begin(), dom_tree.post_end())) {
+       opt::make_range(dom_tree.post_begin(), dom_tree.post_end())) {
     Instruction* merge_inst = node.bb_->GetLoopMergeInst();
     if (merge_inst) {
       bool all_backedge_unreachable = true;
@@ -578,14 +578,14 @@
   }
 }
 
-std::vector<ir::Loop*> LoopDescriptor::GetLoopsInBinaryLayoutOrder() {
+std::vector<opt::Loop*> LoopDescriptor::GetLoopsInBinaryLayoutOrder() {
   std::vector<uint32_t> ids{};
 
   for (size_t i = 0; i < NumLoops(); ++i) {
     ids.push_back(GetLoopByIndex(i).GetHeaderBlock()->id());
   }
 
-  std::vector<ir::Loop*> loops{};
+  std::vector<opt::Loop*> loops{};
   if (!ids.empty()) {
     auto function = GetLoopByIndex(0).GetHeaderBlock()->GetParent();
     for (const auto& block : *function) {
@@ -601,11 +601,11 @@
   return loops;
 }
 
-ir::BasicBlock* Loop::FindConditionBlock() const {
+opt::BasicBlock* Loop::FindConditionBlock() const {
   if (!loop_merge_) {
     return nullptr;
   }
-  ir::BasicBlock* condition_block = nullptr;
+  opt::BasicBlock* condition_block = nullptr;
 
   uint32_t in_loop_pred = 0;
   for (uint32_t p : context_->cfg()->preds(loop_merge_->id())) {
@@ -622,11 +622,11 @@
     return nullptr;
   }
 
-  ir::BasicBlock* bb = context_->cfg()->block(in_loop_pred);
+  opt::BasicBlock* bb = context_->cfg()->block(in_loop_pred);
 
   if (!bb) return nullptr;
 
-  const ir::Instruction& branch = *bb->ctail();
+  const opt::Instruction& branch = *bb->ctail();
 
   // Make sure the branch is a conditional branch.
   if (branch.opcode() != SpvOpBranchConditional) return nullptr;
@@ -640,8 +640,8 @@
   return condition_block;
 }
 
-bool Loop::FindNumberOfIterations(const ir::Instruction* induction,
-                                  const ir::Instruction* branch_inst,
+bool Loop::FindNumberOfIterations(const opt::Instruction* induction,
+                                  const opt::Instruction* branch_inst,
                                   size_t* iterations_out,
                                   int64_t* step_value_out,
                                   int64_t* init_value_out) const {
@@ -649,7 +649,7 @@
   opt::analysis::DefUseManager* def_use_manager = context_->get_def_use_mgr();
 
   // Condition instruction from the OpConditionalBranch.
-  ir::Instruction* condition =
+  opt::Instruction* condition =
       def_use_manager->GetDef(branch_inst->GetSingleWordOperand(0));
 
   assert(IsSupportedCondition(condition->opcode()));
@@ -680,7 +680,7 @@
   }
 
   // Find the instruction which is stepping through the loop.
-  ir::Instruction* step_inst = GetInductionStepOperation(induction);
+  opt::Instruction* step_inst = GetInductionStepOperation(induction);
   if (!step_inst) return false;
 
   // Find the constant value used by the condition variable.
@@ -833,20 +833,20 @@
 
 // Returns the list of induction variables within the loop.
 void Loop::GetInductionVariables(
-    std::vector<ir::Instruction*>& induction_variables) const {
-  for (ir::Instruction& inst : *loop_header_) {
+    std::vector<opt::Instruction*>& induction_variables) const {
+  for (opt::Instruction& inst : *loop_header_) {
     if (inst.opcode() == SpvOp::SpvOpPhi) {
       induction_variables.push_back(&inst);
     }
   }
 }
 
-ir::Instruction* Loop::FindConditionVariable(
-    const ir::BasicBlock* condition_block) const {
+opt::Instruction* Loop::FindConditionVariable(
+    const opt::BasicBlock* condition_block) const {
   // Find the branch instruction.
-  const ir::Instruction& branch_inst = *condition_block->ctail();
+  const opt::Instruction& branch_inst = *condition_block->ctail();
 
-  ir::Instruction* induction = nullptr;
+  opt::Instruction* induction = nullptr;
   // Verify that the branch instruction is a conditional branch.
   if (branch_inst.opcode() == SpvOp::SpvOpBranchConditional) {
     // From the branch instruction find the branch condition.
@@ -854,13 +854,13 @@
 
     // Find the instruction representing the condition used in the conditional
     // branch.
-    ir::Instruction* condition =
+    opt::Instruction* condition =
         def_use_manager->GetDef(branch_inst.GetSingleWordOperand(0));
 
     // Ensure that the condition is a less than operation.
     if (condition && IsSupportedCondition(condition->opcode())) {
       // The left hand side operand of the operation.
-      ir::Instruction* variable_inst =
+      opt::Instruction* variable_inst =
           def_use_manager->GetDef(condition->GetSingleWordOperand(2));
 
       // Make sure the variable instruction used is a phi.
@@ -924,7 +924,7 @@
 // maintain the state of the loop descriptor class.
 void LoopDescriptor::PostModificationCleanup() {
   LoopContainerType loops_to_remove_;
-  for (ir::Loop* loop : loops_) {
+  for (opt::Loop* loop : loops_) {
     if (loop->IsMarkedForRemoval()) {
       loops_to_remove_.push_back(loop);
       if (loop->HasParent()) {
@@ -933,13 +933,13 @@
     }
   }
 
-  for (ir::Loop* loop : loops_to_remove_) {
+  for (opt::Loop* loop : loops_to_remove_) {
     loops_.erase(std::find(loops_.begin(), loops_.end(), loop));
   }
 
   for (auto& pair : loops_to_add_) {
-    ir::Loop* parent = pair.first;
-    ir::Loop* loop = pair.second;
+    opt::Loop* parent = pair.first;
+    opt::Loop* loop = pair.second;
 
     if (parent) {
       loop->SetParent(nullptr);
@@ -964,12 +964,12 @@
 }
 
 // Adds a new loop nest to the descriptor set.
-ir::Loop* LoopDescriptor::AddLoopNest(std::unique_ptr<ir::Loop> new_loop) {
-  ir::Loop* loop = new_loop.release();
+opt::Loop* LoopDescriptor::AddLoopNest(std::unique_ptr<opt::Loop> new_loop) {
+  opt::Loop* loop = new_loop.release();
   if (!loop->HasParent()) dummy_top_loop_.nested_loops_.push_back(loop);
   // Iterate from inner to outer most loop, adding basic block to loop mapping
   // as we go.
-  for (ir::Loop& current_loop :
+  for (opt::Loop& current_loop :
        make_range(iterator::begin(loop), iterator::end(nullptr))) {
     loops_.push_back(&current_loop);
     for (uint32_t bb_id : current_loop.GetBlocks())
@@ -979,18 +979,18 @@
   return loop;
 }
 
-void LoopDescriptor::RemoveLoop(ir::Loop* loop) {
-  ir::Loop* parent = loop->GetParent() ? loop->GetParent() : &dummy_top_loop_;
+void LoopDescriptor::RemoveLoop(opt::Loop* loop) {
+  opt::Loop* parent = loop->GetParent() ? loop->GetParent() : &dummy_top_loop_;
   parent->nested_loops_.erase(std::find(parent->nested_loops_.begin(),
                                         parent->nested_loops_.end(), loop));
   std::for_each(
       loop->nested_loops_.begin(), loop->nested_loops_.end(),
-      [loop](ir::Loop* sub_loop) { sub_loop->SetParent(loop->GetParent()); });
+      [loop](opt::Loop* sub_loop) { sub_loop->SetParent(loop->GetParent()); });
   parent->nested_loops_.insert(parent->nested_loops_.end(),
                                loop->nested_loops_.begin(),
                                loop->nested_loops_.end());
   for (uint32_t bb_id : loop->GetBlocks()) {
-    ir::Loop* l = FindLoopForBasicBlock(bb_id);
+    opt::Loop* l = FindLoopForBasicBlock(bb_id);
     if (l == loop) {
       SetBasicBlockToLoop(bb_id, l->GetParent());
     } else {
@@ -1005,5 +1005,5 @@
   loops_.erase(it);
 }
 
-}  // namespace ir
+}  // namespace opt
 }  // namespace spvtools
diff --git a/source/opt/loop_descriptor.h b/source/opt/loop_descriptor.h
index 714cd14..f0dd085 100644
--- a/source/opt/loop_descriptor.h
+++ b/source/opt/loop_descriptor.h
@@ -24,15 +24,13 @@
 #include <vector>
 
 #include "opt/basic_block.h"
+#include "opt/dominator_analysis.h"
 #include "opt/module.h"
 #include "opt/tree_iterator.h"
 
 namespace spvtools {
 namespace opt {
-class DominatorAnalysis;
-struct DominatorTreeNode;
-}  // namespace opt
-namespace ir {
+
 class IRContext;
 class CFG;
 class LoopDescriptor;
@@ -79,7 +77,7 @@
   inline void UpdateLoopMergeInst() {
     assert(GetHeaderBlock()->GetLoopMergeInst() &&
            "The loop is not structured");
-    ir::Instruction* merge_inst = GetHeaderBlock()->GetLoopMergeInst();
+    opt::Instruction* merge_inst = GetHeaderBlock()->GetLoopMergeInst();
     merge_inst->SetInOperand(0, {GetMergeBlock()->id()});
   }
 
@@ -234,20 +232,21 @@
   }
 
   // Returns the list of induction variables within the loop.
-  void GetInductionVariables(std::vector<ir::Instruction*>& inductions) const;
+  void GetInductionVariables(std::vector<opt::Instruction*>& inductions) const;
 
   // This function uses the |condition| to find the induction variable which is
   // used by the loop condition within the loop. This only works if the loop is
   // bound by a single condition and single induction variable.
-  ir::Instruction* FindConditionVariable(const ir::BasicBlock* condition) const;
+  opt::Instruction* FindConditionVariable(
+      const opt::BasicBlock* condition) const;
 
   // Returns the number of iterations within a loop when given the |induction|
   // variable and the loop |condition| check. It stores the found number of
   // iterations in the output parameter |iterations| and optionally, the step
   // value in |step_value| and the initial value of the induction variable in
   // |init_value|.
-  bool FindNumberOfIterations(const ir::Instruction* induction,
-                              const ir::Instruction* condition,
+  bool FindNumberOfIterations(const opt::Instruction* induction,
+                              const opt::Instruction* condition,
                               size_t* iterations,
                               int64_t* step_amount = nullptr,
                               int64_t* init_value = nullptr) const;
@@ -264,7 +263,7 @@
 
   // Finds the conditional block with a branch to the merge and continue blocks
   // within the loop body.
-  ir::BasicBlock* FindConditionBlock() const;
+  opt::BasicBlock* FindConditionBlock() const;
 
   // Remove the child loop form this loop.
   inline void RemoveChildLoop(Loop* loop) {
@@ -308,13 +307,13 @@
   // Extract the initial value from the |induction| variable and store it in
   // |value|. If the function couldn't find the initial value of |induction|
   // return false.
-  bool GetInductionInitValue(const ir::Instruction* induction,
+  bool GetInductionInitValue(const opt::Instruction* induction,
                              int64_t* value) const;
 
   // Takes in a phi instruction |induction| and the loop |header| and returns
   // the step operation of the loop.
-  ir::Instruction* GetInductionStepOperation(
-      const ir::Instruction* induction) const;
+  opt::Instruction* GetInductionStepOperation(
+      const opt::Instruction* induction) const;
 
   // Returns true if we can deduce the number of loop iterations in the step
   // operation |step|. IsSupportedCondition must also be true for the condition
@@ -332,7 +331,7 @@
   // exist. If |include_merge| is true, the merge block will also be included at
   // the end of the list if it exist.
   void ComputeLoopStructuredOrder(
-      std::vector<ir::BasicBlock*>* ordered_loop_blocks,
+      std::vector<opt::BasicBlock*>* ordered_loop_blocks,
       bool include_pre_header = false, bool include_merge = false) const;
 
   // Given the loop |condition|, |initial_value|, |step_value|, the trip count
@@ -346,7 +345,7 @@
 
   // Returns the condition instruction for entry into the loop
   // Returns nullptr if it can't be found.
-  ir::Instruction* GetConditionInst() const;
+  opt::Instruction* GetConditionInst() const;
 
   // Returns the context associated this loop.
   IRContext* GetContext() const { return context_; }
@@ -355,7 +354,7 @@
   // which is also dominated by the loop continue block. This block is the latch
   // block. The specification mandates that this block should exist, therefore
   // this function will assert if it is not found.
-  ir::BasicBlock* FindLatchBlock();
+  opt::BasicBlock* FindLatchBlock();
 
  private:
   IRContext* context_;
@@ -459,7 +458,7 @@
 
   // Returns the loops in |this| in the order their headers appear in the
   // binary.
-  std::vector<ir::Loop*> GetLoopsInBinaryLayoutOrder();
+  std::vector<opt::Loop*> GetLoopsInBinaryLayoutOrder();
 
   // Returns the inner most loop that contains the basic block id |block_id|.
   inline Loop* operator[](uint32_t block_id) const {
@@ -502,7 +501,7 @@
 
   // Mark the loop |loop_to_add| as needing to be added when the user calls
   // PostModificationCleanup. |parent| may be null.
-  inline void AddLoop(ir::Loop* loop_to_add, ir::Loop* parent) {
+  inline void AddLoop(opt::Loop* loop_to_add, opt::Loop* parent) {
     loops_to_add_.emplace_back(std::make_pair(parent, loop_to_add));
   }
 
@@ -521,12 +520,12 @@
 
   // Adds the loop |new_loop| and all its nested loops to the descriptor set.
   // The object takes ownership of all the loops.
-  ir::Loop* AddLoopNest(std::unique_ptr<ir::Loop> new_loop);
+  opt::Loop* AddLoopNest(std::unique_ptr<opt::Loop> new_loop);
 
   // Remove the loop |loop|.
-  void RemoveLoop(ir::Loop* loop);
+  void RemoveLoop(opt::Loop* loop);
 
-  void SetAsTopLoop(ir::Loop* loop) {
+  void SetAsTopLoop(opt::Loop* loop) {
     assert(std::find(dummy_top_loop_.begin(), dummy_top_loop_.end(), loop) ==
                dummy_top_loop_.end() &&
            "already registered");
@@ -569,7 +568,7 @@
   LoopsToAddContainerType loops_to_add_;
 };
 
-}  // namespace ir
+}  // namespace opt
 }  // namespace spvtools
 
 #endif  // LIBSPIRV_OPT_LOOP_DESCRIPTORS_H_
diff --git a/source/opt/loop_fission.cpp b/source/opt/loop_fission.cpp
index 10d5220..b942fff 100644
--- a/source/opt/loop_fission.cpp
+++ b/source/opt/loop_fission.cpp
@@ -55,7 +55,7 @@
 
 class LoopFissionImpl {
  public:
-  LoopFissionImpl(ir::IRContext* context, ir::Loop* loop)
+  LoopFissionImpl(opt::IRContext* context, opt::Loop* loop)
       : context_(context), loop_(loop), load_used_in_condition_(false) {}
 
   // Group each instruction in the loop into sets of instructions related by
@@ -69,37 +69,37 @@
   bool CanPerformSplit();
 
   // Split the loop and return a pointer to the new loop.
-  ir::Loop* SplitLoop();
+  opt::Loop* SplitLoop();
 
   // Checks if |inst| is safe to move. We can only move instructions which don't
   // have any side effects and OpLoads and OpStores.
-  bool MovableInstruction(const ir::Instruction& inst) const;
+  bool MovableInstruction(const opt::Instruction& inst) const;
 
  private:
   // Traverse the def use chain of |inst| and add the users and uses of |inst|
   // which are in the same loop to the |returned_set|.
-  void TraverseUseDef(ir::Instruction* inst,
-                      std::set<ir::Instruction*>* returned_set,
+  void TraverseUseDef(opt::Instruction* inst,
+                      std::set<opt::Instruction*>* returned_set,
                       bool ignore_phi_users = false, bool report_loads = false);
 
   // We group the instructions in the block into two different groups, the
   // instructions to be kept in the original loop and the ones to be cloned into
   // the new loop. As the cloned loop is attached to the preheader it will be
   // the first loop and the second loop will be the original.
-  std::set<ir::Instruction*> cloned_loop_instructions_;
-  std::set<ir::Instruction*> original_loop_instructions_;
+  std::set<opt::Instruction*> cloned_loop_instructions_;
+  std::set<opt::Instruction*> original_loop_instructions_;
 
   // We need a set of all the instructions to be seen so we can break any
   // recursion and also so we can ignore certain instructions by preemptively
   // adding them to this set.
-  std::set<ir::Instruction*> seen_instructions_;
+  std::set<opt::Instruction*> seen_instructions_;
 
   // A map of instructions to their relative position in the function.
-  std::map<ir::Instruction*, size_t> instruction_order_;
+  std::map<opt::Instruction*, size_t> instruction_order_;
 
-  ir::IRContext* context_;
+  opt::IRContext* context_;
 
-  ir::Loop* loop_;
+  opt::Loop* loop_;
 
   // This is set to true by TraverseUseDef when traversing the instructions
   // related to the loop condition and any if conditions should any of those
@@ -107,27 +107,27 @@
   bool load_used_in_condition_;
 };
 
-bool LoopFissionImpl::MovableInstruction(const ir::Instruction& inst) const {
+bool LoopFissionImpl::MovableInstruction(const opt::Instruction& inst) const {
   return inst.opcode() == SpvOp::SpvOpLoad ||
          inst.opcode() == SpvOp::SpvOpStore ||
          inst.opcode() == SpvOp::SpvOpSelectionMerge ||
          inst.opcode() == SpvOp::SpvOpPhi || inst.IsOpcodeCodeMotionSafe();
 }
 
-void LoopFissionImpl::TraverseUseDef(ir::Instruction* inst,
-                                     std::set<ir::Instruction*>* returned_set,
+void LoopFissionImpl::TraverseUseDef(opt::Instruction* inst,
+                                     std::set<opt::Instruction*>* returned_set,
                                      bool ignore_phi_users, bool report_loads) {
   assert(returned_set && "Set to be returned cannot be null.");
 
   opt::analysis::DefUseManager* def_use = context_->get_def_use_mgr();
-  std::set<ir::Instruction*>& inst_set = *returned_set;
+  std::set<opt::Instruction*>& inst_set = *returned_set;
 
   // We create this functor to traverse the use def chain to build the
   // grouping of related instructions. The lambda captures the std::function
   // to allow it to recurse.
-  std::function<void(ir::Instruction*)> traverser_functor;
+  std::function<void(opt::Instruction*)> traverser_functor;
   traverser_functor = [this, def_use, &inst_set, &traverser_functor,
-                       ignore_phi_users, report_loads](ir::Instruction* user) {
+                       ignore_phi_users, report_loads](opt::Instruction* user) {
     // If we've seen the instruction before or it is not inside the loop end the
     // traversal.
     if (!user || seen_instructions_.count(user) != 0 ||
@@ -171,7 +171,7 @@
     def_use->ForEachUser(user, traverser_functor);
 
     // Wrapper functor for the use traversal.
-    auto traverse_use = [&traverser_functor](ir::Instruction* use, uint32_t) {
+    auto traverse_use = [&traverser_functor](opt::Instruction* use, uint32_t) {
       traverser_functor(use);
     };
     def_use->ForEachUse(user, traverse_use);
@@ -184,33 +184,33 @@
 }
 
 bool LoopFissionImpl::GroupInstructionsByUseDef() {
-  std::vector<std::set<ir::Instruction*>> sets{};
+  std::vector<std::set<opt::Instruction*>> sets{};
 
   // We want to ignore all the instructions stemming from the loop condition
   // instruction.
-  ir::BasicBlock* condition_block = loop_->FindConditionBlock();
+  opt::BasicBlock* condition_block = loop_->FindConditionBlock();
 
   if (!condition_block) return false;
-  ir::Instruction* condition = &*condition_block->tail();
+  opt::Instruction* condition = &*condition_block->tail();
 
   // We iterate over the blocks via iterating over all the blocks in the
   // function, we do this so we are iterating in the same order which the blocks
   // appear in the binary.
-  ir::Function& function = *loop_->GetHeaderBlock()->GetParent();
+  opt::Function& function = *loop_->GetHeaderBlock()->GetParent();
 
   // Create a temporary set to ignore certain groups of instructions within the
   // loop. We don't want any instructions related to control flow to be removed
   // from either loop only instructions within the control flow bodies.
-  std::set<ir::Instruction*> instructions_to_ignore{};
+  std::set<opt::Instruction*> instructions_to_ignore{};
   TraverseUseDef(condition, &instructions_to_ignore, true, true);
 
   // Traverse control flow instructions to ensure they are added to the
   // seen_instructions_ set and will be ignored when it it called with actual
   // sets.
-  for (ir::BasicBlock& block : function) {
+  for (opt::BasicBlock& block : function) {
     if (!loop_->IsInsideLoop(block.id())) continue;
 
-    for (ir::Instruction& inst : block) {
+    for (opt::Instruction& inst : block) {
       // Ignore all instructions related to control flow.
       if (inst.opcode() == SpvOp::SpvOpSelectionMerge || inst.IsBranch()) {
         TraverseUseDef(&inst, &instructions_to_ignore, true, true);
@@ -220,12 +220,12 @@
 
   // Traverse the instructions and generate the sets, automatically ignoring any
   // instructions in instructions_to_ignore.
-  for (ir::BasicBlock& block : function) {
+  for (opt::BasicBlock& block : function) {
     if (!loop_->IsInsideLoop(block.id()) ||
         loop_->GetHeaderBlock()->id() == block.id())
       continue;
 
-    for (ir::Instruction& inst : block) {
+    for (opt::Instruction& inst : block) {
       // Record the order that each load/store is seen.
       if (inst.opcode() == SpvOp::SpvOpLoad ||
           inst.opcode() == SpvOp::SpvOpStore) {
@@ -238,7 +238,7 @@
       }
 
       // Build the set.
-      std::set<ir::Instruction*> inst_set{};
+      std::set<opt::Instruction*> inst_set{};
       TraverseUseDef(&inst, &inst_set);
       if (!inst_set.empty()) sets.push_back(std::move(inst_set));
     }
@@ -273,8 +273,8 @@
 
   // Build a list of all parent loops of this loop. Loop dependence analysis
   // needs this structure.
-  std::vector<const ir::Loop*> loops;
-  ir::Loop* parent_loop = loop_;
+  std::vector<const opt::Loop*> loops;
+  opt::Loop* parent_loop = loop_;
   while (parent_loop) {
     loops.push_back(parent_loop);
     parent_loop = parent_loop->GetParent();
@@ -283,13 +283,13 @@
   LoopDependenceAnalysis analysis{context_, loops};
 
   // A list of all the stores in the cloned loop.
-  std::vector<ir::Instruction*> set_one_stores{};
+  std::vector<opt::Instruction*> set_one_stores{};
 
   // A list of all the loads in the cloned loop.
-  std::vector<ir::Instruction*> set_one_loads{};
+  std::vector<opt::Instruction*> set_one_loads{};
 
   // Populate the above lists.
-  for (ir::Instruction* inst : cloned_loop_instructions_) {
+  for (opt::Instruction* inst : cloned_loop_instructions_) {
     if (inst->opcode() == SpvOp::SpvOpStore) {
       set_one_stores.push_back(inst);
     } else if (inst->opcode() == SpvOp::SpvOpLoad) {
@@ -307,7 +307,7 @@
 
   // Check the dependencies between loads in the cloned loop and stores in the
   // original and vice versa.
-  for (ir::Instruction* inst : original_loop_instructions_) {
+  for (opt::Instruction* inst : original_loop_instructions_) {
     // If we find any instruction which we can't move (such as a barrier),
     // return false.
     if (!MovableInstruction(*inst)) return false;
@@ -315,7 +315,7 @@
     // Look at the dependency between the loads in the original and stores in
     // the cloned loops.
     if (inst->opcode() == SpvOp::SpvOpLoad) {
-      for (ir::Instruction* store : set_one_stores) {
+      for (opt::Instruction* store : set_one_stores) {
         DistanceVector vec{loop_depth};
 
         // If the store actually should appear after the load, return false.
@@ -333,7 +333,7 @@
         }
       }
     } else if (inst->opcode() == SpvOp::SpvOpStore) {
-      for (ir::Instruction* load : set_one_loads) {
+      for (opt::Instruction* load : set_one_loads) {
         DistanceVector vec{loop_depth};
 
         // If the load actually should appear after the store, return false.
@@ -355,30 +355,30 @@
   return true;
 }
 
-ir::Loop* LoopFissionImpl::SplitLoop() {
+opt::Loop* LoopFissionImpl::SplitLoop() {
   // Clone the loop.
   LoopUtils util{context_, loop_};
   LoopUtils::LoopCloningResult clone_results;
-  ir::Loop* cloned_loop = util.CloneAndAttachLoopToHeader(&clone_results);
+  opt::Loop* cloned_loop = util.CloneAndAttachLoopToHeader(&clone_results);
 
   // Update the OpLoopMerge in the cloned loop.
   cloned_loop->UpdateLoopMergeInst();
 
   // Add the loop_ to the module.
-  ir::Function::iterator it =
+  opt::Function::iterator it =
       util.GetFunction()->FindBlock(loop_->GetOrCreatePreHeaderBlock()->id());
   util.GetFunction()->AddBasicBlocks(clone_results.cloned_bb_.begin(),
                                      clone_results.cloned_bb_.end(), ++it);
   loop_->SetPreHeaderBlock(cloned_loop->GetMergeBlock());
 
-  std::vector<ir::Instruction*> instructions_to_kill{};
+  std::vector<opt::Instruction*> instructions_to_kill{};
 
   // Kill all the instructions which should appear in the cloned loop but not in
   // the original loop.
   for (uint32_t id : loop_->GetBlocks()) {
-    ir::BasicBlock* block = context_->cfg()->block(id);
+    opt::BasicBlock* block = context_->cfg()->block(id);
 
-    for (ir::Instruction& inst : *block) {
+    for (opt::Instruction& inst : *block) {
       // If the instruction appears in the cloned loop instruction group, kill
       // it.
       if (cloned_loop_instructions_.count(&inst) == 1 &&
@@ -395,9 +395,9 @@
   // Kill all instructions which should appear in the original loop and not in
   // the cloned loop.
   for (uint32_t id : cloned_loop->GetBlocks()) {
-    ir::BasicBlock* block = context_->cfg()->block(id);
-    for (ir::Instruction& inst : *block) {
-      ir::Instruction* old_inst = clone_results.ptr_map_[&inst];
+    opt::BasicBlock* block = context_->cfg()->block(id);
+    for (opt::Instruction& inst : *block) {
+      opt::Instruction* old_inst = clone_results.ptr_map_[&inst];
       // If the instruction belongs to the original loop instruction group, kill
       // it.
       if (cloned_loop_instructions_.count(old_inst) == 0 &&
@@ -407,7 +407,7 @@
     }
   }
 
-  for (ir::Instruction* i : instructions_to_kill) {
+  for (opt::Instruction* i : instructions_to_kill) {
     context_->KillInst(i);
   }
 
@@ -433,37 +433,38 @@
   };
 }
 
-bool LoopFissionPass::ShouldSplitLoop(const ir::Loop& loop, ir::IRContext* c) {
+bool LoopFissionPass::ShouldSplitLoop(const opt::Loop& loop,
+                                      opt::IRContext* c) {
   LivenessAnalysis* analysis = c->GetLivenessAnalysis();
 
   RegisterLiveness::RegionRegisterLiveness liveness{};
 
-  ir::Function* function = loop.GetHeaderBlock()->GetParent();
+  opt::Function* function = loop.GetHeaderBlock()->GetParent();
   analysis->Get(function)->ComputeLoopRegisterPressure(loop, &liveness);
 
   return split_criteria_(liveness);
 }
 
-Pass::Status LoopFissionPass::Process(ir::IRContext* c) {
+Pass::Status LoopFissionPass::Process(opt::IRContext* c) {
   bool changed = false;
 
-  for (ir::Function& f : *c->module()) {
+  for (opt::Function& f : *c->module()) {
     // We collect all the inner most loops in the function and run the loop
     // splitting util on each. The reason we do this is to allow us to iterate
     // over each, as creating new loops will invalidate the the loop iterator.
-    std::vector<ir::Loop*> inner_most_loops{};
-    ir::LoopDescriptor& loop_descriptor = *c->GetLoopDescriptor(&f);
-    for (ir::Loop& loop : loop_descriptor) {
+    std::vector<opt::Loop*> inner_most_loops{};
+    opt::LoopDescriptor& loop_descriptor = *c->GetLoopDescriptor(&f);
+    for (opt::Loop& loop : loop_descriptor) {
       if (!loop.HasChildren() && ShouldSplitLoop(loop, c)) {
         inner_most_loops.push_back(&loop);
       }
     }
 
     // List of new loops which meet the criteria to be split again.
-    std::vector<ir::Loop*> new_loops_to_split{};
+    std::vector<opt::Loop*> new_loops_to_split{};
 
     while (!inner_most_loops.empty()) {
-      for (ir::Loop* loop : inner_most_loops) {
+      for (opt::Loop* loop : inner_most_loops) {
         LoopFissionImpl impl{c, loop};
 
         // Group the instructions in the loop into two different sets of related
@@ -474,9 +475,9 @@
         }
 
         if (impl.CanPerformSplit()) {
-          ir::Loop* second_loop = impl.SplitLoop();
+          opt::Loop* second_loop = impl.SplitLoop();
           changed = true;
-          c->InvalidateAnalysesExceptFor(ir::IRContext::kAnalysisLoopAnalysis);
+          c->InvalidateAnalysesExceptFor(opt::IRContext::kAnalysisLoopAnalysis);
 
           // If the newly created loop meets the criteria to be split, split it
           // again.
diff --git a/source/opt/loop_fission.h b/source/opt/loop_fission.h
index 8a7424d..3464ee1 100644
--- a/source/opt/loop_fission.h
+++ b/source/opt/loop_fission.h
@@ -57,10 +57,10 @@
 
   const char* name() const override { return "Loop Fission"; }
 
-  Pass::Status Process(ir::IRContext* context) override;
+  Pass::Status Process(opt::IRContext* context) override;
 
   // Checks if |loop| meets the register pressure criteria to be split.
-  bool ShouldSplitLoop(const ir::Loop& loop, ir::IRContext* context);
+  bool ShouldSplitLoop(const opt::Loop& loop, opt::IRContext* context);
 
  private:
   // Functor to run in ShouldSplitLoop to determine if the register pressure
diff --git a/source/opt/loop_fusion.cpp b/source/opt/loop_fusion.cpp
index eacf1c3..a7c4292 100644
--- a/source/opt/loop_fusion.cpp
+++ b/source/opt/loop_fusion.cpp
@@ -27,7 +27,7 @@
 namespace {
 
 // Append all the loops nested in |loop| to |loops|.
-void CollectChildren(ir::Loop* loop, std::vector<const ir::Loop*>* loops) {
+void CollectChildren(opt::Loop* loop, std::vector<const opt::Loop*>* loops) {
   for (auto child : *loop) {
     loops->push_back(child);
     if (child->NumImmediateChildren() != 0) {
@@ -37,10 +37,10 @@
 }
 
 // Return the set of locations accessed by |stores| and |loads|.
-std::set<ir::Instruction*> GetLocationsAccessed(
-    const std::map<ir::Instruction*, std::vector<ir::Instruction*>>& stores,
-    const std::map<ir::Instruction*, std::vector<ir::Instruction*>>& loads) {
-  std::set<ir::Instruction*> locations{};
+std::set<opt::Instruction*> GetLocationsAccessed(
+    const std::map<opt::Instruction*, std::vector<opt::Instruction*>>& stores,
+    const std::map<opt::Instruction*, std::vector<opt::Instruction*>>& loads) {
+  std::set<opt::Instruction*> locations{};
 
   for (const auto& kv : stores) {
     locations.insert(std::get<0>(kv));
@@ -56,8 +56,8 @@
 // Append all dependences from |sources| to |destinations| to |dependences|.
 void GetDependences(std::vector<DistanceVector>* dependences,
                     LoopDependenceAnalysis* analysis,
-                    const std::vector<ir::Instruction*>& sources,
-                    const std::vector<ir::Instruction*>& destinations,
+                    const std::vector<opt::Instruction*>& sources,
+                    const std::vector<opt::Instruction*>& destinations,
                     size_t num_entries) {
   for (auto source : sources) {
     for (auto destination : destinations) {
@@ -70,8 +70,8 @@
 }
 
 // Apped all instructions in |block| to |instructions|.
-void AddInstructionsInBlock(std::vector<ir::Instruction*>* instructions,
-                            ir::BasicBlock* block) {
+void AddInstructionsInBlock(std::vector<opt::Instruction*>* instructions,
+                            opt::BasicBlock* block) {
   for (auto& inst : *block) {
     instructions->push_back(&inst);
   }
@@ -82,12 +82,12 @@
 }  // namespace
 
 bool LoopFusion::UsedInContinueOrConditionBlock(
-    ir::Instruction* phi_instruction, ir::Loop* loop) {
+    opt::Instruction* phi_instruction, opt::Loop* loop) {
   auto condition_block = loop->FindConditionBlock()->id();
   auto continue_block = loop->GetContinueBlock()->id();
   auto not_used = context_->get_def_use_mgr()->WhileEachUser(
       phi_instruction,
-      [this, condition_block, continue_block](ir::Instruction* instruction) {
+      [this, condition_block, continue_block](opt::Instruction* instruction) {
         auto block_id = context_->get_instr_block(instruction)->id();
         return block_id != condition_block && block_id != continue_block;
       });
@@ -96,10 +96,10 @@
 }
 
 void LoopFusion::RemoveIfNotUsedContinueOrConditionBlock(
-    std::vector<ir::Instruction*>* instructions, ir::Loop* loop) {
+    std::vector<opt::Instruction*>* instructions, opt::Loop* loop) {
   instructions->erase(
       std::remove_if(std::begin(*instructions), std::end(*instructions),
-                     [this, loop](ir::Instruction* instruction) {
+                     [this, loop](opt::Instruction* instruction) {
                        return !UsedInContinueOrConditionBlock(instruction,
                                                               loop);
                      }),
@@ -132,7 +132,7 @@
 
   // |GetInductionVariables| returns all OpPhi in the header. Check that both
   // loops have exactly one that is used in the continue and condition blocks.
-  std::vector<ir::Instruction*> inductions_0{}, inductions_1{};
+  std::vector<opt::Instruction*> inductions_0{}, inductions_1{};
   loop_0_->GetInductionVariables(inductions_0);
   RemoveIfNotUsedContinueOrConditionBlock(&inductions_0, loop_0_);
 
@@ -169,7 +169,7 @@
 
   auto pre_header_1 = loop_1_->GetPreHeaderBlock();
 
-  std::vector<ir::BasicBlock*> block_to_check{};
+  std::vector<opt::BasicBlock*> block_to_check{};
   block_to_check.push_back(pre_header_1);
 
   if (loop_0_->GetMergeBlock() != loop_1_->GetPreHeaderBlock()) {
@@ -208,7 +208,7 @@
         auto is_used = false;
         context_->get_def_use_mgr()->ForEachUse(
             inst.GetSingleWordInOperand(0),
-            [&is_used](ir::Instruction* use_inst, uint32_t) {
+            [&is_used](opt::Instruction* use_inst, uint32_t) {
               if (use_inst->opcode() == SpvOpLoad) {
                 is_used = true;
               }
@@ -230,7 +230,7 @@
   return true;
 }  // namespace opt
 
-bool LoopFusion::ContainsBarriersOrFunctionCalls(ir::Loop* loop) {
+bool LoopFusion::ContainsBarriersOrFunctionCalls(opt::Loop* loop) {
   for (const auto& block : loop->GetBlocks()) {
     for (const auto& inst : *containing_function_->FindBlock(block)) {
       auto opcode = inst.opcode();
@@ -336,9 +336,9 @@
   return true;
 }
 
-std::map<ir::Instruction*, std::vector<ir::Instruction*>>
-LoopFusion::LocationToMemOps(const std::vector<ir::Instruction*>& mem_ops) {
-  std::map<ir::Instruction*, std::vector<ir::Instruction*>> location_map{};
+std::map<opt::Instruction*, std::vector<opt::Instruction*>>
+LoopFusion::LocationToMemOps(const std::vector<opt::Instruction*>& mem_ops) {
+  std::map<opt::Instruction*, std::vector<opt::Instruction*>> location_map{};
 
   for (auto instruction : mem_ops) {
     auto access_location = context_->get_def_use_mgr()->GetDef(
@@ -355,10 +355,10 @@
   return location_map;
 }
 
-std::pair<std::vector<ir::Instruction*>, std::vector<ir::Instruction*>>
-LoopFusion::GetLoadsAndStoresInLoop(ir::Loop* loop) {
-  std::vector<ir::Instruction*> loads{};
-  std::vector<ir::Instruction*> stores{};
+std::pair<std::vector<opt::Instruction*>, std::vector<opt::Instruction*>>
+LoopFusion::GetLoadsAndStoresInLoop(opt::Loop* loop) {
+  std::vector<opt::Instruction*> loads{};
+  std::vector<opt::Instruction*> stores{};
 
   for (auto block_id : loop->GetBlocks()) {
     if (block_id == loop->GetContinueBlock()->id()) {
@@ -377,9 +377,9 @@
   return std::make_pair(loads, stores);
 }
 
-bool LoopFusion::IsUsedInLoop(ir::Instruction* instruction, ir::Loop* loop) {
+bool LoopFusion::IsUsedInLoop(opt::Instruction* instruction, opt::Loop* loop) {
   auto not_used = context_->get_def_use_mgr()->WhileEachUser(
-      instruction, [this, loop](ir::Instruction* user) {
+      instruction, [this, loop](opt::Instruction* user) {
         auto block_id = context_->get_instr_block(user)->id();
         return !loop->IsInsideLoop(block_id);
       });
@@ -397,7 +397,7 @@
     return false;
   }
 
-  std::vector<ir::Instruction*> phi_instructions{};
+  std::vector<opt::Instruction*> phi_instructions{};
   loop_0_->GetInductionVariables(phi_instructions);
 
   // Check no OpPhi in |loop_0_| is used in |loop_1_|.
@@ -410,7 +410,7 @@
   // Check no LCSSA OpPhi in merge block of |loop_0_| is used in |loop_1_|.
   auto phi_used = false;
   loop_0_->GetMergeBlock()->ForEachPhiInst(
-      [this, &phi_used](ir::Instruction* phi_instruction) {
+      [this, &phi_used](opt::Instruction* phi_instruction) {
         phi_used |= IsUsedInLoop(phi_instruction, loop_1_);
       });
 
@@ -433,7 +433,7 @@
   auto locations_0 = GetLocationsAccessed(store_locs_0, load_locs_0);
   auto locations_1 = GetLocationsAccessed(store_locs_1, load_locs_1);
 
-  std::vector<ir::Instruction*> potential_clashes{};
+  std::vector<opt::Instruction*> potential_clashes{};
 
   std::set_intersection(std::begin(locations_0), std::end(locations_0),
                         std::begin(locations_1), std::end(locations_1),
@@ -445,7 +445,7 @@
   }
 
   // Find variables that have at least one store.
-  std::vector<ir::Instruction*> potential_clashes_with_stores{};
+  std::vector<opt::Instruction*> potential_clashes_with_stores{};
   for (auto location : potential_clashes) {
     if (store_locs_0.find(location) != std::end(store_locs_0) ||
         store_locs_1.find(location) != std::end(store_locs_1)) {
@@ -463,7 +463,7 @@
   // distance.
 
   // Find all the loops in this loop nest for the dependency analysis.
-  std::vector<const ir::Loop*> loops{};
+  std::vector<const opt::Loop*> loops{};
 
   // Find the parents.
   for (auto current_loop = loop_0_; current_loop != nullptr;
@@ -519,7 +519,7 @@
   return true;
 }
 
-void ReplacePhiParentWith(ir::Instruction* inst, uint32_t orig_block,
+void ReplacePhiParentWith(opt::Instruction* inst, uint32_t orig_block,
                           uint32_t new_block) {
   if (inst->GetSingleWordInOperand(1) == orig_block) {
     inst->SetInOperand(1, {new_block});
@@ -555,7 +555,7 @@
 
   // Update merge block id in the header of |loop_0_| to the merge block of
   // |loop_1_|.
-  loop_0_->GetHeaderBlock()->ForEachInst([this](ir::Instruction* inst) {
+  loop_0_->GetHeaderBlock()->ForEachInst([this](opt::Instruction* inst) {
     if (inst->opcode() == SpvOpLoopMerge) {
       inst->SetInOperand(0, {loop_1_->GetMergeBlock()->id()});
     }
@@ -563,7 +563,7 @@
 
   // Update condition branch target in |loop_0_| to the merge block of
   // |loop_1_|.
-  condition_block_of_0->ForEachInst([this](ir::Instruction* inst) {
+  condition_block_of_0->ForEachInst([this](opt::Instruction* inst) {
     if (inst->opcode() == SpvOpBranchConditional) {
       auto loop_0_merge_block_id = loop_0_->GetMergeBlock()->id();
 
@@ -577,7 +577,7 @@
 
   // Move OpPhi instructions not corresponding to the induction variable from
   // the header of |loop_1_| to the header of |loop_0_|.
-  std::vector<ir::Instruction*> instructions_to_move{};
+  std::vector<opt::Instruction*> instructions_to_move{};
   for (auto& instruction : *loop_1_->GetHeaderBlock()) {
     if (instruction.opcode() == SpvOpPhi && &instruction != induction_1_) {
       instructions_to_move.push_back(&instruction);
@@ -590,7 +590,7 @@
   }
 
   // Update the OpPhi parents to the correct blocks in |loop_0_|.
-  loop_0_->GetHeaderBlock()->ForEachPhiInst([this](ir::Instruction* i) {
+  loop_0_->GetHeaderBlock()->ForEachPhiInst([this](opt::Instruction* i) {
     ReplacePhiParentWith(i, loop_1_->GetPreHeaderBlock()->id(),
                          loop_0_->GetPreHeaderBlock()->id());
 
@@ -611,14 +611,14 @@
 
   // Replace LCSSA OpPhi in merge block of |loop_0_|.
   loop_0_->GetMergeBlock()->ForEachPhiInst(
-      [this](ir::Instruction* instruction) {
+      [this](opt::Instruction* instruction) {
         context_->ReplaceAllUsesWith(instruction->result_id(),
                                      instruction->GetSingleWordInOperand(0));
       });
 
   // Update LCSSA OpPhi in merge block of |loop_1_|.
   loop_1_->GetMergeBlock()->ForEachPhiInst(
-      [condition_block_of_0](ir::Instruction* instruction) {
+      [condition_block_of_0](opt::Instruction* instruction) {
         instruction->SetInOperand(1, {condition_block_of_0->id()});
       });
 
@@ -627,7 +627,7 @@
 
   // Gather all instructions to be killed from |loop_1_| (induction variable
   // initialisation, header, condition and continue blocks).
-  std::vector<ir::Instruction*> instr_to_delete{};
+  std::vector<opt::Instruction*> instr_to_delete{};
   AddInstructionsInBlock(&instr_to_delete, loop_1_->GetPreHeaderBlock());
   AddInstructionsInBlock(&instr_to_delete, loop_1_->GetHeaderBlock());
   AddInstructionsInBlock(&instr_to_delete, loop_1_->FindConditionBlock());
@@ -673,7 +673,7 @@
   auto ld = context_->GetLoopDescriptor(containing_function_);
 
   // Create a copy, so the iterator wouldn't be invalidated.
-  std::vector<ir::Loop*> loops_to_add_remove{};
+  std::vector<opt::Loop*> loops_to_add_remove{};
   for (auto child_loop : *loop_1_) {
     loops_to_add_remove.push_back(child_loop);
   }
@@ -722,10 +722,10 @@
 
   // Invalidate analyses.
   context_->InvalidateAnalysesExceptFor(
-      ir::IRContext::Analysis::kAnalysisInstrToBlockMapping |
-      ir::IRContext::Analysis::kAnalysisLoopAnalysis |
-      ir::IRContext::Analysis::kAnalysisDefUse |
-      ir::IRContext::Analysis::kAnalysisCFG);
+      opt::IRContext::Analysis::kAnalysisInstrToBlockMapping |
+      opt::IRContext::Analysis::kAnalysisLoopAnalysis |
+      opt::IRContext::Analysis::kAnalysisDefUse |
+      opt::IRContext::Analysis::kAnalysisCFG);
 }
 
 }  // namespace opt
diff --git a/source/opt/loop_fusion.h b/source/opt/loop_fusion.h
index c3efc7a..90f2bf0 100644
--- a/source/opt/loop_fusion.h
+++ b/source/opt/loop_fusion.h
@@ -29,7 +29,7 @@
 
 class LoopFusion {
  public:
-  LoopFusion(ir::IRContext* context, ir::Loop* loop_0, ir::Loop* loop_1)
+  LoopFusion(opt::IRContext* context, opt::Loop* loop_0, opt::Loop* loop_1)
       : context_(context),
         loop_0_(loop_0),
         loop_1_(loop_1),
@@ -70,42 +70,42 @@
 
   // Returns |true| if |instruction| is used in the continue or condition block
   // of |loop|.
-  bool UsedInContinueOrConditionBlock(ir::Instruction* instruction,
-                                      ir::Loop* loop);
+  bool UsedInContinueOrConditionBlock(opt::Instruction* instruction,
+                                      opt::Loop* loop);
 
   // Remove entries in |instructions| that are not used in the continue or
   // condition block of |loop|.
   void RemoveIfNotUsedContinueOrConditionBlock(
-      std::vector<ir::Instruction*>* instructions, ir::Loop* loop);
+      std::vector<opt::Instruction*>* instructions, opt::Loop* loop);
 
   // Returns |true| if |instruction| is used in |loop|.
-  bool IsUsedInLoop(ir::Instruction* instruction, ir::Loop* loop);
+  bool IsUsedInLoop(opt::Instruction* instruction, opt::Loop* loop);
 
   // Returns |true| if |loop| has at least one barrier or function call.
-  bool ContainsBarriersOrFunctionCalls(ir::Loop* loop);
+  bool ContainsBarriersOrFunctionCalls(opt::Loop* loop);
 
   // Get all instructions in the |loop| (except in the latch block) that have
   // the opcode |opcode|.
-  std::pair<std::vector<ir::Instruction*>, std::vector<ir::Instruction*>>
-  GetLoadsAndStoresInLoop(ir::Loop* loop);
+  std::pair<std::vector<opt::Instruction*>, std::vector<opt::Instruction*>>
+  GetLoadsAndStoresInLoop(opt::Loop* loop);
 
   // Given a vector of memory operations (OpLoad/OpStore), constructs a map from
   // variables to the loads/stores that those variables.
-  std::map<ir::Instruction*, std::vector<ir::Instruction*>> LocationToMemOps(
-      const std::vector<ir::Instruction*>& mem_ops);
+  std::map<opt::Instruction*, std::vector<opt::Instruction*>> LocationToMemOps(
+      const std::vector<opt::Instruction*>& mem_ops);
 
-  ir::IRContext* context_;
+  opt::IRContext* context_;
 
   // The original loops to be fused.
-  ir::Loop* loop_0_;
-  ir::Loop* loop_1_;
+  opt::Loop* loop_0_;
+  opt::Loop* loop_1_;
 
   // The function that contains |loop_0_| and |loop_1_|.
-  ir::Function* containing_function_ = nullptr;
+  opt::Function* containing_function_ = nullptr;
 
   // The induction variables for |loop_0_| and |loop_1_|.
-  ir::Instruction* induction_0_ = nullptr;
-  ir::Instruction* induction_1_ = nullptr;
+  opt::Instruction* induction_0_ = nullptr;
+  opt::Instruction* induction_1_ = nullptr;
 };
 
 }  // namespace opt
diff --git a/source/opt/loop_fusion_pass.cpp b/source/opt/loop_fusion_pass.cpp
index e891c88..fa7d487 100644
--- a/source/opt/loop_fusion_pass.cpp
+++ b/source/opt/loop_fusion_pass.cpp
@@ -22,21 +22,21 @@
 namespace spvtools {
 namespace opt {
 
-Pass::Status LoopFusionPass::Process(ir::IRContext* c) {
+Pass::Status LoopFusionPass::Process(opt::IRContext* c) {
   bool modified = false;
-  ir::Module* module = c->module();
+  opt::Module* module = c->module();
 
   // Process each function in the module
-  for (ir::Function& f : *module) {
+  for (opt::Function& f : *module) {
     modified |= ProcessFunction(&f);
   }
 
   return modified ? Status::SuccessWithChange : Status::SuccessWithoutChange;
 }
 
-bool LoopFusionPass::ProcessFunction(ir::Function* function) {
+bool LoopFusionPass::ProcessFunction(opt::Function* function) {
   auto c = function->context();
-  ir::LoopDescriptor& ld = *c->GetLoopDescriptor(function);
+  opt::LoopDescriptor& ld = *c->GetLoopDescriptor(function);
 
   // If a loop doesn't have a preheader needs then it needs to be created. Make
   // sure to return Status::SuccessWithChange in that case.
diff --git a/source/opt/loop_fusion_pass.h b/source/opt/loop_fusion_pass.h
index 868e9b5..b80cb24 100644
--- a/source/opt/loop_fusion_pass.h
+++ b/source/opt/loop_fusion_pass.h
@@ -34,12 +34,12 @@
   // Processes the given |module|. Returns Status::Failure if errors occur when
   // processing. Returns the corresponding Status::Success if processing is
   // succesful to indicate whether changes have been made to the modue.
-  Status Process(ir::IRContext* c) override;
+  Status Process(opt::IRContext* c) override;
 
  private:
   // Fuse loops in |function| if compatible, legal and the fused loop won't use
   // too many registers.
-  bool ProcessFunction(ir::Function* function);
+  bool ProcessFunction(opt::Function* function);
 
   // The maximum number of registers a fused loop is allowed to use.
   size_t max_registers_per_loop_;
diff --git a/source/opt/loop_peeling.cpp b/source/opt/loop_peeling.cpp
index 3da3a14..99a8869 100644
--- a/source/opt/loop_peeling.cpp
+++ b/source/opt/loop_peeling.cpp
@@ -33,20 +33,20 @@
 
 void LoopPeeling::DuplicateAndConnectLoop(
     LoopUtils::LoopCloningResult* clone_results) {
-  ir::CFG& cfg = *context_->cfg();
+  opt::CFG& cfg = *context_->cfg();
   analysis::DefUseManager* def_use_mgr = context_->get_def_use_mgr();
 
   assert(CanPeelLoop() && "Cannot peel loop!");
 
-  std::vector<ir::BasicBlock*> ordered_loop_blocks;
-  ir::BasicBlock* pre_header = loop_->GetOrCreatePreHeaderBlock();
+  std::vector<opt::BasicBlock*> ordered_loop_blocks;
+  opt::BasicBlock* pre_header = loop_->GetOrCreatePreHeaderBlock();
 
   loop_->ComputeLoopStructuredOrder(&ordered_loop_blocks);
 
   cloned_loop_ = loop_utils_.CloneLoop(clone_results, ordered_loop_blocks);
 
   // Add the basic block to the function.
-  ir::Function::iterator it =
+  opt::Function::iterator it =
       loop_utils_.GetFunction()->FindBlock(pre_header->id());
   assert(it != loop_utils_.GetFunction()->end() &&
          "Pre-header not found in the function.");
@@ -54,7 +54,7 @@
       clone_results->cloned_bb_.begin(), clone_results->cloned_bb_.end(), ++it);
 
   // Make the |loop_|'s preheader the |cloned_loop_| one.
-  ir::BasicBlock* cloned_header = cloned_loop_->GetHeaderBlock();
+  opt::BasicBlock* cloned_header = cloned_loop_->GetHeaderBlock();
   pre_header->ForEachSuccessorLabel(
       [cloned_header](uint32_t* succ) { *succ = cloned_header->id(); });
 
@@ -71,7 +71,7 @@
   uint32_t cloned_loop_exit = 0;
   for (uint32_t pred_id : cfg.preds(loop_->GetMergeBlock()->id())) {
     if (loop_->IsInsideLoop(pred_id)) continue;
-    ir::BasicBlock* bb = cfg.block(pred_id);
+    opt::BasicBlock* bb = cfg.block(pred_id);
     assert(cloned_loop_exit == 0 && "The loop has multiple exits.");
     cloned_loop_exit = bb->id();
     bb->ForEachSuccessorLabel([this](uint32_t* succ) {
@@ -116,7 +116,7 @@
   // }
   loop_->GetHeaderBlock()->ForEachPhiInst([cloned_loop_exit, def_use_mgr,
                                            clone_results,
-                                           this](ir::Instruction* phi) {
+                                           this](opt::Instruction* phi) {
     for (uint32_t i = 0; i < phi->NumInOperands(); i += 2) {
       if (!loop_->IsInsideLoop(phi->GetSingleWordInOperand(i + 1))) {
         phi->SetInOperand(i,
@@ -143,20 +143,20 @@
     return;
   }
 
-  ir::BasicBlock::iterator insert_point =
+  opt::BasicBlock::iterator insert_point =
       GetClonedLoop()->GetLatchBlock()->tail();
   if (GetClonedLoop()->GetLatchBlock()->GetMergeInst()) {
     --insert_point;
   }
   InstructionBuilder builder(context_, &*insert_point,
-                             ir::IRContext::kAnalysisDefUse |
-                                 ir::IRContext::kAnalysisInstrToBlockMapping);
-  ir::Instruction* uint_1_cst =
+                             opt::IRContext::kAnalysisDefUse |
+                                 opt::IRContext::kAnalysisInstrToBlockMapping);
+  opt::Instruction* uint_1_cst =
       builder.Add32BitConstantInteger<uint32_t>(1, int_type_->IsSigned());
   // Create the increment.
   // Note that we do "1 + 1" here, one of the operand should the phi
   // value but we don't have it yet. The operand will be set latter.
-  ir::Instruction* iv_inc = builder.AddIAdd(
+  opt::Instruction* iv_inc = builder.AddIAdd(
       uint_1_cst->type_id(), uint_1_cst->result_id(), uint_1_cst->result_id());
 
   builder.SetInsertPoint(&*GetClonedLoop()->GetHeaderBlock()->begin());
@@ -180,12 +180,12 @@
 }
 
 void LoopPeeling::GetIteratorUpdateOperations(
-    const ir::Loop* loop, ir::Instruction* iterator,
-    std::unordered_set<ir::Instruction*>* operations) {
+    const opt::Loop* loop, opt::Instruction* iterator,
+    std::unordered_set<opt::Instruction*>* operations) {
   opt::analysis::DefUseManager* def_use_mgr = context_->get_def_use_mgr();
   operations->insert(iterator);
   iterator->ForEachInId([def_use_mgr, loop, operations, this](uint32_t* id) {
-    ir::Instruction* insn = def_use_mgr->GetDef(*id);
+    opt::Instruction* insn = def_use_mgr->GetDef(*id);
     if (insn->opcode() == SpvOpLabel) {
       return;
     }
@@ -202,7 +202,7 @@
 // Gather the set of blocks for all the path from |entry| to |root|.
 static void GetBlocksInPath(uint32_t block, uint32_t entry,
                             std::unordered_set<uint32_t>* blocks_in_path,
-                            const ir::CFG& cfg) {
+                            const opt::CFG& cfg) {
   for (uint32_t pid : cfg.preds(block)) {
     if (blocks_in_path->insert(pid).second) {
       if (pid != entry) {
@@ -213,7 +213,7 @@
 }
 
 bool LoopPeeling::IsConditionCheckSideEffectFree() const {
-  ir::CFG& cfg = *context_->cfg();
+  opt::CFG& cfg = *context_->cfg();
 
   // The "do-while" form does not cause issues, the algorithm takes into account
   // the first iteration.
@@ -227,8 +227,8 @@
                     &blocks_in_path, cfg);
 
     for (uint32_t bb_id : blocks_in_path) {
-      ir::BasicBlock* bb = cfg.block(bb_id);
-      if (!bb->WhileEachInst([this](ir::Instruction* insn) {
+      opt::BasicBlock* bb = cfg.block(bb_id);
+      if (!bb->WhileEachInst([this](opt::Instruction* insn) {
             if (insn->IsBranch()) return true;
             switch (insn->opcode()) {
               case SpvOpLabel:
@@ -249,9 +249,9 @@
 }
 
 void LoopPeeling::GetIteratingExitValues() {
-  ir::CFG& cfg = *context_->cfg();
+  opt::CFG& cfg = *context_->cfg();
 
-  loop_->GetHeaderBlock()->ForEachPhiInst([this](ir::Instruction* phi) {
+  loop_->GetHeaderBlock()->ForEachPhiInst([this](opt::Instruction* phi) {
     exit_value_[phi->result_id()] = nullptr;
   });
 
@@ -270,8 +270,8 @@
                              condition_block_id) != header_pred.end();
   if (do_while_form_) {
     loop_->GetHeaderBlock()->ForEachPhiInst(
-        [condition_block_id, def_use_mgr, this](ir::Instruction* phi) {
-          std::unordered_set<ir::Instruction*> operations;
+        [condition_block_id, def_use_mgr, this](opt::Instruction* phi) {
+          std::unordered_set<opt::Instruction*> operations;
 
           for (uint32_t i = 0; i < phi->NumInOperands(); i += 2) {
             if (condition_block_id == phi->GetSingleWordInOperand(i + 1)) {
@@ -284,17 +284,17 @@
     DominatorTree* dom_tree =
         &context_->GetDominatorAnalysis(loop_utils_.GetFunction())
              ->GetDomTree();
-    ir::BasicBlock* condition_block = cfg.block(condition_block_id);
+    opt::BasicBlock* condition_block = cfg.block(condition_block_id);
 
     loop_->GetHeaderBlock()->ForEachPhiInst(
-        [dom_tree, condition_block, this](ir::Instruction* phi) {
-          std::unordered_set<ir::Instruction*> operations;
+        [dom_tree, condition_block, this](opt::Instruction* phi) {
+          std::unordered_set<opt::Instruction*> operations;
 
           // Not the back-edge value, check if the phi instruction is the only
           // possible candidate.
           GetIteratorUpdateOperations(loop_, phi, &operations);
 
-          for (ir::Instruction* insn : operations) {
+          for (opt::Instruction* insn : operations) {
             if (insn == phi) {
               continue;
             }
@@ -309,8 +309,8 @@
 }
 
 void LoopPeeling::FixExitCondition(
-    const std::function<uint32_t(ir::Instruction*)>& condition_builder) {
-  ir::CFG& cfg = *context_->cfg();
+    const std::function<uint32_t(opt::Instruction*)>& condition_builder) {
+  opt::CFG& cfg = *context_->cfg();
 
   uint32_t condition_block_id = 0;
   for (uint32_t id : cfg.preds(GetClonedLoop()->GetMergeBlock()->id())) {
@@ -321,10 +321,10 @@
   }
   assert(condition_block_id != 0 && "2nd loop in improperly connected");
 
-  ir::BasicBlock* condition_block = cfg.block(condition_block_id);
-  ir::Instruction* exit_condition = condition_block->terminator();
+  opt::BasicBlock* condition_block = cfg.block(condition_block_id);
+  opt::Instruction* exit_condition = condition_block->terminator();
   assert(exit_condition->opcode() == SpvOpBranchConditional);
-  ir::BasicBlock::iterator insert_point = condition_block->tail();
+  opt::BasicBlock::iterator insert_point = condition_block->tail();
   if (condition_block->GetMergeInst()) {
     --insert_point;
   }
@@ -343,17 +343,17 @@
   context_->get_def_use_mgr()->AnalyzeInstUse(exit_condition);
 }
 
-ir::BasicBlock* LoopPeeling::CreateBlockBefore(ir::BasicBlock* bb) {
+opt::BasicBlock* LoopPeeling::CreateBlockBefore(opt::BasicBlock* bb) {
   analysis::DefUseManager* def_use_mgr = context_->get_def_use_mgr();
-  ir::CFG& cfg = *context_->cfg();
+  opt::CFG& cfg = *context_->cfg();
   assert(cfg.preds(bb->id()).size() == 1 && "More than one predecessor");
 
-  std::unique_ptr<ir::BasicBlock> new_bb = MakeUnique<ir::BasicBlock>(
-      std::unique_ptr<ir::Instruction>(new ir::Instruction(
+  std::unique_ptr<opt::BasicBlock> new_bb = MakeUnique<opt::BasicBlock>(
+      std::unique_ptr<opt::Instruction>(new opt::Instruction(
           context_, SpvOpLabel, 0, context_->TakeNextId(), {})));
   new_bb->SetParent(loop_utils_.GetFunction());
   // Update the loop descriptor.
-  ir::Loop* in_loop = (*loop_utils_.GetLoopDescriptor())[bb];
+  opt::Loop* in_loop = (*loop_utils_.GetLoopDescriptor())[bb];
   if (in_loop) {
     in_loop->AddBasicBlock(new_bb.get());
     loop_utils_.GetLoopDescriptor()->SetBasicBlockToLoop(new_bb->id(), in_loop);
@@ -362,7 +362,7 @@
   context_->set_instr_block(new_bb->GetLabelInst(), new_bb.get());
   def_use_mgr->AnalyzeInstDefUse(new_bb->GetLabelInst());
 
-  ir::BasicBlock* bb_pred = cfg.block(cfg.preds(bb->id())[0]);
+  opt::BasicBlock* bb_pred = cfg.block(cfg.preds(bb->id())[0]);
   bb_pred->tail()->ForEachInId([bb, &new_bb](uint32_t* id) {
     if (*id == bb->id()) {
       *id = new_bb->id();
@@ -373,37 +373,37 @@
   def_use_mgr->AnalyzeInstUse(&*bb_pred->tail());
 
   // Update the incoming branch.
-  bb->ForEachPhiInst([&new_bb, def_use_mgr](ir::Instruction* phi) {
+  bb->ForEachPhiInst([&new_bb, def_use_mgr](opt::Instruction* phi) {
     phi->SetInOperand(1, {new_bb->id()});
     def_use_mgr->AnalyzeInstUse(phi);
   });
   InstructionBuilder(context_, new_bb.get(),
-                     ir::IRContext::kAnalysisDefUse |
-                         ir::IRContext::kAnalysisInstrToBlockMapping)
+                     opt::IRContext::kAnalysisDefUse |
+                         opt::IRContext::kAnalysisInstrToBlockMapping)
       .AddBranch(bb->id());
   cfg.RegisterBlock(new_bb.get());
 
   // Add the basic block to the function.
-  ir::Function::iterator it = loop_utils_.GetFunction()->FindBlock(bb->id());
+  opt::Function::iterator it = loop_utils_.GetFunction()->FindBlock(bb->id());
   assert(it != loop_utils_.GetFunction()->end() &&
          "Basic block not found in the function.");
-  ir::BasicBlock* ret = new_bb.get();
+  opt::BasicBlock* ret = new_bb.get();
   loop_utils_.GetFunction()->AddBasicBlock(std::move(new_bb), it);
   return ret;
 }
 
-ir::BasicBlock* LoopPeeling::ProtectLoop(ir::Loop* loop,
-                                         ir::Instruction* condition,
-                                         ir::BasicBlock* if_merge) {
-  ir::BasicBlock* if_block = loop->GetOrCreatePreHeaderBlock();
+opt::BasicBlock* LoopPeeling::ProtectLoop(opt::Loop* loop,
+                                          opt::Instruction* condition,
+                                          opt::BasicBlock* if_merge) {
+  opt::BasicBlock* if_block = loop->GetOrCreatePreHeaderBlock();
   // Will no longer be a pre-header because of the if.
   loop->SetPreHeaderBlock(nullptr);
   // Kill the branch to the header.
   context_->KillInst(&*if_block->tail());
 
   InstructionBuilder builder(context_, if_block,
-                             ir::IRContext::kAnalysisDefUse |
-                                 ir::IRContext::kAnalysisInstrToBlockMapping);
+                             opt::IRContext::kAnalysisDefUse |
+                                 opt::IRContext::kAnalysisInstrToBlockMapping);
   builder.AddConditionalBranch(condition->result_id(),
                                loop->GetHeaderBlock()->id(), if_merge->id(),
                                if_merge->id());
@@ -423,24 +423,25 @@
 
   InstructionBuilder builder(context_,
                              &*cloned_loop_->GetPreHeaderBlock()->tail(),
-                             ir::IRContext::kAnalysisDefUse |
-                                 ir::IRContext::kAnalysisInstrToBlockMapping);
-  ir::Instruction* factor =
+                             opt::IRContext::kAnalysisDefUse |
+                                 opt::IRContext::kAnalysisInstrToBlockMapping);
+  opt::Instruction* factor =
       builder.Add32BitConstantInteger(peel_factor, int_type_->IsSigned());
 
-  ir::Instruction* has_remaining_iteration = builder.AddLessThan(
+  opt::Instruction* has_remaining_iteration = builder.AddLessThan(
       factor->result_id(), loop_iteration_count_->result_id());
-  ir::Instruction* max_iteration = builder.AddSelect(
+  opt::Instruction* max_iteration = builder.AddSelect(
       factor->type_id(), has_remaining_iteration->result_id(),
       factor->result_id(), loop_iteration_count_->result_id());
 
   // Change the exit condition of the cloned loop to be (exit when become
   // false):
   //  "canonical_induction_variable_" < min("factor", "loop_iteration_count_")
-  FixExitCondition([max_iteration, this](ir::Instruction* insert_before_point) {
+  FixExitCondition([max_iteration,
+                    this](opt::Instruction* insert_before_point) {
     return InstructionBuilder(context_, insert_before_point,
-                              ir::IRContext::kAnalysisDefUse |
-                                  ir::IRContext::kAnalysisInstrToBlockMapping)
+                              opt::IRContext::kAnalysisDefUse |
+                                  opt::IRContext::kAnalysisInstrToBlockMapping)
         .AddLessThan(canonical_induction_variable_->result_id(),
                      max_iteration->result_id())
         ->result_id();
@@ -448,15 +449,15 @@
 
   // "Protect" the second loop: the second loop can only be executed if
   // |has_remaining_iteration| is true (i.e. factor < loop_iteration_count_).
-  ir::BasicBlock* if_merge_block = loop_->GetMergeBlock();
+  opt::BasicBlock* if_merge_block = loop_->GetMergeBlock();
   loop_->SetMergeBlock(CreateBlockBefore(loop_->GetMergeBlock()));
   // Prevent the second loop from being executed if we already executed all the
   // required iterations.
-  ir::BasicBlock* if_block =
+  opt::BasicBlock* if_block =
       ProtectLoop(loop_, has_remaining_iteration, if_merge_block);
   // Patch the phi of the merge block.
   if_merge_block->ForEachPhiInst(
-      [&clone_results, if_block, this](ir::Instruction* phi) {
+      [&clone_results, if_block, this](opt::Instruction* phi) {
         // if_merge_block had previously only 1 predecessor.
         uint32_t incoming_value = phi->GetSingleWordInOperand(0);
         auto def_in_loop = clone_results.value_map_.find(incoming_value);
@@ -470,9 +471,9 @@
       });
 
   context_->InvalidateAnalysesExceptFor(
-      ir::IRContext::kAnalysisDefUse |
-      ir::IRContext::kAnalysisInstrToBlockMapping |
-      ir::IRContext::kAnalysisLoopAnalysis | ir::IRContext::kAnalysisCFG);
+      opt::IRContext::kAnalysisDefUse |
+      opt::IRContext::kAnalysisInstrToBlockMapping |
+      opt::IRContext::kAnalysisLoopAnalysis | opt::IRContext::kAnalysisCFG);
 }
 
 void LoopPeeling::PeelAfter(uint32_t peel_factor) {
@@ -487,22 +488,22 @@
 
   InstructionBuilder builder(context_,
                              &*cloned_loop_->GetPreHeaderBlock()->tail(),
-                             ir::IRContext::kAnalysisDefUse |
-                                 ir::IRContext::kAnalysisInstrToBlockMapping);
-  ir::Instruction* factor =
+                             opt::IRContext::kAnalysisDefUse |
+                                 opt::IRContext::kAnalysisInstrToBlockMapping);
+  opt::Instruction* factor =
       builder.Add32BitConstantInteger(peel_factor, int_type_->IsSigned());
 
-  ir::Instruction* has_remaining_iteration = builder.AddLessThan(
+  opt::Instruction* has_remaining_iteration = builder.AddLessThan(
       factor->result_id(), loop_iteration_count_->result_id());
 
   // Change the exit condition of the cloned loop to be (exit when become
   // false):
   //  "canonical_induction_variable_" + "factor" < "loop_iteration_count_"
-  FixExitCondition([factor, this](ir::Instruction* insert_before_point) {
+  FixExitCondition([factor, this](opt::Instruction* insert_before_point) {
     InstructionBuilder cond_builder(
         context_, insert_before_point,
-        ir::IRContext::kAnalysisDefUse |
-            ir::IRContext::kAnalysisInstrToBlockMapping);
+        opt::IRContext::kAnalysisDefUse |
+            opt::IRContext::kAnalysisInstrToBlockMapping);
     // Build the following check: canonical_induction_variable_ + factor <
     // iteration_count
     return cond_builder
@@ -524,7 +525,7 @@
   // Use the second loop preheader as if merge block.
 
   // Prevent the first loop if only the peeled loop needs it.
-  ir::BasicBlock* if_block =
+  opt::BasicBlock* if_block =
       ProtectLoop(cloned_loop_, has_remaining_iteration,
                   GetOriginalLoop()->GetPreHeaderBlock());
 
@@ -535,25 +536,25 @@
   // We had to the preheader (our if merge block) the required phi instruction
   // and patch the header phi.
   GetOriginalLoop()->GetHeaderBlock()->ForEachPhiInst(
-      [&clone_results, if_block, this](ir::Instruction* phi) {
+      [&clone_results, if_block, this](opt::Instruction* phi) {
         opt::analysis::DefUseManager* def_use_mgr = context_->get_def_use_mgr();
 
-        auto find_value_idx = [](ir::Instruction* phi_inst, ir::Loop* loop) {
+        auto find_value_idx = [](opt::Instruction* phi_inst, opt::Loop* loop) {
           uint32_t preheader_value_idx =
               !loop->IsInsideLoop(phi_inst->GetSingleWordInOperand(1)) ? 0 : 2;
           return preheader_value_idx;
         };
 
-        ir::Instruction* cloned_phi =
+        opt::Instruction* cloned_phi =
             def_use_mgr->GetDef(clone_results.value_map_.at(phi->result_id()));
         uint32_t cloned_preheader_value = cloned_phi->GetSingleWordInOperand(
             find_value_idx(cloned_phi, GetClonedLoop()));
 
-        ir::Instruction* new_phi =
+        opt::Instruction* new_phi =
             InstructionBuilder(context_,
                                &*GetOriginalLoop()->GetPreHeaderBlock()->tail(),
-                               ir::IRContext::kAnalysisDefUse |
-                                   ir::IRContext::kAnalysisInstrToBlockMapping)
+                               opt::IRContext::kAnalysisDefUse |
+                                   opt::IRContext::kAnalysisInstrToBlockMapping)
                 .AddPhi(phi->type_id(),
                         {phi->GetSingleWordInOperand(
                              find_value_idx(phi, GetOriginalLoop())),
@@ -566,49 +567,49 @@
       });
 
   context_->InvalidateAnalysesExceptFor(
-      ir::IRContext::kAnalysisDefUse |
-      ir::IRContext::kAnalysisInstrToBlockMapping |
-      ir::IRContext::kAnalysisLoopAnalysis | ir::IRContext::kAnalysisCFG);
+      opt::IRContext::kAnalysisDefUse |
+      opt::IRContext::kAnalysisInstrToBlockMapping |
+      opt::IRContext::kAnalysisLoopAnalysis | opt::IRContext::kAnalysisCFG);
 }
 
-Pass::Status LoopPeelingPass::Process(ir::IRContext* c) {
+Pass::Status LoopPeelingPass::Process(opt::IRContext* c) {
   InitializeProcessing(c);
 
   bool modified = false;
-  ir::Module* module = c->module();
+  opt::Module* module = c->module();
 
   // Process each function in the module
-  for (ir::Function& f : *module) {
+  for (opt::Function& f : *module) {
     modified |= ProcessFunction(&f);
   }
 
   return modified ? Status::SuccessWithChange : Status::SuccessWithoutChange;
 }
 
-bool LoopPeelingPass::ProcessFunction(ir::Function* f) {
+bool LoopPeelingPass::ProcessFunction(opt::Function* f) {
   bool modified = false;
-  ir::LoopDescriptor& loop_descriptor = *context()->GetLoopDescriptor(f);
+  opt::LoopDescriptor& loop_descriptor = *context()->GetLoopDescriptor(f);
 
-  std::vector<ir::Loop*> to_process_loop;
+  std::vector<opt::Loop*> to_process_loop;
   to_process_loop.reserve(loop_descriptor.NumLoops());
-  for (ir::Loop& l : loop_descriptor) {
+  for (opt::Loop& l : loop_descriptor) {
     to_process_loop.push_back(&l);
   }
 
   opt::ScalarEvolutionAnalysis scev_analysis(context());
 
-  for (ir::Loop* loop : to_process_loop) {
+  for (opt::Loop* loop : to_process_loop) {
     CodeMetrics loop_size;
     loop_size.Analyze(*loop);
 
     auto try_peel = [&loop_size, &modified,
-                     this](ir::Loop* loop_to_peel) -> ir::Loop* {
+                     this](opt::Loop* loop_to_peel) -> opt::Loop* {
       if (!loop_to_peel->IsLCSSA()) {
         LoopUtils(context(), loop_to_peel).MakeLoopClosedSSA();
       }
 
       bool peeled_loop;
-      ir::Loop* still_peelable_loop;
+      opt::Loop* still_peelable_loop;
       std::tie(peeled_loop, still_peelable_loop) =
           ProcessLoop(loop_to_peel, &loop_size);
 
@@ -619,7 +620,7 @@
       return still_peelable_loop;
     };
 
-    ir::Loop* still_peelable_loop = try_peel(loop);
+    opt::Loop* still_peelable_loop = try_peel(loop);
     // The pass is working out the maximum factor by which a loop can be peeled.
     // If the loop can potentially be peeled again, then there is only one
     // possible direction, so only one call is still needed.
@@ -631,19 +632,19 @@
   return modified;
 }
 
-std::pair<bool, ir::Loop*> LoopPeelingPass::ProcessLoop(
-    ir::Loop* loop, CodeMetrics* loop_size) {
+std::pair<bool, opt::Loop*> LoopPeelingPass::ProcessLoop(
+    opt::Loop* loop, CodeMetrics* loop_size) {
   opt::ScalarEvolutionAnalysis* scev_analysis =
       context()->GetScalarEvolutionAnalysis();
   // Default values for bailing out.
-  std::pair<bool, ir::Loop*> bail_out{false, nullptr};
+  std::pair<bool, opt::Loop*> bail_out{false, nullptr};
 
-  ir::BasicBlock* exit_block = loop->FindConditionBlock();
+  opt::BasicBlock* exit_block = loop->FindConditionBlock();
   if (!exit_block) {
     return bail_out;
   }
 
-  ir::Instruction* exiting_iv = loop->FindConditionVariable(exit_block);
+  opt::Instruction* exiting_iv = loop->FindConditionVariable(exit_block);
   if (!exiting_iv) {
     return bail_out;
   }
@@ -656,11 +657,11 @@
     return bail_out;
   }
 
-  ir::Instruction* canonical_induction_variable = nullptr;
+  opt::Instruction* canonical_induction_variable = nullptr;
 
   loop->GetHeaderBlock()->WhileEachPhiInst([&canonical_induction_variable,
                                             scev_analysis,
-                                            this](ir::Instruction* insn) {
+                                            this](opt::Instruction* insn) {
     if (const SERecurrentNode* iv =
             scev_analysis->AnalyzeInstruction(insn)->AsSERecurrentNode()) {
       const SEConstantNode* offset = iv->GetOffset()->AsSEConstantNode();
@@ -687,8 +688,8 @@
   LoopPeeling peeler(
       loop,
       InstructionBuilder(context(), loop->GetHeaderBlock(),
-                         ir::IRContext::kAnalysisDefUse |
-                             ir::IRContext::kAnalysisInstrToBlockMapping)
+                         opt::IRContext::kAnalysisDefUse |
+                             opt::IRContext::kAnalysisInstrToBlockMapping)
           .Add32BitConstantInteger<uint32_t>(static_cast<uint32_t>(iterations),
                                              is_signed),
       canonical_induction_variable);
@@ -708,7 +709,7 @@
     if (block == exit_block->id()) {
       continue;
     }
-    ir::BasicBlock* bb = cfg()->block(block);
+    opt::BasicBlock* bb = cfg()->block(block);
     PeelDirection direction;
     uint32_t factor;
     std::tie(direction, factor) = peel_info.GetPeelingInfo(bb);
@@ -750,7 +751,7 @@
   loop_size->roi_size_ *= factor;
 
   // Find if a loop should be peeled again.
-  ir::Loop* extra_opportunity = nullptr;
+  opt::Loop* extra_opportunity = nullptr;
 
   if (direction == PeelDirection::kBefore) {
     peeler.PeelBefore(factor);
@@ -776,9 +777,9 @@
 }
 
 uint32_t LoopPeelingPass::LoopPeelingInfo::GetFirstLoopInvariantOperand(
-    ir::Instruction* condition) const {
+    opt::Instruction* condition) const {
   for (uint32_t i = 0; i < condition->NumInOperands(); i++) {
-    ir::BasicBlock* bb =
+    opt::BasicBlock* bb =
         context_->get_instr_block(condition->GetSingleWordInOperand(i));
     if (bb && loop_->IsInsideLoop(bb)) {
       return condition->GetSingleWordInOperand(i);
@@ -789,9 +790,9 @@
 }
 
 uint32_t LoopPeelingPass::LoopPeelingInfo::GetFirstNonLoopInvariantOperand(
-    ir::Instruction* condition) const {
+    opt::Instruction* condition) const {
   for (uint32_t i = 0; i < condition->NumInOperands(); i++) {
-    ir::BasicBlock* bb =
+    opt::BasicBlock* bb =
         context_->get_instr_block(condition->GetSingleWordInOperand(i));
     if (!bb || !loop_->IsInsideLoop(bb)) {
       return condition->GetSingleWordInOperand(i);
@@ -820,14 +821,14 @@
 }
 
 LoopPeelingPass::LoopPeelingInfo::Direction
-LoopPeelingPass::LoopPeelingInfo::GetPeelingInfo(ir::BasicBlock* bb) const {
+LoopPeelingPass::LoopPeelingInfo::GetPeelingInfo(opt::BasicBlock* bb) const {
   if (bb->terminator()->opcode() != SpvOpBranchConditional) {
     return GetNoneDirection();
   }
 
   opt::analysis::DefUseManager* def_use_mgr = context_->get_def_use_mgr();
 
-  ir::Instruction* condition =
+  opt::Instruction* condition =
       def_use_mgr->GetDef(bb->terminator()->GetSingleWordInOperand(0));
 
   if (!IsHandledCondition(condition->opcode())) {
diff --git a/source/opt/loop_peeling.h b/source/opt/loop_peeling.h
index 6f10825..b160ab1 100644
--- a/source/opt/loop_peeling.h
+++ b/source/opt/loop_peeling.h
@@ -75,8 +75,8 @@
   // |loop_iteration_count| and start at 0 and increase by step of one at each
   // iteration. The value nullptr is interpreted as no suitable variable exists
   // and one will be created.
-  LoopPeeling(ir::Loop* loop, ir::Instruction* loop_iteration_count,
-              ir::Instruction* canonical_induction_variable = nullptr)
+  LoopPeeling(opt::Loop* loop, opt::Instruction* loop_iteration_count,
+              opt::Instruction* canonical_induction_variable = nullptr)
       : context_(loop->GetContext()),
         loop_utils_(loop->GetContext(), loop),
         loop_(loop),
@@ -115,7 +115,7 @@
   // This restriction will not apply if a loop rotate is applied before (i.e.
   // becomes a do-while loop).
   bool CanPeelLoop() const {
-    ir::CFG& cfg = *context_->cfg();
+    opt::CFG& cfg = *context_->cfg();
 
     if (!loop_iteration_count_) {
       return false;
@@ -140,7 +140,7 @@
     }
 
     return !std::any_of(exit_value_.cbegin(), exit_value_.cend(),
-                        [](std::pair<uint32_t, ir::Instruction*> it) {
+                        [](std::pair<uint32_t, opt::Instruction*> it) {
                           return it.second == nullptr;
                         });
   }
@@ -154,31 +154,31 @@
   void PeelAfter(uint32_t factor);
 
   // Returns the cloned loop.
-  ir::Loop* GetClonedLoop() { return cloned_loop_; }
+  opt::Loop* GetClonedLoop() { return cloned_loop_; }
   // Returns the original loop.
-  ir::Loop* GetOriginalLoop() { return loop_; }
+  opt::Loop* GetOriginalLoop() { return loop_; }
 
  private:
-  ir::IRContext* context_;
+  opt::IRContext* context_;
   LoopUtils loop_utils_;
   // The original loop.
-  ir::Loop* loop_;
+  opt::Loop* loop_;
   // The initial |loop_| upper bound.
-  ir::Instruction* loop_iteration_count_;
+  opt::Instruction* loop_iteration_count_;
   // The int type to use for the canonical_induction_variable_.
   analysis::Integer* int_type_;
   // The cloned loop.
-  ir::Loop* cloned_loop_;
+  opt::Loop* cloned_loop_;
   // This is set to true when the exit and back-edge branch instruction is the
   // same.
   bool do_while_form_;
   // The canonical induction variable from the original loop if it exists.
-  ir::Instruction* original_loop_canonical_induction_variable_;
+  opt::Instruction* original_loop_canonical_induction_variable_;
   // The canonical induction variable of the cloned loop. The induction variable
   // is initialized to 0 and incremented by step of 1.
-  ir::Instruction* canonical_induction_variable_;
+  opt::Instruction* canonical_induction_variable_;
   // Map between loop iterators and exit values. Loop iterators
-  std::unordered_map<uint32_t, ir::Instruction*> exit_value_;
+  std::unordered_map<uint32_t, opt::Instruction*> exit_value_;
 
   // Duplicate |loop_| and place the new loop before the cloned loop. Iterating
   // values from the cloned loop are then connected to the original loop as
@@ -193,16 +193,16 @@
   // Fixes the exit condition of the before loop. The function calls
   // |condition_builder| to get the condition to use in the conditional branch
   // of the loop exit. The loop will be exited if the condition evaluate to
-  // true. |condition_builder| takes an ir::Instruction* that represent the
+  // true. |condition_builder| takes an opt::Instruction* that represent the
   // insertion point.
   void FixExitCondition(
-      const std::function<uint32_t(ir::Instruction*)>& condition_builder);
+      const std::function<uint32_t(opt::Instruction*)>& condition_builder);
 
   // Gathers all operations involved in the update of |iterator| into
   // |operations|.
   void GetIteratorUpdateOperations(
-      const ir::Loop* loop, ir::Instruction* iterator,
-      std::unordered_set<ir::Instruction*>* operations);
+      const opt::Loop* loop, opt::Instruction* iterator,
+      std::unordered_set<opt::Instruction*>* operations);
 
   // Gathers exiting iterator values. The function builds a map between each
   // iterating value in the loop (a phi instruction in the loop header) and its
@@ -216,14 +216,14 @@
 
   // Creates a new basic block and insert it between |bb| and the predecessor of
   // |bb|.
-  ir::BasicBlock* CreateBlockBefore(ir::BasicBlock* bb);
+  opt::BasicBlock* CreateBlockBefore(opt::BasicBlock* bb);
 
   // Inserts code to only execute |loop| only if the given |condition| is true.
   // |if_merge| is a suitable basic block to be used by the if condition as
   // merge block.
   // The function returns the if block protecting the loop.
-  ir::BasicBlock* ProtectLoop(ir::Loop* loop, ir::Instruction* condition,
-                              ir::BasicBlock* if_merge);
+  opt::BasicBlock* ProtectLoop(opt::Loop* loop, opt::Instruction* condition,
+                               opt::BasicBlock* if_merge);
 };
 
 // Implements a loop peeling optimization.
@@ -241,7 +241,7 @@
 
   // Holds some statistics about peeled function.
   struct LoopPeelingStats {
-    std::vector<std::tuple<const ir::Loop*, PeelDirection, uint32_t>>
+    std::vector<std::tuple<const opt::Loop*, PeelDirection, uint32_t>>
         peeled_loops_;
   };
 
@@ -262,7 +262,7 @@
   // Processes the given |module|. Returns Status::Failure if errors occur when
   // processing. Returns the corresponding Status::Success if processing is
   // succesful to indicate whether changes have been made to the modue.
-  Pass::Status Process(ir::IRContext* context) override;
+  Pass::Status Process(opt::IRContext* context) override;
 
  private:
   // Describes the peeling direction.
@@ -277,7 +277,7 @@
    public:
     using Direction = std::pair<PeelDirection, uint32_t>;
 
-    LoopPeelingInfo(ir::Loop* loop, size_t loop_max_iterations,
+    LoopPeelingInfo(opt::Loop* loop, size_t loop_max_iterations,
                     opt::ScalarEvolutionAnalysis* scev_analysis)
         : context_(loop->GetContext()),
           loop_(loop),
@@ -288,15 +288,15 @@
     // make the conditional branch of the basic block |bb| an unconditional
     // branch. If |bb|'s terminator is not a conditional branch or the condition
     // is not workable then it returns PeelDirection::kNone and a 0 factor.
-    Direction GetPeelingInfo(ir::BasicBlock* bb) const;
+    Direction GetPeelingInfo(opt::BasicBlock* bb) const;
 
    private:
     // Returns the id of the loop invariant operand of the conditional
     // expression |condition|. It returns if no operand is invariant.
-    uint32_t GetFirstLoopInvariantOperand(ir::Instruction* condition) const;
+    uint32_t GetFirstLoopInvariantOperand(opt::Instruction* condition) const;
     // Returns the id of the non loop invariant operand of the conditional
     // expression |condition|. It returns if all operands are invariant.
-    uint32_t GetFirstNonLoopInvariantOperand(ir::Instruction* condition) const;
+    uint32_t GetFirstNonLoopInvariantOperand(opt::Instruction* condition) const;
 
     // Returns the value of |rec| at the first loop iteration.
     SExpression GetValueAtFirstIteration(SERecurrentNode* rec) const;
@@ -316,16 +316,16 @@
     static Direction GetNoneDirection() {
       return Direction{LoopPeelingPass::PeelDirection::kNone, 0};
     }
-    ir::IRContext* context_;
-    ir::Loop* loop_;
+    opt::IRContext* context_;
+    opt::Loop* loop_;
     opt::ScalarEvolutionAnalysis* scev_analysis_;
     size_t loop_max_iterations_;
   };
   // Peel profitable loops in |f|.
-  bool ProcessFunction(ir::Function* f);
+  bool ProcessFunction(opt::Function* f);
   // Peel |loop| if profitable.
-  std::pair<bool, ir::Loop*> ProcessLoop(ir::Loop* loop,
-                                         CodeMetrics* loop_size);
+  std::pair<bool, opt::Loop*> ProcessLoop(opt::Loop* loop,
+                                          CodeMetrics* loop_size);
 
   static size_t code_grow_threshold_;
   LoopPeelingStats* stats_;
diff --git a/source/opt/loop_unroller.cpp b/source/opt/loop_unroller.cpp
index 3006b32..57133f7 100644
--- a/source/opt/loop_unroller.cpp
+++ b/source/opt/loop_unroller.cpp
@@ -84,9 +84,9 @@
         new_header_block(nullptr) {}
 
   // Initialize from the loop descriptor class.
-  LoopUnrollState(ir::Instruction* induction, ir::BasicBlock* latch_block,
-                  ir::BasicBlock* condition,
-                  std::vector<ir::Instruction*>&& phis)
+  LoopUnrollState(opt::Instruction* induction, opt::BasicBlock* latch_block,
+                  opt::BasicBlock* condition,
+                  std::vector<opt::Instruction*>&& phis)
       : previous_phi_(induction),
         previous_latch_block_(latch_block),
         previous_condition_block_(condition),
@@ -118,53 +118,53 @@
   }
 
   // The induction variable from the immediately preceding loop body.
-  ir::Instruction* previous_phi_;
+  opt::Instruction* previous_phi_;
 
   // All the phi nodes from the previous loop iteration.
-  std::vector<ir::Instruction*> previous_phis_;
+  std::vector<opt::Instruction*> previous_phis_;
 
-  std::vector<ir::Instruction*> new_phis_;
+  std::vector<opt::Instruction*> new_phis_;
 
   // The previous latch block. The backedge will be removed from this and
   // added to the new latch block.
-  ir::BasicBlock* previous_latch_block_;
+  opt::BasicBlock* previous_latch_block_;
 
   // The previous condition block. This may be folded to flatten the loop.
-  ir::BasicBlock* previous_condition_block_;
+  opt::BasicBlock* previous_condition_block_;
 
   // The new induction variable.
-  ir::Instruction* new_phi;
+  opt::Instruction* new_phi;
 
   // The new continue block.
-  ir::BasicBlock* new_continue_block;
+  opt::BasicBlock* new_continue_block;
 
   // The new condition block.
-  ir::BasicBlock* new_condition_block;
+  opt::BasicBlock* new_condition_block;
 
   // The new header block.
-  ir::BasicBlock* new_header_block;
+  opt::BasicBlock* new_header_block;
 
   // The new latch block.
-  ir::BasicBlock* new_latch_block;
+  opt::BasicBlock* new_latch_block;
 
   // A mapping of new block ids to the original blocks which they were copied
   // from.
-  std::unordered_map<uint32_t, ir::BasicBlock*> new_blocks;
+  std::unordered_map<uint32_t, opt::BasicBlock*> new_blocks;
 
   // A mapping of the original instruction ids to the instruction ids to their
   // copies.
   std::unordered_map<uint32_t, uint32_t> new_inst;
 
-  std::unordered_map<uint32_t, ir::Instruction*> ids_to_new_inst;
+  std::unordered_map<uint32_t, opt::Instruction*> ids_to_new_inst;
 };
 
 // This class implements the actual unrolling. It uses a LoopUnrollState to
 // maintain the state of the unrolling inbetween steps.
 class LoopUnrollerUtilsImpl {
  public:
-  using BasicBlockListTy = std::vector<std::unique_ptr<ir::BasicBlock>>;
+  using BasicBlockListTy = std::vector<std::unique_ptr<opt::BasicBlock>>;
 
-  LoopUnrollerUtilsImpl(ir::IRContext* c, ir::Function* function)
+  LoopUnrollerUtilsImpl(opt::IRContext* c, opt::Function* function)
       : context_(c),
         function_(*function),
         loop_condition_block_(nullptr),
@@ -175,7 +175,7 @@
 
   // Unroll the |loop| by given |factor| by copying the whole body |factor|
   // times. The resulting basicblock structure will remain a loop.
-  void PartiallyUnroll(ir::Loop*, size_t factor);
+  void PartiallyUnroll(opt::Loop*, size_t factor);
 
   // If partially unrolling the |loop| would leave the loop with too many bodies
   // for its number of iterations then this method should be used. This method
@@ -183,131 +183,131 @@
   // successor of the original's merge block. The original loop will have its
   // condition changed to loop over the residual part and the duplicate will be
   // partially unrolled. The resulting structure will be two loops.
-  void PartiallyUnrollResidualFactor(ir::Loop* loop, size_t factor);
+  void PartiallyUnrollResidualFactor(opt::Loop* loop, size_t factor);
 
   // Fully unroll the |loop| by copying the full body by the total number of
   // loop iterations, folding all conditions, and removing the backedge from the
   // continue block to the header.
-  void FullyUnroll(ir::Loop* loop);
+  void FullyUnroll(opt::Loop* loop);
 
   // Get the ID of the variable in the |phi| paired with |label|.
-  uint32_t GetPhiDefID(const ir::Instruction* phi, uint32_t label) const;
+  uint32_t GetPhiDefID(const opt::Instruction* phi, uint32_t label) const;
 
   // Close the loop by removing the OpLoopMerge from the |loop| header block and
   // making the backedge point to the merge block.
-  void CloseUnrolledLoop(ir::Loop* loop);
+  void CloseUnrolledLoop(opt::Loop* loop);
 
   // Remove the OpConditionalBranch instruction inside |conditional_block| used
   // to branch to either exit or continue the loop and replace it with an
   // unconditional OpBranch to block |new_target|.
-  void FoldConditionBlock(ir::BasicBlock* condtion_block, uint32_t new_target);
+  void FoldConditionBlock(opt::BasicBlock* condtion_block, uint32_t new_target);
 
   // Add all blocks_to_add_ to function_ at the |insert_point|.
-  void AddBlocksToFunction(const ir::BasicBlock* insert_point);
+  void AddBlocksToFunction(const opt::BasicBlock* insert_point);
 
   // Duplicates the |old_loop|, cloning each body and remaping the ids without
   // removing instructions or changing relative structure. Result will be stored
   // in |new_loop|.
-  void DuplicateLoop(ir::Loop* old_loop, ir::Loop* new_loop);
+  void DuplicateLoop(opt::Loop* old_loop, opt::Loop* new_loop);
 
   inline size_t GetLoopIterationCount() const {
     return number_of_loop_iterations_;
   }
 
   // Extracts the initial state information from the |loop|.
-  void Init(ir::Loop* loop);
+  void Init(opt::Loop* loop);
 
   // Replace the uses of each induction variable outside the loop with the final
   // value of the induction variable before the loop exit. To reflect the proper
   // state of a fully unrolled loop.
-  void ReplaceInductionUseWithFinalValue(ir::Loop* loop);
+  void ReplaceInductionUseWithFinalValue(opt::Loop* loop);
 
   // Remove all the instructions in the invalidated_instructions_ vector.
   void RemoveDeadInstructions();
 
   // Replace any use of induction variables outwith the loop with the final
   // value of the induction variable in the unrolled loop.
-  void ReplaceOutsideLoopUseWithFinalValue(ir::Loop* loop);
+  void ReplaceOutsideLoopUseWithFinalValue(opt::Loop* loop);
 
   // Set the LoopControl operand of the OpLoopMerge instruction to be
   // DontUnroll.
-  void MarkLoopControlAsDontUnroll(ir::Loop* loop) const;
+  void MarkLoopControlAsDontUnroll(opt::Loop* loop) const;
 
  private:
   // Remap all the in |basic_block| to new IDs and keep the mapping of new ids
   // to old
   // ids. |loop| is used to identify special loop blocks (header, continue,
   // ect).
-  void AssignNewResultIds(ir::BasicBlock* basic_block);
+  void AssignNewResultIds(opt::BasicBlock* basic_block);
 
   // Using the map built by AssignNewResultIds, for each instruction in
   // |basic_block| use
   // that map to substitute the IDs used by instructions (in the operands) with
   // the new ids.
-  void RemapOperands(ir::BasicBlock* basic_block);
+  void RemapOperands(opt::BasicBlock* basic_block);
 
   // Copy the whole body of the loop, all blocks dominated by the |loop| header
   // and not dominated by the |loop| merge. The copied body will be linked to by
   // the old |loop| continue block and the new body will link to the |loop|
   // header via the new continue block. |eliminate_conditions| is used to decide
   // whether or not to fold all the condition blocks other than the last one.
-  void CopyBody(ir::Loop* loop, bool eliminate_conditions);
+  void CopyBody(opt::Loop* loop, bool eliminate_conditions);
 
   // Copy a given |block_to_copy| in the |loop| and record the mapping of the
   // old/new ids. |preserve_instructions| determines whether or not the method
   // will modify (other than result_id) instructions which are copied.
-  void CopyBasicBlock(ir::Loop* loop, const ir::BasicBlock* block_to_copy,
+  void CopyBasicBlock(opt::Loop* loop, const opt::BasicBlock* block_to_copy,
                       bool preserve_instructions);
 
   // The actual implementation of the unroll step. Unrolls |loop| by given
   // |factor| by copying the body by |factor| times. Also propagates the
   // induction variable value throughout the copies.
-  void Unroll(ir::Loop* loop, size_t factor);
+  void Unroll(opt::Loop* loop, size_t factor);
 
   // Fills the loop_blocks_inorder_ field with the ordered list of basic blocks
   // as computed by the method ComputeLoopOrderedBlocks.
-  void ComputeLoopOrderedBlocks(ir::Loop* loop);
+  void ComputeLoopOrderedBlocks(opt::Loop* loop);
 
   // Adds the blocks_to_add_ to both the |loop| and to the parent of |loop| if
   // the parent exists.
-  void AddBlocksToLoop(ir::Loop* loop) const;
+  void AddBlocksToLoop(opt::Loop* loop) const;
 
   // After the partially unroll step the phi instructions in the header block
   // will be in an illegal format. This function makes the phis legal by making
   // the edge from the latch block come from the new latch block and the value
   // to be the actual value of the phi at that point.
-  void LinkLastPhisToStart(ir::Loop* loop) const;
+  void LinkLastPhisToStart(opt::Loop* loop) const;
 
   // A pointer to the IRContext. Used to add/remove instructions and for usedef
   // chains.
-  ir::IRContext* context_;
+  opt::IRContext* context_;
 
   // A reference the function the loop is within.
-  ir::Function& function_;
+  opt::Function& function_;
 
   // A list of basic blocks to be added to the loop at the end of an unroll
   // step.
   BasicBlockListTy blocks_to_add_;
 
   // List of instructions which are now dead and can be removed.
-  std::vector<ir::Instruction*> invalidated_instructions_;
+  std::vector<opt::Instruction*> invalidated_instructions_;
 
   // Maintains the current state of the transform between calls to unroll.
   LoopUnrollState state_;
 
   // An ordered list containing the loop basic blocks.
-  std::vector<ir::BasicBlock*> loop_blocks_inorder_;
+  std::vector<opt::BasicBlock*> loop_blocks_inorder_;
 
   // The block containing the condition check which contains a conditional
   // branch to the merge and continue block.
-  ir::BasicBlock* loop_condition_block_;
+  opt::BasicBlock* loop_condition_block_;
 
   // The induction variable of the loop.
-  ir::Instruction* loop_induction_variable_;
+  opt::Instruction* loop_induction_variable_;
 
   // Phis used in the loop need to be remapped to use the actual result values
   // and then be remapped at the end.
-  std::vector<ir::Instruction*> loop_phi_instructions_;
+  std::vector<opt::Instruction*> loop_phi_instructions_;
 
   // The number of loop iterations that the loop would preform pre-unroll.
   size_t number_of_loop_iterations_;
@@ -325,8 +325,8 @@
 
 // Retrieve the index of the OpPhi instruction |phi| which corresponds to the
 // incoming |block| id.
-static uint32_t GetPhiIndexFromLabel(const ir::BasicBlock* block,
-                                     const ir::Instruction* phi) {
+static uint32_t GetPhiIndexFromLabel(const opt::BasicBlock* block,
+                                     const opt::Instruction* phi) {
   for (uint32_t i = 1; i < phi->NumInOperands(); i += 2) {
     if (block->id() == phi->GetSingleWordInOperand(i)) {
       return i;
@@ -336,7 +336,7 @@
   return 0;
 }
 
-void LoopUnrollerUtilsImpl::Init(ir::Loop* loop) {
+void LoopUnrollerUtilsImpl::Init(opt::Loop* loop) {
   loop_condition_block_ = loop->FindConditionBlock();
 
   // When we reinit the second loop during PartiallyUnrollResidualFactor we need
@@ -367,12 +367,12 @@
 // loop it creates two loops and unrolls one and adjusts the condition on the
 // other. The end result being that the new loop pair iterates over the correct
 // number of bodies.
-void LoopUnrollerUtilsImpl::PartiallyUnrollResidualFactor(ir::Loop* loop,
+void LoopUnrollerUtilsImpl::PartiallyUnrollResidualFactor(opt::Loop* loop,
                                                           size_t factor) {
-  std::unique_ptr<ir::Instruction> new_label{new ir::Instruction(
+  std::unique_ptr<opt::Instruction> new_label{new opt::Instruction(
       context_, SpvOp::SpvOpLabel, 0, context_->TakeNextId(), {})};
-  std::unique_ptr<ir::BasicBlock> new_exit_bb{
-      new ir::BasicBlock(std::move(new_label))};
+  std::unique_ptr<opt::BasicBlock> new_exit_bb{
+      new opt::BasicBlock(std::move(new_label))};
 
   // Save the id of the block before we move it.
   uint32_t new_merge_id = new_exit_bb->id();
@@ -380,13 +380,14 @@
   // Add the block the list of blocks to add, we want this merge block to be
   // right at the start of the new blocks.
   blocks_to_add_.push_back(std::move(new_exit_bb));
-  ir::BasicBlock* new_exit_bb_raw = blocks_to_add_[0].get();
-  ir::Instruction& original_conditional_branch = *loop_condition_block_->tail();
+  opt::BasicBlock* new_exit_bb_raw = blocks_to_add_[0].get();
+  opt::Instruction& original_conditional_branch =
+      *loop_condition_block_->tail();
   // Duplicate the loop, providing access to the blocks of both loops.
   // This is a naked new due to the VS2013 requirement of not having unique
   // pointers in vectors, as it will be inserted into a vector with
   // loop_descriptor.AddLoop.
-  ir::Loop* new_loop = new ir::Loop(*loop);
+  opt::Loop* new_loop = new opt::Loop(*loop);
 
   // Clear the basic blocks of the new loop.
   new_loop->ClearBlocks();
@@ -414,18 +415,18 @@
   // Add the new merge block to the back of the list of blocks to be added. It
   // needs to be the last block added to maintain dominator order in the binary.
   blocks_to_add_.push_back(
-      std::unique_ptr<ir::BasicBlock>(new_loop->GetMergeBlock()));
+      std::unique_ptr<opt::BasicBlock>(new_loop->GetMergeBlock()));
 
   // Add the blocks to the function.
   AddBlocksToFunction(loop->GetMergeBlock());
 
   // Reset the usedef analysis.
   context_->InvalidateAnalysesExceptFor(
-      ir::IRContext::Analysis::kAnalysisLoopAnalysis);
+      opt::IRContext::Analysis::kAnalysisLoopAnalysis);
   opt::analysis::DefUseManager* def_use_manager = context_->get_def_use_mgr();
 
   // The loop condition.
-  ir::Instruction* condition_check = def_use_manager->GetDef(
+  opt::Instruction* condition_check = def_use_manager->GetDef(
       original_conditional_branch.GetSingleWordOperand(0));
 
   // This should have been checked by the LoopUtils::CanPerformUnroll function
@@ -433,14 +434,14 @@
   assert(loop->IsSupportedCondition(condition_check->opcode()));
 
   // We need to account for the initial body when calculating the remainder.
-  int64_t remainder = ir::Loop::GetResidualConditionValue(
+  int64_t remainder = opt::Loop::GetResidualConditionValue(
       condition_check->opcode(), loop_init_value_, loop_step_value_,
       number_of_loop_iterations_, factor);
 
   assert(remainder > std::numeric_limits<int32_t>::min() &&
          remainder < std::numeric_limits<int32_t>::max());
 
-  ir::Instruction* new_constant = nullptr;
+  opt::Instruction* new_constant = nullptr;
 
   // If the remainder is negative then we add a signed constant, otherwise just
   // add an unsigned constant.
@@ -461,14 +462,14 @@
   // the preheader block. For the duplicated loop we need to update the constant
   // to be the amount of iterations covered by the first loop and the incoming
   // block to be the first loops new merge block.
-  std::vector<ir::Instruction*> new_inductions;
+  std::vector<opt::Instruction*> new_inductions;
   new_loop->GetInductionVariables(new_inductions);
 
-  std::vector<ir::Instruction*> old_inductions;
+  std::vector<opt::Instruction*> old_inductions;
   loop->GetInductionVariables(old_inductions);
   for (size_t index = 0; index < new_inductions.size(); ++index) {
-    ir::Instruction* new_induction = new_inductions[index];
-    ir::Instruction* old_induction = old_inductions[index];
+    opt::Instruction* new_induction = new_inductions[index];
+    opt::Instruction* old_induction = old_inductions[index];
     // Get the index of the loop initalizer, the value coming in from the
     // preheader.
     uint32_t initalizer_index =
@@ -483,7 +484,7 @@
     // then replace that use with the second loop induction variable.
     uint32_t second_loop_induction = new_induction->result_id();
     auto replace_use_outside_of_loop = [loop, second_loop_induction](
-                                           ir::Instruction* user,
+                                           opt::Instruction* user,
                                            uint32_t operand_index) {
       if (!loop->IsInsideLoop(user)) {
         user->SetOperand(operand_index, {second_loop_induction});
@@ -495,11 +496,11 @@
   }
 
   context_->InvalidateAnalysesExceptFor(
-      ir::IRContext::Analysis::kAnalysisLoopAnalysis);
+      opt::IRContext::Analysis::kAnalysisLoopAnalysis);
 
   context_->ReplaceAllUsesWith(loop->GetMergeBlock()->id(), new_merge_id);
 
-  ir::LoopDescriptor& loop_descriptor =
+  opt::LoopDescriptor& loop_descriptor =
       *context_->GetLoopDescriptor(&function_);
 
   loop_descriptor.AddLoop(new_loop, loop->GetParent());
@@ -509,8 +510,9 @@
 
 // Mark this loop as DontUnroll as it will already be unrolled and it may not
 // be safe to unroll a previously partially unrolled loop.
-void LoopUnrollerUtilsImpl::MarkLoopControlAsDontUnroll(ir::Loop* loop) const {
-  ir::Instruction* loop_merge_inst = loop->GetHeaderBlock()->GetLoopMergeInst();
+void LoopUnrollerUtilsImpl::MarkLoopControlAsDontUnroll(opt::Loop* loop) const {
+  opt::Instruction* loop_merge_inst =
+      loop->GetHeaderBlock()->GetLoopMergeInst();
   assert(loop_merge_inst &&
          "Loop merge instruction could not be found after entering unroller "
          "(should have exited before this)");
@@ -521,13 +523,13 @@
 // Duplicate the |loop| body |factor| - 1 number of times while keeping the loop
 // backedge intact. This will leave the loop with |factor| number of bodies
 // after accounting for the initial body.
-void LoopUnrollerUtilsImpl::Unroll(ir::Loop* loop, size_t factor) {
+void LoopUnrollerUtilsImpl::Unroll(opt::Loop* loop, size_t factor) {
   // If we unroll a loop partially it will not be safe to unroll it further.
   // This is due to the current method of calculating the number of loop
   // iterations.
   MarkLoopControlAsDontUnroll(loop);
 
-  std::vector<ir::Instruction*> inductions;
+  std::vector<opt::Instruction*> inductions;
   loop->GetInductionVariables(inductions);
   state_ = LoopUnrollState{loop_induction_variable_, loop->GetLatchBlock(),
                            loop_condition_block_, std::move(inductions)};
@@ -538,15 +540,15 @@
 
 void LoopUnrollerUtilsImpl::RemoveDeadInstructions() {
   // Remove the dead instructions.
-  for (ir::Instruction* inst : invalidated_instructions_) {
+  for (opt::Instruction* inst : invalidated_instructions_) {
     context_->KillInst(inst);
   }
 }
 
-void LoopUnrollerUtilsImpl::ReplaceInductionUseWithFinalValue(ir::Loop* loop) {
+void LoopUnrollerUtilsImpl::ReplaceInductionUseWithFinalValue(opt::Loop* loop) {
   context_->InvalidateAnalysesExceptFor(
-      ir::IRContext::Analysis::kAnalysisLoopAnalysis);
-  std::vector<ir::Instruction*> inductions;
+      opt::IRContext::Analysis::kAnalysisLoopAnalysis);
+  std::vector<opt::Instruction*> inductions;
   loop->GetInductionVariables(inductions);
 
   for (size_t index = 0; index < inductions.size(); ++index) {
@@ -559,7 +561,7 @@
 
 // Fully unroll the loop by partially unrolling it by the number of loop
 // iterations minus one for the body already accounted for.
-void LoopUnrollerUtilsImpl::FullyUnroll(ir::Loop* loop) {
+void LoopUnrollerUtilsImpl::FullyUnroll(opt::Loop* loop) {
   // We unroll the loop by number of iterations in the loop.
   Unroll(loop, number_of_loop_iterations_);
 
@@ -586,18 +588,18 @@
   RemoveDeadInstructions();
   // Invalidate all analyses.
   context_->InvalidateAnalysesExceptFor(
-      ir::IRContext::Analysis::kAnalysisLoopAnalysis);
+      opt::IRContext::Analysis::kAnalysisLoopAnalysis);
 }
 
 // Copy a given basic block, give it a new result_id, and store the new block
 // and the id mapping in the state. |preserve_instructions| is used to determine
 // whether or not this function should edit instructions other than the
 // |result_id|.
-void LoopUnrollerUtilsImpl::CopyBasicBlock(ir::Loop* loop,
-                                           const ir::BasicBlock* itr,
+void LoopUnrollerUtilsImpl::CopyBasicBlock(opt::Loop* loop,
+                                           const opt::BasicBlock* itr,
                                            bool preserve_instructions) {
   // Clone the block exactly, including the IDs.
-  ir::BasicBlock* basic_block = itr->Clone(context_);
+  opt::BasicBlock* basic_block = itr->Clone(context_);
   basic_block->SetParent(itr->GetParent());
 
   // Assign each result a new unique ID and keep a mapping of the old ids to
@@ -608,7 +610,7 @@
   if (itr == loop->GetContinueBlock()) {
     // Make the OpLoopMerge point to this block for the continue.
     if (!preserve_instructions) {
-      ir::Instruction* merge_inst = loop->GetHeaderBlock()->GetLoopMergeInst();
+      opt::Instruction* merge_inst = loop->GetHeaderBlock()->GetLoopMergeInst();
       merge_inst->SetInOperand(1, {basic_block->id()});
     }
 
@@ -621,7 +623,7 @@
 
     if (!preserve_instructions) {
       // Remove the loop merge instruction if it exists.
-      ir::Instruction* merge_inst = basic_block->GetLoopMergeInst();
+      opt::Instruction* merge_inst = basic_block->GetLoopMergeInst();
       if (merge_inst) invalidated_instructions_.push_back(merge_inst);
     }
   }
@@ -636,38 +638,38 @@
 
   // Add this block to the list of blocks to add to the function at the end of
   // the unrolling process.
-  blocks_to_add_.push_back(std::unique_ptr<ir::BasicBlock>(basic_block));
+  blocks_to_add_.push_back(std::unique_ptr<opt::BasicBlock>(basic_block));
 
   // Keep tracking the old block via a map.
   state_.new_blocks[itr->id()] = basic_block;
 }
 
-void LoopUnrollerUtilsImpl::CopyBody(ir::Loop* loop,
+void LoopUnrollerUtilsImpl::CopyBody(opt::Loop* loop,
                                      bool eliminate_conditions) {
   // Copy each basic block in the loop, give them new ids, and save state
   // information.
-  for (const ir::BasicBlock* itr : loop_blocks_inorder_) {
+  for (const opt::BasicBlock* itr : loop_blocks_inorder_) {
     CopyBasicBlock(loop, itr, false);
   }
 
   // Set the previous latch block to point to the new header.
-  ir::Instruction& latch_branch = *state_.previous_latch_block_->tail();
+  opt::Instruction& latch_branch = *state_.previous_latch_block_->tail();
   latch_branch.SetInOperand(0, {state_.new_header_block->id()});
 
   // As the algorithm copies the original loop blocks exactly, the tail of the
   // latch block on iterations after the first one will be a branch to the new
   // header and not the actual loop header. The last continue block in the loop
   // should always be a backedge to the global header.
-  ir::Instruction& new_latch_branch = *state_.new_latch_block->tail();
+  opt::Instruction& new_latch_branch = *state_.new_latch_block->tail();
   new_latch_branch.SetInOperand(0, {loop->GetHeaderBlock()->id()});
 
-  std::vector<ir::Instruction*> inductions;
+  std::vector<opt::Instruction*> inductions;
   loop->GetInductionVariables(inductions);
   for (size_t index = 0; index < inductions.size(); ++index) {
-    ir::Instruction* master_copy = inductions[index];
+    opt::Instruction* master_copy = inductions[index];
 
     assert(master_copy->result_id() != 0);
-    ir::Instruction* induction_clone =
+    opt::Instruction* induction_clone =
         state_.ids_to_new_inst[state_.new_inst[master_copy->result_id()]];
 
     state_.new_phis_.push_back(induction_clone);
@@ -695,14 +697,14 @@
     RemapOperands(pair.second);
   }
 
-  for (ir::Instruction* dead_phi : state_.new_phis_)
+  for (opt::Instruction* dead_phi : state_.new_phis_)
     invalidated_instructions_.push_back(dead_phi);
 
   // Swap the state so the new is now the previous.
   state_.NextIterationState();
 }
 
-uint32_t LoopUnrollerUtilsImpl::GetPhiDefID(const ir::Instruction* phi,
+uint32_t LoopUnrollerUtilsImpl::GetPhiDefID(const opt::Instruction* phi,
                                             uint32_t label) const {
   for (uint32_t operand = 3; operand < phi->NumOperands(); operand += 2) {
     if (phi->GetSingleWordOperand(operand) == label) {
@@ -713,10 +715,10 @@
   return 0;
 }
 
-void LoopUnrollerUtilsImpl::FoldConditionBlock(ir::BasicBlock* condition_block,
+void LoopUnrollerUtilsImpl::FoldConditionBlock(opt::BasicBlock* condition_block,
                                                uint32_t operand_label) {
   // Remove the old conditional branch to the merge and continue blocks.
-  ir::Instruction& old_branch = *condition_block->tail();
+  opt::Instruction& old_branch = *condition_block->tail();
   uint32_t new_target = old_branch.GetSingleWordOperand(operand_label);
 
   context_->KillInst(&old_branch);
@@ -725,9 +727,9 @@
   builder.AddBranch(new_target);
 }
 
-void LoopUnrollerUtilsImpl::CloseUnrolledLoop(ir::Loop* loop) {
+void LoopUnrollerUtilsImpl::CloseUnrolledLoop(opt::Loop* loop) {
   // Remove the OpLoopMerge instruction from the function.
-  ir::Instruction* merge_inst = loop->GetHeaderBlock()->GetLoopMergeInst();
+  opt::Instruction* merge_inst = loop->GetHeaderBlock()->GetLoopMergeInst();
   invalidated_instructions_.push_back(merge_inst);
 
   // Remove the final backedge to the header and make it point instead to the
@@ -738,7 +740,7 @@
   // Remove all induction variables as the phis will now be invalid. Replace all
   // uses with the constant initializer value (all uses of phis will be in
   // the first iteration with the subsequent phis already having been removed).
-  std::vector<ir::Instruction*> inductions;
+  std::vector<opt::Instruction*> inductions;
   loop->GetInductionVariables(inductions);
 
   // We can use the state instruction mechanism to replace all internal loop
@@ -747,31 +749,31 @@
   // use context ReplaceAllUsesWith for the uses outside the loop with the final
   // trip phi value.
   state_.new_inst.clear();
-  for (ir::Instruction* induction : inductions) {
+  for (opt::Instruction* induction : inductions) {
     uint32_t initalizer_id =
         GetPhiDefID(induction, loop->GetPreHeaderBlock()->id());
 
     state_.new_inst[induction->result_id()] = initalizer_id;
   }
 
-  for (ir::BasicBlock* block : loop_blocks_inorder_) {
+  for (opt::BasicBlock* block : loop_blocks_inorder_) {
     RemapOperands(block);
   }
 }
 
 // Uses the first loop to create a copy of the loop with new IDs.
-void LoopUnrollerUtilsImpl::DuplicateLoop(ir::Loop* old_loop,
-                                          ir::Loop* new_loop) {
-  std::vector<ir::BasicBlock*> new_block_order;
+void LoopUnrollerUtilsImpl::DuplicateLoop(opt::Loop* old_loop,
+                                          opt::Loop* new_loop) {
+  std::vector<opt::BasicBlock*> new_block_order;
 
   // Copy every block in the old loop.
-  for (const ir::BasicBlock* itr : loop_blocks_inorder_) {
+  for (const opt::BasicBlock* itr : loop_blocks_inorder_) {
     CopyBasicBlock(old_loop, itr, true);
     new_block_order.push_back(blocks_to_add_.back().get());
   }
 
   // Clone the merge block, give it a new id and record it in the state.
-  ir::BasicBlock* new_merge = old_loop->GetMergeBlock()->Clone(context_);
+  opt::BasicBlock* new_merge = old_loop->GetMergeBlock()->Clone(context_);
   new_merge->SetParent(old_loop->GetMergeBlock()->GetParent());
   AssignNewResultIds(new_merge);
   state_.new_blocks[old_loop->GetMergeBlock()->id()] = new_merge;
@@ -793,10 +795,10 @@
 }
 
 // Whenever the utility copies a block it stores it in a tempory buffer, this
-// function adds the buffer into the ir::Function. The blocks will be inserted
+// function adds the buffer into the opt::Function. The blocks will be inserted
 // after the block |insert_point|.
 void LoopUnrollerUtilsImpl::AddBlocksToFunction(
-    const ir::BasicBlock* insert_point) {
+    const opt::BasicBlock* insert_point) {
   for (auto basic_block_iterator = function_.begin();
        basic_block_iterator != function_.end(); ++basic_block_iterator) {
     if (basic_block_iterator->id() == insert_point->id()) {
@@ -812,7 +814,7 @@
 
 // Assign all result_ids in |basic_block| instructions to new IDs and preserve
 // the mapping of new ids to old ones.
-void LoopUnrollerUtilsImpl::AssignNewResultIds(ir::BasicBlock* basic_block) {
+void LoopUnrollerUtilsImpl::AssignNewResultIds(opt::BasicBlock* basic_block) {
   // Label instructions aren't covered by normal traversal of the
   // instructions.
   uint32_t new_label_id = context_->TakeNextId();
@@ -821,7 +823,7 @@
   state_.new_inst[basic_block->GetLabelInst()->result_id()] = new_label_id;
   basic_block->GetLabelInst()->SetResultId(new_label_id);
 
-  for (ir::Instruction& inst : *basic_block) {
+  for (opt::Instruction& inst : *basic_block) {
     uint32_t old_id = inst.result_id();
 
     // Ignore stores etc.
@@ -845,8 +847,8 @@
 
 // For all instructions in |basic_block| check if the operands used are from a
 // copied instruction and if so swap out the operand for the copy of it.
-void LoopUnrollerUtilsImpl::RemapOperands(ir::BasicBlock* basic_block) {
-  for (ir::Instruction& inst : *basic_block) {
+void LoopUnrollerUtilsImpl::RemapOperands(opt::BasicBlock* basic_block) {
+  for (opt::Instruction& inst : *basic_block) {
     auto remap_operands_to_new_ids = [this](uint32_t* id) {
       auto itr = state_.new_inst.find(*id);
 
@@ -861,13 +863,13 @@
 
 // Generate the ordered list of basic blocks in the |loop| and cache it for
 // later use.
-void LoopUnrollerUtilsImpl::ComputeLoopOrderedBlocks(ir::Loop* loop) {
+void LoopUnrollerUtilsImpl::ComputeLoopOrderedBlocks(opt::Loop* loop) {
   loop_blocks_inorder_.clear();
   loop->ComputeLoopStructuredOrder(&loop_blocks_inorder_);
 }
 
 // Adds the blocks_to_add_ to both the loop and to the parent.
-void LoopUnrollerUtilsImpl::AddBlocksToLoop(ir::Loop* loop) const {
+void LoopUnrollerUtilsImpl::AddBlocksToLoop(opt::Loop* loop) const {
   // Add the blocks to this loop.
   for (auto& block_itr : blocks_to_add_) {
     loop->AddBasicBlock(block_itr.get());
@@ -877,12 +879,12 @@
   if (loop->GetParent()) AddBlocksToLoop(loop->GetParent());
 }
 
-void LoopUnrollerUtilsImpl::LinkLastPhisToStart(ir::Loop* loop) const {
-  std::vector<ir::Instruction*> inductions;
+void LoopUnrollerUtilsImpl::LinkLastPhisToStart(opt::Loop* loop) const {
+  std::vector<opt::Instruction*> inductions;
   loop->GetInductionVariables(inductions);
 
   for (size_t i = 0; i < inductions.size(); ++i) {
-    ir::Instruction* last_phi_in_block = state_.previous_phis_[i];
+    opt::Instruction* last_phi_in_block = state_.previous_phis_[i];
 
     uint32_t phi_index =
         GetPhiIndexFromLabel(state_.previous_latch_block_, last_phi_in_block);
@@ -890,7 +892,7 @@
         last_phi_in_block->GetSingleWordInOperand(phi_index - 1);
     uint32_t phi_label = last_phi_in_block->GetSingleWordInOperand(phi_index);
 
-    ir::Instruction* phi = inductions[i];
+    opt::Instruction* phi = inductions[i];
     phi->SetInOperand(phi_index - 1, {phi_variable});
     phi->SetInOperand(phi_index, {phi_label});
   }
@@ -898,7 +900,7 @@
 
 // Duplicate the |loop| body |factor| number of times while keeping the loop
 // backedge intact.
-void LoopUnrollerUtilsImpl::PartiallyUnroll(ir::Loop* loop, size_t factor) {
+void LoopUnrollerUtilsImpl::PartiallyUnroll(opt::Loop* loop, size_t factor) {
   Unroll(loop, factor);
   LinkLastPhisToStart(loop);
   AddBlocksToLoop(loop);
@@ -925,11 +927,11 @@
   }
 
   // Find check the loop has a condition we can find and evaluate.
-  const ir::BasicBlock* condition = loop_->FindConditionBlock();
+  const opt::BasicBlock* condition = loop_->FindConditionBlock();
   if (!condition) return false;
 
   // Check that we can find and process the induction variable.
-  const ir::Instruction* induction = loop_->FindConditionVariable(condition);
+  const opt::Instruction* induction = loop_->FindConditionVariable(condition);
   if (!induction || induction->opcode() != SpvOpPhi) return false;
 
   // Check that we can find the number of loop iterations.
@@ -938,7 +940,7 @@
 
   // Make sure the latch block is a unconditional branch to the header
   // block.
-  const ir::Instruction& branch = *loop_->GetLatchBlock()->ctail();
+  const opt::Instruction& branch = *loop_->GetLatchBlock()->ctail();
   bool branching_assumption =
       branch.opcode() == SpvOpBranch &&
       branch.GetSingleWordInOperand(0) == loop_->GetHeaderBlock()->id();
@@ -946,7 +948,7 @@
     return false;
   }
 
-  std::vector<ir::Instruction*> inductions;
+  std::vector<opt::Instruction*> inductions;
   loop_->GetInductionVariables(inductions);
 
   // Ban breaks within the loop.
@@ -967,7 +969,7 @@
   // Iterate over all the blocks within the loop and check that none of them
   // exit the loop.
   for (uint32_t label_id : loop_->GetBlocks()) {
-    const ir::BasicBlock* block = context_->cfg()->block(label_id);
+    const opt::BasicBlock* block = context_->cfg()->block(label_id);
     if (block->ctail()->opcode() == SpvOp::SpvOpKill ||
         block->ctail()->opcode() == SpvOp::SpvOpReturn ||
         block->ctail()->opcode() == SpvOp::SpvOpReturnValue) {
@@ -1013,7 +1015,7 @@
 bool LoopUtils::FullyUnroll() {
   if (!CanPerformUnroll()) return false;
 
-  std::vector<ir::Instruction*> inductions;
+  std::vector<opt::Instruction*> inductions;
   loop_->GetInductionVariables(inductions);
 
   LoopUnrollerUtilsImpl unroller{context_,
@@ -1028,7 +1030,7 @@
 void LoopUtils::Finalize() {
   // Clean up the loop descriptor to preserve the analysis.
 
-  ir::LoopDescriptor* LD = context_->GetLoopDescriptor(&function_);
+  opt::LoopDescriptor* LD = context_->GetLoopDescriptor(&function_);
   LD->PostModificationCleanup();
 }
 
@@ -1038,12 +1040,12 @@
  *
  */
 
-Pass::Status LoopUnroller::Process(ir::IRContext* c) {
+Pass::Status LoopUnroller::Process(opt::IRContext* c) {
   context_ = c;
   bool changed = false;
-  for (ir::Function& f : *c->module()) {
-    ir::LoopDescriptor* LD = context_->GetLoopDescriptor(&f);
-    for (ir::Loop& loop : *LD) {
+  for (opt::Function& f : *c->module()) {
+    opt::LoopDescriptor* LD = context_->GetLoopDescriptor(&f);
+    for (opt::Loop& loop : *LD) {
       LoopUtils loop_utils{c, &loop};
       if (!loop.HasUnrollLoopControl() || !loop_utils.CanPerformUnroll()) {
         continue;
diff --git a/source/opt/loop_unroller.h b/source/opt/loop_unroller.h
index caf0a8e..2c1b606 100644
--- a/source/opt/loop_unroller.h
+++ b/source/opt/loop_unroller.h
@@ -27,10 +27,10 @@
 
   const char* name() const override { return "Loop unroller"; }
 
-  Status Process(ir::IRContext* context) override;
+  Status Process(opt::IRContext* context) override;
 
  private:
-  ir::IRContext* context_;
+  opt::IRContext* context_;
   bool fully_unroll_;
   int unroll_factor_;
 };
diff --git a/source/opt/loop_unswitch_pass.cpp b/source/opt/loop_unswitch_pass.cpp
index 274fd0f..bb2f0be 100644
--- a/source/opt/loop_unswitch_pass.cpp
+++ b/source/opt/loop_unswitch_pass.cpp
@@ -52,8 +52,8 @@
 //  - The loop invariant condition is not uniform.
 class LoopUnswitch {
  public:
-  LoopUnswitch(ir::IRContext* context, ir::Function* function, ir::Loop* loop,
-               ir::LoopDescriptor* loop_desc)
+  LoopUnswitch(opt::IRContext* context, opt::Function* function,
+               opt::Loop* loop, opt::LoopDescriptor* loop_desc)
       : function_(function),
         loop_(loop),
         loop_desc_(*loop_desc),
@@ -70,10 +70,10 @@
     if (switch_block_) return true;
     if (loop_->IsSafeToClone()) return false;
 
-    ir::CFG& cfg = *context_->cfg();
+    opt::CFG& cfg = *context_->cfg();
 
     for (uint32_t bb_id : loop_->GetBlocks()) {
-      ir::BasicBlock* bb = cfg.block(bb_id);
+      opt::BasicBlock* bb = cfg.block(bb_id);
       if (bb->terminator()->IsBranch() &&
           bb->terminator()->opcode() != SpvOpBranch) {
         if (IsConditionLoopInvariant(bb->terminator())) {
@@ -87,8 +87,8 @@
   }
 
   // Return the iterator to the basic block |bb|.
-  ir::Function::iterator FindBasicBlockPosition(ir::BasicBlock* bb_to_find) {
-    ir::Function::iterator it = function_->FindBlock(bb_to_find->id());
+  opt::Function::iterator FindBasicBlockPosition(opt::BasicBlock* bb_to_find) {
+    opt::Function::iterator it = function_->FindBlock(bb_to_find->id());
     assert(it != function_->end() && "Basic Block not found");
     return it;
   }
@@ -96,12 +96,13 @@
   // Creates a new basic block and insert it into the function |fn| at the
   // position |ip|. This function preserves the def/use and instr to block
   // managers.
-  ir::BasicBlock* CreateBasicBlock(ir::Function::iterator ip) {
+  opt::BasicBlock* CreateBasicBlock(opt::Function::iterator ip) {
     analysis::DefUseManager* def_use_mgr = context_->get_def_use_mgr();
 
-    ir::BasicBlock* bb = &*ip.InsertBefore(std::unique_ptr<ir::BasicBlock>(
-        new ir::BasicBlock(std::unique_ptr<ir::Instruction>(new ir::Instruction(
-            context_, SpvOpLabel, 0, context_->TakeNextId(), {})))));
+    opt::BasicBlock* bb =
+        &*ip.InsertBefore(std::unique_ptr<opt::BasicBlock>(new opt::BasicBlock(
+            std::unique_ptr<opt::Instruction>(new opt::Instruction(
+                context_, SpvOpLabel, 0, context_->TakeNextId(), {})))));
     bb->SetParent(function_);
     def_use_mgr->AnalyzeInstDef(bb->GetLabelInst());
     context_->set_instr_block(bb->GetLabelInst(), bb);
@@ -116,7 +117,7 @@
     assert(loop_->GetPreHeaderBlock() && "This loop has no pre-header block");
     assert(loop_->IsLCSSA() && "This loop is not in LCSSA form");
 
-    ir::CFG& cfg = *context_->cfg();
+    opt::CFG& cfg = *context_->cfg();
     DominatorTree* dom_tree =
         &context_->GetDominatorAnalysis(function_)->GetDomTree();
     analysis::DefUseManager* def_use_mgr = context_->get_def_use_mgr();
@@ -132,11 +133,11 @@
     //////////////////////////////////////////////////////////////////////////////
 
     // Get the merge block if it exists.
-    ir::BasicBlock* if_merge_block = loop_->GetMergeBlock();
+    opt::BasicBlock* if_merge_block = loop_->GetMergeBlock();
     // The merge block is only created if the loop has a unique exit block. We
     // have this guarantee for structured loops, for compute loop it will
     // trivially help maintain both a structured-like form and LCSAA.
-    ir::BasicBlock* loop_merge_block =
+    opt::BasicBlock* loop_merge_block =
         if_merge_block
             ? CreateBasicBlock(FindBasicBlockPosition(if_merge_block))
             : nullptr;
@@ -144,17 +145,17 @@
       // Add the instruction and update managers.
       opt::InstructionBuilder builder(
           context_, loop_merge_block,
-          ir::IRContext::kAnalysisDefUse |
-              ir::IRContext::kAnalysisInstrToBlockMapping);
+          opt::IRContext::kAnalysisDefUse |
+              opt::IRContext::kAnalysisInstrToBlockMapping);
       builder.AddBranch(if_merge_block->id());
       builder.SetInsertPoint(&*loop_merge_block->begin());
       cfg.RegisterBlock(loop_merge_block);
       def_use_mgr->AnalyzeInstDef(loop_merge_block->GetLabelInst());
       // Update CFG.
       if_merge_block->ForEachPhiInst(
-          [loop_merge_block, &builder, this](ir::Instruction* phi) {
-            ir::Instruction* cloned = phi->Clone(context_);
-            builder.AddInstruction(std::unique_ptr<ir::Instruction>(cloned));
+          [loop_merge_block, &builder, this](opt::Instruction* phi) {
+            opt::Instruction* cloned = phi->Clone(context_);
+            builder.AddInstruction(std::unique_ptr<opt::Instruction>(cloned));
             phi->SetInOperand(0, {cloned->result_id()});
             phi->SetInOperand(1, {loop_merge_block->id()});
             for (uint32_t j = phi->NumInOperands() - 1; j > 1; j--)
@@ -164,7 +165,7 @@
       std::vector<uint32_t> preds = cfg.preds(if_merge_block->id());
       for (uint32_t pid : preds) {
         if (pid == loop_merge_block->id()) continue;
-        ir::BasicBlock* p_bb = cfg.block(pid);
+        opt::BasicBlock* p_bb = cfg.block(pid);
         p_bb->ForEachSuccessorLabel(
             [if_merge_block, loop_merge_block](uint32_t* id) {
               if (*id == if_merge_block->id()) *id = loop_merge_block->id();
@@ -173,7 +174,7 @@
       }
       cfg.RemoveNonExistingEdges(if_merge_block->id());
       // Update loop descriptor.
-      if (ir::Loop* ploop = loop_->GetParent()) {
+      if (opt::Loop* ploop = loop_->GetParent()) {
         ploop->AddBasicBlock(loop_merge_block);
         loop_desc_.SetBasicBlockToLoop(loop_merge_block->id(), ploop);
       }
@@ -198,20 +199,20 @@
     //         for the constant branch.
     ////////////////////////////////////////////////////////////////////////////
 
-    ir::BasicBlock* if_block = loop_->GetPreHeaderBlock();
+    opt::BasicBlock* if_block = loop_->GetPreHeaderBlock();
     // If this preheader is the parent loop header,
     // we need to create a dedicated block for the if.
-    ir::BasicBlock* loop_pre_header =
+    opt::BasicBlock* loop_pre_header =
         CreateBasicBlock(++FindBasicBlockPosition(if_block));
     opt::InstructionBuilder(context_, loop_pre_header,
-                            ir::IRContext::kAnalysisDefUse |
-                                ir::IRContext::kAnalysisInstrToBlockMapping)
+                            opt::IRContext::kAnalysisDefUse |
+                                opt::IRContext::kAnalysisInstrToBlockMapping)
         .AddBranch(loop_->GetHeaderBlock()->id());
 
     if_block->tail()->SetInOperand(0, {loop_pre_header->id()});
 
     // Update loop descriptor.
-    if (ir::Loop* ploop = loop_desc_[if_block]) {
+    if (opt::Loop* ploop = loop_desc_[if_block]) {
       ploop->AddBasicBlock(loop_pre_header);
       loop_desc_.SetBasicBlockToLoop(loop_pre_header->id(), ploop);
     }
@@ -223,7 +224,7 @@
     cfg.RemoveNonExistingEdges(loop_->GetHeaderBlock()->id());
 
     loop_->GetHeaderBlock()->ForEachPhiInst(
-        [loop_pre_header, if_block](ir::Instruction* phi) {
+        [loop_pre_header, if_block](opt::Instruction* phi) {
           phi->ForEachInId([loop_pre_header, if_block](uint32_t* id) {
             if (*id == if_block->id()) {
               *id = loop_pre_header->id();
@@ -259,9 +260,9 @@
     //   - Specialize the loop //
     /////////////////////////////
 
-    ir::Instruction* iv_condition = &*switch_block_->tail();
+    opt::Instruction* iv_condition = &*switch_block_->tail();
     SpvOp iv_opcode = iv_condition->opcode();
-    ir::Instruction* condition =
+    opt::Instruction* condition =
         def_use_mgr->GetDef(iv_condition->GetOperand(0).words[0]);
 
     analysis::ConstantManager* cst_mgr = context_->get_constant_mgr();
@@ -270,10 +271,10 @@
 
     // Build the list of value for which we need to clone and specialize the
     // loop.
-    std::vector<std::pair<ir::Instruction*, ir::BasicBlock*>> constant_branch;
+    std::vector<std::pair<opt::Instruction*, opt::BasicBlock*>> constant_branch;
     // Special case for the original loop
-    ir::Instruction* original_loop_constant_value;
-    ir::BasicBlock* original_loop_target;
+    opt::Instruction* original_loop_constant_value;
+    opt::BasicBlock* original_loop_target;
     if (iv_opcode == SpvOpBranchConditional) {
       constant_branch.emplace_back(
           cst_mgr->GetDefiningInstruction(cst_mgr->GetConstant(cond_type, {0})),
@@ -308,13 +309,13 @@
     }
 
     for (auto& specialisation_pair : constant_branch) {
-      ir::Instruction* specialisation_value = specialisation_pair.first;
+      opt::Instruction* specialisation_value = specialisation_pair.first;
       //////////////////////////////////////////////////////////
       // Step 3: Duplicate |loop_|.
       //////////////////////////////////////////////////////////
       LoopUtils::LoopCloningResult clone_result;
 
-      ir::Loop* cloned_loop =
+      opt::Loop* cloned_loop =
           loop_utils.CloneLoop(&clone_result, ordered_loop_blocks_);
       specialisation_pair.second = cloned_loop->GetPreHeaderBlock();
 
@@ -326,10 +327,10 @@
         std::unordered_set<uint32_t> dead_blocks;
         std::unordered_set<uint32_t> unreachable_merges;
         SimplifyLoop(
-            ir::make_range(
-                ir::UptrVectorIterator<ir::BasicBlock>(
+            opt::make_range(
+                opt::UptrVectorIterator<opt::BasicBlock>(
                     &clone_result.cloned_bb_, clone_result.cloned_bb_.begin()),
-                ir::UptrVectorIterator<ir::BasicBlock>(
+                opt::UptrVectorIterator<opt::BasicBlock>(
                     &clone_result.cloned_bb_, clone_result.cloned_bb_.end())),
             cloned_loop, condition, specialisation_value, &dead_blocks);
 
@@ -338,7 +339,7 @@
         cloned_loop =
             CleanLoopNest(cloned_loop, dead_blocks, &unreachable_merges);
         CleanUpCFG(
-            ir::UptrVectorIterator<ir::BasicBlock>(
+            opt::UptrVectorIterator<opt::BasicBlock>(
                 &clone_result.cloned_bb_, clone_result.cloned_bb_.begin()),
             dead_blocks, unreachable_merges);
 
@@ -347,10 +348,10 @@
         ///////////////////////////////////////////////////////////
 
         for (uint32_t merge_bb_id : if_merging_blocks) {
-          ir::BasicBlock* merge = context_->cfg()->block(merge_bb_id);
+          opt::BasicBlock* merge = context_->cfg()->block(merge_bb_id);
           // We are in LCSSA so we only care about phi instructions.
           merge->ForEachPhiInst([is_from_original_loop, &dead_blocks,
-                                 &clone_result](ir::Instruction* phi) {
+                                 &clone_result](opt::Instruction* phi) {
             uint32_t num_in_operands = phi->NumInOperands();
             for (uint32_t i = 0; i < num_in_operands; i += 2) {
               uint32_t pred = phi->GetSingleWordInOperand(i + 1);
@@ -381,11 +382,11 @@
     {
       std::unordered_set<uint32_t> dead_blocks;
       std::unordered_set<uint32_t> unreachable_merges;
-      SimplifyLoop(ir::make_range(function_->begin(), function_->end()), loop_,
+      SimplifyLoop(opt::make_range(function_->begin(), function_->end()), loop_,
                    condition, original_loop_constant_value, &dead_blocks);
 
       for (uint32_t merge_bb_id : if_merging_blocks) {
-        ir::BasicBlock* merge = context_->cfg()->block(merge_bb_id);
+        opt::BasicBlock* merge = context_->cfg()->block(merge_bb_id);
         // LCSSA, so we only care about phi instructions.
         // If we the phi is reduced to a single incoming branch, do not
         // propagate it to preserve LCSSA.
@@ -424,7 +425,7 @@
           constant_branch[0].second->id(),
           if_merge_block ? if_merge_block->id() : kInvalidId);
     } else {
-      std::vector<std::pair<ir::Operand::OperandData, uint32_t>> targets;
+      std::vector<std::pair<opt::Operand::OperandData, uint32_t>> targets;
       for (auto& t : constant_branch) {
         targets.emplace_back(t.first->GetInOperand(0).words, t.second->id());
       }
@@ -438,7 +439,7 @@
     ordered_loop_blocks_.clear();
 
     context_->InvalidateAnalysesExceptFor(
-        ir::IRContext::Analysis::kAnalysisLoopAnalysis);
+        opt::IRContext::Analysis::kAnalysisLoopAnalysis);
   }
 
   // Returns true if the unswitch killed the original |loop_|.
@@ -446,37 +447,37 @@
 
  private:
   using ValueMapTy = std::unordered_map<uint32_t, uint32_t>;
-  using BlockMapTy = std::unordered_map<uint32_t, ir::BasicBlock*>;
+  using BlockMapTy = std::unordered_map<uint32_t, opt::BasicBlock*>;
 
-  ir::Function* function_;
-  ir::Loop* loop_;
-  ir::LoopDescriptor& loop_desc_;
-  ir::IRContext* context_;
+  opt::Function* function_;
+  opt::Loop* loop_;
+  opt::LoopDescriptor& loop_desc_;
+  opt::IRContext* context_;
 
-  ir::BasicBlock* switch_block_;
+  opt::BasicBlock* switch_block_;
   // Map between instructions and if they are dynamically uniform.
   std::unordered_map<uint32_t, bool> dynamically_uniform_;
   // The loop basic blocks in structured order.
-  std::vector<ir::BasicBlock*> ordered_loop_blocks_;
+  std::vector<opt::BasicBlock*> ordered_loop_blocks_;
 
   // Returns the next usable id for the context.
   uint32_t TakeNextId() { return context_->TakeNextId(); }
 
   // Patches |bb|'s phi instruction by removing incoming value from unexisting
   // or tagged as dead branches.
-  void PatchPhis(ir::BasicBlock* bb,
+  void PatchPhis(opt::BasicBlock* bb,
                  const std::unordered_set<uint32_t>& dead_blocks,
                  bool preserve_phi) {
-    ir::CFG& cfg = *context_->cfg();
+    opt::CFG& cfg = *context_->cfg();
 
-    std::vector<ir::Instruction*> phi_to_kill;
+    std::vector<opt::Instruction*> phi_to_kill;
     const std::vector<uint32_t>& bb_preds = cfg.preds(bb->id());
     auto is_branch_dead = [&bb_preds, &dead_blocks](uint32_t id) {
       return dead_blocks.count(id) ||
              std::find(bb_preds.begin(), bb_preds.end(), id) == bb_preds.end();
     };
     bb->ForEachPhiInst([&phi_to_kill, &is_branch_dead, preserve_phi,
-                        this](ir::Instruction* insn) {
+                        this](opt::Instruction* insn) {
       uint32_t i = 0;
       while (i < insn->NumInOperands()) {
         uint32_t incoming_id = insn->GetSingleWordInOperand(i + 1);
@@ -497,7 +498,7 @@
                                      insn->GetSingleWordInOperand(0));
       }
     });
-    for (ir::Instruction* insn : phi_to_kill) {
+    for (opt::Instruction* insn : phi_to_kill) {
       context_->KillInst(insn);
     }
   }
@@ -505,13 +506,13 @@
   // Removes any block that is tagged as dead, if the block is in
   // |unreachable_merges| then all block's instructions are replaced by a
   // OpUnreachable.
-  void CleanUpCFG(ir::UptrVectorIterator<ir::BasicBlock> bb_it,
+  void CleanUpCFG(opt::UptrVectorIterator<opt::BasicBlock> bb_it,
                   const std::unordered_set<uint32_t>& dead_blocks,
                   const std::unordered_set<uint32_t>& unreachable_merges) {
-    ir::CFG& cfg = *context_->cfg();
+    opt::CFG& cfg = *context_->cfg();
 
     while (bb_it != bb_it.End()) {
-      ir::BasicBlock& bb = *bb_it;
+      opt::BasicBlock& bb = *bb_it;
 
       if (unreachable_merges.count(bb.id())) {
         if (bb.begin() != bb.tail() ||
@@ -536,7 +537,7 @@
 
   // Return true if |c_inst| is a Boolean constant and set |cond_val| with the
   // value that |c_inst|
-  bool GetConstCondition(const ir::Instruction* c_inst, bool* cond_val) {
+  bool GetConstCondition(const opt::Instruction* c_inst, bool* cond_val) {
     bool cond_is_const;
     switch (c_inst->opcode()) {
       case SpvOpConstantFalse: {
@@ -564,20 +565,20 @@
   //   - |cst_value| must be constant or null (to represent the default target
   //   of an OpSwitch).
   void SimplifyLoop(
-      ir::IteratorRange<ir::UptrVectorIterator<ir::BasicBlock>> block_range,
-      ir::Loop* loop, ir::Instruction* to_version_insn,
-      ir::Instruction* cst_value, std::unordered_set<uint32_t>* dead_blocks) {
-    ir::CFG& cfg = *context_->cfg();
+      opt::IteratorRange<opt::UptrVectorIterator<opt::BasicBlock>> block_range,
+      opt::Loop* loop, opt::Instruction* to_version_insn,
+      opt::Instruction* cst_value, std::unordered_set<uint32_t>* dead_blocks) {
+    opt::CFG& cfg = *context_->cfg();
     analysis::DefUseManager* def_use_mgr = context_->get_def_use_mgr();
 
     std::function<bool(uint32_t)> ignore_node;
     ignore_node = [loop](uint32_t bb_id) { return !loop->IsInsideLoop(bb_id); };
 
-    std::vector<std::pair<ir::Instruction*, uint32_t>> use_list;
+    std::vector<std::pair<opt::Instruction*, uint32_t>> use_list;
     def_use_mgr->ForEachUse(
         to_version_insn, [&use_list, &ignore_node, this](
-                             ir::Instruction* inst, uint32_t operand_index) {
-          ir::BasicBlock* bb = context_->get_instr_block(inst);
+                             opt::Instruction* inst, uint32_t operand_index) {
+          opt::BasicBlock* bb = context_->get_instr_block(inst);
 
           if (!bb || ignore_node(bb->id())) {
             // Out of the loop, the specialization does not apply any more.
@@ -589,9 +590,9 @@
     // First pass: inject the specialized value into the loop (and only the
     // loop).
     for (auto use : use_list) {
-      ir::Instruction* inst = use.first;
+      opt::Instruction* inst = use.first;
       uint32_t operand_index = use.second;
-      ir::BasicBlock* bb = context_->get_instr_block(inst);
+      opt::BasicBlock* bb = context_->get_instr_block(inst);
 
       // If it is not a branch, simply inject the value.
       if (!inst->IsBranch()) {
@@ -627,9 +628,9 @@
           live_target = inst->GetSingleWordInOperand(1);
           if (cst_value) {
             if (!cst_value->IsConstant()) break;
-            const ir::Operand& cst = cst_value->GetInOperand(0);
+            const opt::Operand& cst = cst_value->GetInOperand(0);
             for (uint32_t i = 2; i < inst->NumInOperands(); i += 2) {
-              const ir::Operand& literal = inst->GetInOperand(i);
+              const opt::Operand& literal = inst->GetInOperand(i);
               if (literal == cst) {
                 live_target = inst->GetSingleWordInOperand(i + 1);
                 break;
@@ -648,13 +649,13 @@
       }
       if (live_target != 0) {
         // Check for the presence of the merge block.
-        if (ir::Instruction* merge = bb->GetMergeInst())
+        if (opt::Instruction* merge = bb->GetMergeInst())
           context_->KillInst(merge);
         context_->KillInst(&*bb->tail());
         opt::InstructionBuilder builder(
             context_, bb,
-            ir::IRContext::kAnalysisDefUse |
-                ir::IRContext::kAnalysisInstrToBlockMapping);
+            opt::IRContext::kAnalysisDefUse |
+                opt::IRContext::kAnalysisInstrToBlockMapping);
         builder.AddBranch(live_target);
       }
     }
@@ -662,7 +663,7 @@
     // Go through the loop basic block and tag all blocks that are obviously
     // dead.
     std::unordered_set<uint32_t> visited;
-    for (ir::BasicBlock& bb : block_range) {
+    for (opt::BasicBlock& bb : block_range) {
       if (ignore_node(bb.id())) continue;
       visited.insert(bb.id());
 
@@ -677,12 +678,12 @@
       }
       if (!has_live_pred) {
         dead_blocks->insert(bb.id());
-        const ir::BasicBlock& cbb = bb;
+        const opt::BasicBlock& cbb = bb;
         // Patch the phis for any back-edge.
         cbb.ForEachSuccessorLabel(
             [dead_blocks, &visited, &cfg, this](uint32_t id) {
               if (!visited.count(id) || dead_blocks->count(id)) return;
-              ir::BasicBlock* succ = cfg.block(id);
+              opt::BasicBlock* succ = cfg.block(id);
               PatchPhis(succ, *dead_blocks, false);
             });
         continue;
@@ -694,7 +695,7 @@
 
   // Returns true if the header is not reachable or tagged as dead or if we
   // never loop back.
-  bool IsLoopDead(ir::BasicBlock* header, ir::BasicBlock* latch,
+  bool IsLoopDead(opt::BasicBlock* header, opt::BasicBlock* latch,
                   const std::unordered_set<uint32_t>& dead_blocks) {
     if (!header || dead_blocks.count(header->id())) return true;
     if (!latch || dead_blocks.count(latch->id())) return true;
@@ -714,14 +715,14 @@
   // |unreachable_merges|.
   // The function returns the pointer to |loop| or nullptr if the loop was
   // killed.
-  ir::Loop* CleanLoopNest(ir::Loop* loop,
-                          const std::unordered_set<uint32_t>& dead_blocks,
-                          std::unordered_set<uint32_t>* unreachable_merges) {
+  opt::Loop* CleanLoopNest(opt::Loop* loop,
+                           const std::unordered_set<uint32_t>& dead_blocks,
+                           std::unordered_set<uint32_t>* unreachable_merges) {
     // This represent the pair of dead loop and nearest alive parent (nullptr if
     // no parent).
-    std::unordered_map<ir::Loop*, ir::Loop*> dead_loops;
-    auto get_parent = [&dead_loops](ir::Loop* l) -> ir::Loop* {
-      std::unordered_map<ir::Loop*, ir::Loop*>::iterator it =
+    std::unordered_map<opt::Loop*, opt::Loop*> dead_loops;
+    auto get_parent = [&dead_loops](opt::Loop* l) -> opt::Loop* {
+      std::unordered_map<opt::Loop*, opt::Loop*>::iterator it =
           dead_loops.find(l);
       if (it != dead_loops.end()) return it->second;
       return nullptr;
@@ -730,7 +731,8 @@
     bool is_main_loop_dead =
         IsLoopDead(loop->GetHeaderBlock(), loop->GetLatchBlock(), dead_blocks);
     if (is_main_loop_dead) {
-      if (ir::Instruction* merge = loop->GetHeaderBlock()->GetLoopMergeInst()) {
+      if (opt::Instruction* merge =
+              loop->GetHeaderBlock()->GetLoopMergeInst()) {
         context_->KillInst(merge);
       }
       dead_loops[loop] = loop->GetParent();
@@ -738,12 +740,12 @@
       dead_loops[loop] = loop;
     // For each loop, check if we killed it. If we did, find a suitable parent
     // for its children.
-    for (ir::Loop& sub_loop :
-         ir::make_range(++opt::TreeDFIterator<ir::Loop>(loop),
-                        opt::TreeDFIterator<ir::Loop>())) {
+    for (opt::Loop& sub_loop :
+         opt::make_range(++opt::TreeDFIterator<opt::Loop>(loop),
+                         opt::TreeDFIterator<opt::Loop>())) {
       if (IsLoopDead(sub_loop.GetHeaderBlock(), sub_loop.GetLatchBlock(),
                      dead_blocks)) {
-        if (ir::Instruction* merge =
+        if (opt::Instruction* merge =
                 sub_loop.GetHeaderBlock()->GetLoopMergeInst()) {
           context_->KillInst(merge);
         }
@@ -763,7 +765,7 @@
 
     // Remove dead blocks from live loops.
     for (uint32_t bb_id : dead_blocks) {
-      ir::Loop* l = loop_desc_[bb_id];
+      opt::Loop* l = loop_desc_[bb_id];
       if (l) {
         l->RemoveBasicBlock(bb_id);
         loop_desc_.ForgetBasicBlock(bb_id);
@@ -772,8 +774,8 @@
 
     std::for_each(
         dead_loops.begin(), dead_loops.end(),
-        [&loop, this](
-            std::unordered_map<ir::Loop*, ir::Loop*>::iterator::reference it) {
+        [&loop, this](std::unordered_map<opt::Loop*,
+                                         opt::Loop*>::iterator::reference it) {
           if (it.first == loop) loop = nullptr;
           loop_desc_.RemoveLoop(it.first);
         });
@@ -783,7 +785,7 @@
 
   // Returns true if |var| is dynamically uniform.
   // Note: this is currently approximated as uniform.
-  bool IsDynamicallyUniform(ir::Instruction* var, const ir::BasicBlock* entry,
+  bool IsDynamicallyUniform(opt::Instruction* var, const opt::BasicBlock* entry,
                             const DominatorTree& post_dom_tree) {
     assert(post_dom_tree.IsPostDominator());
     analysis::DefUseManager* def_use_mgr = context_->get_def_use_mgr();
@@ -798,7 +800,7 @@
     is_uniform = false;
 
     dec_mgr->WhileEachDecoration(var->result_id(), SpvDecorationUniform,
-                                 [&is_uniform](const ir::Instruction&) {
+                                 [&is_uniform](const opt::Instruction&) {
                                    is_uniform = true;
                                    return false;
                                  });
@@ -806,7 +808,7 @@
       return is_uniform;
     }
 
-    ir::BasicBlock* parent = context_->get_instr_block(var);
+    opt::BasicBlock* parent = context_->get_instr_block(var);
     if (!parent) {
       return is_uniform = true;
     }
@@ -817,7 +819,7 @@
     if (var->opcode() == SpvOpLoad) {
       const uint32_t PtrTypeId =
           def_use_mgr->GetDef(var->GetSingleWordInOperand(0))->type_id();
-      const ir::Instruction* PtrTypeInst = def_use_mgr->GetDef(PtrTypeId);
+      const opt::Instruction* PtrTypeInst = def_use_mgr->GetDef(PtrTypeId);
       uint32_t storage_class =
           PtrTypeInst->GetSingleWordInOperand(kTypePointerStorageClassInIdx);
       if (storage_class != SpvStorageClassUniform &&
@@ -838,12 +840,12 @@
   }
 
   // Returns true if |insn| is constant and dynamically uniform within the loop.
-  bool IsConditionLoopInvariant(ir::Instruction* insn) {
+  bool IsConditionLoopInvariant(opt::Instruction* insn) {
     assert(insn->IsBranch());
     assert(insn->opcode() != SpvOpBranch);
     analysis::DefUseManager* def_use_mgr = context_->get_def_use_mgr();
 
-    ir::Instruction* condition =
+    opt::Instruction* condition =
         def_use_mgr->GetDef(insn->GetOperand(0).words[0]);
     return !loop_->IsInsideLoop(condition) &&
            IsDynamicallyUniform(
@@ -854,33 +856,33 @@
 
 }  // namespace
 
-Pass::Status LoopUnswitchPass::Process(ir::IRContext* c) {
+Pass::Status LoopUnswitchPass::Process(opt::IRContext* c) {
   InitializeProcessing(c);
 
   bool modified = false;
-  ir::Module* module = c->module();
+  opt::Module* module = c->module();
 
   // Process each function in the module
-  for (ir::Function& f : *module) {
+  for (opt::Function& f : *module) {
     modified |= ProcessFunction(&f);
   }
 
   return modified ? Status::SuccessWithChange : Status::SuccessWithoutChange;
 }
 
-bool LoopUnswitchPass::ProcessFunction(ir::Function* f) {
+bool LoopUnswitchPass::ProcessFunction(opt::Function* f) {
   bool modified = false;
-  std::unordered_set<ir::Loop*> processed_loop;
+  std::unordered_set<opt::Loop*> processed_loop;
 
-  ir::LoopDescriptor& loop_descriptor = *context()->GetLoopDescriptor(f);
+  opt::LoopDescriptor& loop_descriptor = *context()->GetLoopDescriptor(f);
 
   bool loop_changed = true;
   while (loop_changed) {
     loop_changed = false;
-    for (ir::Loop& loop :
-         ir::make_range(++opt::TreeDFIterator<ir::Loop>(
-                            loop_descriptor.GetDummyRootLoop()),
-                        opt::TreeDFIterator<ir::Loop>())) {
+    for (opt::Loop& loop :
+         opt::make_range(++opt::TreeDFIterator<opt::Loop>(
+                             loop_descriptor.GetDummyRootLoop()),
+                         opt::TreeDFIterator<opt::Loop>())) {
       if (processed_loop.count(&loop)) continue;
       processed_loop.insert(&loop);
 
diff --git a/source/opt/loop_unswitch_pass.h b/source/opt/loop_unswitch_pass.h
index dbe5814..8a087f3 100644
--- a/source/opt/loop_unswitch_pass.h
+++ b/source/opt/loop_unswitch_pass.h
@@ -31,10 +31,10 @@
   // Processes the given |module|. Returns Status::Failure if errors occur when
   // processing. Returns the corresponding Status::Success if processing is
   // succesful to indicate whether changes have been made to the modue.
-  Pass::Status Process(ir::IRContext* context) override;
+  Pass::Status Process(opt::IRContext* context) override;
 
  private:
-  bool ProcessFunction(ir::Function* f);
+  bool ProcessFunction(opt::Function* f);
 };
 
 }  // namespace opt
diff --git a/source/opt/loop_utils.cpp b/source/opt/loop_utils.cpp
index 8b7c932..28f0239 100644
--- a/source/opt/loop_utils.cpp
+++ b/source/opt/loop_utils.cpp
@@ -31,9 +31,9 @@
 namespace {
 // Return true if |bb| is dominated by at least one block in |exits|
 static inline bool DominatesAnExit(
-    ir::BasicBlock* bb, const std::unordered_set<ir::BasicBlock*>& exits,
+    opt::BasicBlock* bb, const std::unordered_set<opt::BasicBlock*>& exits,
     const opt::DominatorTree& dom_tree) {
-  for (ir::BasicBlock* e_bb : exits)
+  for (opt::BasicBlock* e_bb : exits)
     if (dom_tree.Dominates(bb, e_bb)) return true;
   return false;
 }
@@ -47,9 +47,9 @@
 // instruction to merge the incoming value according to exit blocks definition.
 class LCSSARewriter {
  public:
-  LCSSARewriter(ir::IRContext* context, const opt::DominatorTree& dom_tree,
-                const std::unordered_set<ir::BasicBlock*>& exit_bb,
-                ir::BasicBlock* merge_block)
+  LCSSARewriter(opt::IRContext* context, const opt::DominatorTree& dom_tree,
+                const std::unordered_set<opt::BasicBlock*>& exit_bb,
+                opt::BasicBlock* merge_block)
       : context_(context),
         cfg_(context_->cfg()),
         dom_tree_(dom_tree),
@@ -57,7 +57,7 @@
         merge_block_id_(merge_block ? merge_block->id() : 0) {}
 
   struct UseRewriter {
-    explicit UseRewriter(LCSSARewriter* base, const ir::Instruction& def_insn)
+    explicit UseRewriter(LCSSARewriter* base, const opt::Instruction& def_insn)
         : base_(base), def_insn_(def_insn) {}
     // Rewrites the use of |def_insn_| by the instruction |user| at the index
     // |operand_index| in terms of phi instruction. This recursively builds new
@@ -68,7 +68,7 @@
     // block. This operation does not update the def/use manager, instead it
     // records what needs to be updated. The actual update is performed by
     // UpdateManagers.
-    void RewriteUse(ir::BasicBlock* bb, ir::Instruction* user,
+    void RewriteUse(opt::BasicBlock* bb, opt::Instruction* user,
                     uint32_t operand_index) {
       assert(
           (user->opcode() != SpvOpPhi || bb != GetParent(user)) &&
@@ -79,7 +79,7 @@
              "not "
              "phi instruction");
 
-      ir::Instruction* new_def = GetOrBuildIncoming(bb->id());
+      opt::Instruction* new_def = GetOrBuildIncoming(bb->id());
 
       user->SetOperand(operand_index, {new_def->result_id()});
       rewritten_.insert(user);
@@ -90,26 +90,26 @@
       opt::analysis::DefUseManager* def_use_mgr =
           base_->context_->get_def_use_mgr();
       // Register all new definitions.
-      for (ir::Instruction* insn : rewritten_) {
+      for (opt::Instruction* insn : rewritten_) {
         def_use_mgr->AnalyzeInstDef(insn);
       }
       // Register all new uses.
-      for (ir::Instruction* insn : rewritten_) {
+      for (opt::Instruction* insn : rewritten_) {
         def_use_mgr->AnalyzeInstUse(insn);
       }
     }
 
    private:
     // Return the basic block that |instr| belongs to.
-    ir::BasicBlock* GetParent(ir::Instruction* instr) {
+    opt::BasicBlock* GetParent(opt::Instruction* instr) {
       return base_->context_->get_instr_block(instr);
     }
 
     // Builds a phi instruction for the basic block |bb|. The function assumes
     // that |defining_blocks| contains the list of basic block that define the
     // usable value for each predecessor of |bb|.
-    inline ir::Instruction* CreatePhiInstruction(
-        ir::BasicBlock* bb, const std::vector<uint32_t>& defining_blocks) {
+    inline opt::Instruction* CreatePhiInstruction(
+        opt::BasicBlock* bb, const std::vector<uint32_t>& defining_blocks) {
       std::vector<uint32_t> incomings;
       const std::vector<uint32_t>& bb_preds = base_->cfg_->preds(bb->id());
       assert(bb_preds.size() == defining_blocks.size());
@@ -120,8 +120,8 @@
       }
       opt::InstructionBuilder builder(
           base_->context_, &*bb->begin(),
-          ir::IRContext::kAnalysisInstrToBlockMapping);
-      ir::Instruction* incoming_phi =
+          opt::IRContext::kAnalysisInstrToBlockMapping);
+      opt::Instruction* incoming_phi =
           builder.AddPhi(def_insn_.type_id(), incomings);
 
       rewritten_.insert(incoming_phi);
@@ -130,8 +130,8 @@
 
     // Builds a phi instruction for the basic block |bb|, all incoming values
     // will be |value|.
-    inline ir::Instruction* CreatePhiInstruction(ir::BasicBlock* bb,
-                                                 const ir::Instruction& value) {
+    inline opt::Instruction* CreatePhiInstruction(
+        opt::BasicBlock* bb, const opt::Instruction& value) {
       std::vector<uint32_t> incomings;
       const std::vector<uint32_t>& bb_preds = base_->cfg_->preds(bb->id());
       for (size_t i = 0; i < bb_preds.size(); i++) {
@@ -140,8 +140,8 @@
       }
       opt::InstructionBuilder builder(
           base_->context_, &*bb->begin(),
-          ir::IRContext::kAnalysisInstrToBlockMapping);
-      ir::Instruction* incoming_phi =
+          opt::IRContext::kAnalysisInstrToBlockMapping);
+      opt::Instruction* incoming_phi =
           builder.AddPhi(def_insn_.type_id(), incomings);
 
       rewritten_.insert(incoming_phi);
@@ -153,21 +153,21 @@
     //   - return the common def used by all predecessors;
     //   - if there is no common def, then we build a new phi instr at the
     //     beginning of |bb_id| and return this new instruction.
-    ir::Instruction* GetOrBuildIncoming(uint32_t bb_id) {
+    opt::Instruction* GetOrBuildIncoming(uint32_t bb_id) {
       assert(base_->cfg_->block(bb_id) != nullptr && "Unknown basic block");
 
-      ir::Instruction*& incoming_phi = bb_to_phi_[bb_id];
+      opt::Instruction*& incoming_phi = bb_to_phi_[bb_id];
       if (incoming_phi) {
         return incoming_phi;
       }
 
-      ir::BasicBlock* bb = &*base_->cfg_->block(bb_id);
+      opt::BasicBlock* bb = &*base_->cfg_->block(bb_id);
       // If this is an exit basic block, look if there already is an eligible
       // phi instruction. An eligible phi has |def_insn_| as all incoming
       // values.
       if (base_->exit_bb_.count(bb)) {
         // Look if there is an eligible phi in this block.
-        if (!bb->WhileEachPhiInst([&incoming_phi, this](ir::Instruction* phi) {
+        if (!bb->WhileEachPhiInst([&incoming_phi, this](opt::Instruction* phi) {
               for (uint32_t i = 0; i < phi->NumInOperands(); i += 2) {
                 if (phi->GetSingleWordInOperand(i) != def_insn_.result_id())
                   return true;
@@ -208,9 +208,9 @@
     }
 
     LCSSARewriter* base_;
-    const ir::Instruction& def_insn_;
-    std::unordered_map<uint32_t, ir::Instruction*> bb_to_phi_;
-    std::unordered_set<ir::Instruction*> rewritten_;
+    const opt::Instruction& def_insn_;
+    std::unordered_map<uint32_t, opt::Instruction*> bb_to_phi_;
+    std::unordered_set<opt::Instruction*> rewritten_;
   };
 
  private:
@@ -226,7 +226,7 @@
     if (defining_blocks.size()) return defining_blocks;
 
     // Check if one of the loop exit basic block dominates |bb_id|.
-    for (const ir::BasicBlock* e_bb : exit_bb_) {
+    for (const opt::BasicBlock* e_bb : exit_bb_) {
       if (dom_tree_.Dominates(e_bb->id(), bb_id)) {
         defining_blocks.push_back(e_bb->id());
         return defining_blocks;
@@ -255,10 +255,10 @@
     return defining_blocks;
   }
 
-  ir::IRContext* context_;
-  ir::CFG* cfg_;
+  opt::IRContext* context_;
+  opt::CFG* cfg_;
   const opt::DominatorTree& dom_tree_;
-  const std::unordered_set<ir::BasicBlock*>& exit_bb_;
+  const std::unordered_set<opt::BasicBlock*>& exit_bb_;
   uint32_t merge_block_id_;
   // This map represent the set of known paths. For each key, the vector
   // represent the set of blocks holding the definition to be used to build the
@@ -274,25 +274,26 @@
 // Make the set |blocks| closed SSA. The set is closed SSA if all the uses
 // outside the set are phi instructions in exiting basic block set (hold by
 // |lcssa_rewriter|).
-inline void MakeSetClosedSSA(ir::IRContext* context, ir::Function* function,
-                             const std::unordered_set<uint32_t>& blocks,
-                             const std::unordered_set<ir::BasicBlock*>& exit_bb,
-                             LCSSARewriter* lcssa_rewriter) {
-  ir::CFG& cfg = *context->cfg();
+inline void MakeSetClosedSSA(
+    opt::IRContext* context, opt::Function* function,
+    const std::unordered_set<uint32_t>& blocks,
+    const std::unordered_set<opt::BasicBlock*>& exit_bb,
+    LCSSARewriter* lcssa_rewriter) {
+  opt::CFG& cfg = *context->cfg();
   opt::DominatorTree& dom_tree =
       context->GetDominatorAnalysis(function)->GetDomTree();
   opt::analysis::DefUseManager* def_use_manager = context->get_def_use_mgr();
 
   for (uint32_t bb_id : blocks) {
-    ir::BasicBlock* bb = cfg.block(bb_id);
+    opt::BasicBlock* bb = cfg.block(bb_id);
     // If bb does not dominate an exit block, then it cannot have escaping defs.
     if (!DominatesAnExit(bb, exit_bb, dom_tree)) continue;
-    for (ir::Instruction& inst : *bb) {
+    for (opt::Instruction& inst : *bb) {
       LCSSARewriter::UseRewriter rewriter(lcssa_rewriter, inst);
       def_use_manager->ForEachUse(
           &inst, [&blocks, &rewriter, &exit_bb, context](
-                     ir::Instruction* use, uint32_t operand_index) {
-            ir::BasicBlock* use_parent = context->get_instr_block(use);
+                     opt::Instruction* use, uint32_t operand_index) {
+            opt::BasicBlock* use_parent = context->get_instr_block(use);
             assert(use_parent);
             if (blocks.count(use_parent->id())) return;
 
@@ -320,26 +321,26 @@
 }  // namespace
 
 void LoopUtils::CreateLoopDedicatedExits() {
-  ir::Function* function = loop_->GetHeaderBlock()->GetParent();
-  ir::LoopDescriptor& loop_desc = *context_->GetLoopDescriptor(function);
-  ir::CFG& cfg = *context_->cfg();
+  opt::Function* function = loop_->GetHeaderBlock()->GetParent();
+  opt::LoopDescriptor& loop_desc = *context_->GetLoopDescriptor(function);
+  opt::CFG& cfg = *context_->cfg();
   opt::analysis::DefUseManager* def_use_mgr = context_->get_def_use_mgr();
 
-  const ir::IRContext::Analysis PreservedAnalyses =
-      ir::IRContext::kAnalysisDefUse |
-      ir::IRContext::kAnalysisInstrToBlockMapping;
+  const opt::IRContext::Analysis PreservedAnalyses =
+      opt::IRContext::kAnalysisDefUse |
+      opt::IRContext::kAnalysisInstrToBlockMapping;
 
   // Gathers the set of basic block that are not in this loop and have at least
   // one predecessor in the loop and one not in the loop.
   std::unordered_set<uint32_t> exit_bb_set;
   loop_->GetExitBlocks(&exit_bb_set);
 
-  std::unordered_set<ir::BasicBlock*> new_loop_exits;
+  std::unordered_set<opt::BasicBlock*> new_loop_exits;
   bool made_change = false;
   // For each block, we create a new one that gathers all branches from
   // the loop and fall into the block.
   for (uint32_t non_dedicate_id : exit_bb_set) {
-    ir::BasicBlock* non_dedicate = cfg.block(non_dedicate_id);
+    opt::BasicBlock* non_dedicate = cfg.block(non_dedicate_id);
     const std::vector<uint32_t>& bb_pred = cfg.preds(non_dedicate_id);
     // Ignore the block if all the predecessors are in the loop.
     if (std::all_of(bb_pred.begin(), bb_pred.end(),
@@ -349,23 +350,23 @@
     }
 
     made_change = true;
-    ir::Function::iterator insert_pt = function->begin();
+    opt::Function::iterator insert_pt = function->begin();
     for (; insert_pt != function->end() && &*insert_pt != non_dedicate;
          ++insert_pt) {
     }
     assert(insert_pt != function->end() && "Basic Block not found");
 
     // Create the dedicate exit basic block.
-    ir::BasicBlock& exit = *insert_pt.InsertBefore(
-        std::unique_ptr<ir::BasicBlock>(new ir::BasicBlock(
-            std::unique_ptr<ir::Instruction>(new ir::Instruction(
+    opt::BasicBlock& exit = *insert_pt.InsertBefore(
+        std::unique_ptr<opt::BasicBlock>(new opt::BasicBlock(
+            std::unique_ptr<opt::Instruction>(new opt::Instruction(
                 context_, SpvOpLabel, 0, context_->TakeNextId(), {})))));
     exit.SetParent(function);
 
     // Redirect in loop predecessors to |exit| block.
     for (uint32_t exit_pred_id : bb_pred) {
       if (loop_->IsInsideLoop(exit_pred_id)) {
-        ir::BasicBlock* pred_block = cfg.block(exit_pred_id);
+        opt::BasicBlock* pred_block = cfg.block(exit_pred_id);
         pred_block->ForEachSuccessorLabel([non_dedicate, &exit](uint32_t* id) {
           if (*id == non_dedicate->id()) *id = exit.id();
         });
@@ -386,7 +387,7 @@
     // the branch.
     builder.SetInsertPoint(builder.AddBranch(non_dedicate->id()));
     non_dedicate->ForEachPhiInst([&builder, &exit, def_use_mgr,
-                                  this](ir::Instruction* phi) {
+                                  this](opt::Instruction* phi) {
       // New phi operands for this instruction.
       std::vector<uint32_t> new_phi_op;
       // Phi operands for the dedicated exit block.
@@ -404,7 +405,7 @@
       }
 
       // Build the new phi instruction dedicated exit block.
-      ir::Instruction* exit_phi = builder.AddPhi(phi->type_id(), exit_phi_op);
+      opt::Instruction* exit_phi = builder.AddPhi(phi->type_id(), exit_phi_op);
       // Build the new incoming branch.
       new_phi_op.push_back(exit_phi->result_id());
       new_phi_op.push_back(exit.id());
@@ -423,7 +424,7 @@
     cfg.RemoveNonExistingEdges(non_dedicate->id());
     new_loop_exits.insert(&exit);
     // If non_dedicate is in a loop, add the new dedicated exit in that loop.
-    if (ir::Loop* parent_loop = loop_desc[non_dedicate])
+    if (opt::Loop* parent_loop = loop_desc[non_dedicate])
       parent_loop->AddBasicBlock(&exit);
   }
 
@@ -433,20 +434,20 @@
 
   if (made_change) {
     context_->InvalidateAnalysesExceptFor(
-        PreservedAnalyses | ir::IRContext::kAnalysisCFG |
-        ir::IRContext::Analysis::kAnalysisLoopAnalysis);
+        PreservedAnalyses | opt::IRContext::kAnalysisCFG |
+        opt::IRContext::Analysis::kAnalysisLoopAnalysis);
   }
 }
 
 void LoopUtils::MakeLoopClosedSSA() {
   CreateLoopDedicatedExits();
 
-  ir::Function* function = loop_->GetHeaderBlock()->GetParent();
-  ir::CFG& cfg = *context_->cfg();
+  opt::Function* function = loop_->GetHeaderBlock()->GetParent();
+  opt::CFG& cfg = *context_->cfg();
   opt::DominatorTree& dom_tree =
       context_->GetDominatorAnalysis(function)->GetDomTree();
 
-  std::unordered_set<ir::BasicBlock*> exit_bb;
+  std::unordered_set<opt::BasicBlock*> exit_bb;
   {
     std::unordered_set<uint32_t> exit_bb_id;
     loop_->GetExitBlocks(&exit_bb_id);
@@ -476,31 +477,31 @@
   }
 
   context_->InvalidateAnalysesExceptFor(
-      ir::IRContext::Analysis::kAnalysisCFG |
-      ir::IRContext::Analysis::kAnalysisDominatorAnalysis |
-      ir::IRContext::Analysis::kAnalysisLoopAnalysis);
+      opt::IRContext::Analysis::kAnalysisCFG |
+      opt::IRContext::Analysis::kAnalysisDominatorAnalysis |
+      opt::IRContext::Analysis::kAnalysisLoopAnalysis);
 }
 
-ir::Loop* LoopUtils::CloneLoop(LoopCloningResult* cloning_result) const {
+opt::Loop* LoopUtils::CloneLoop(LoopCloningResult* cloning_result) const {
   // Compute the structured order of the loop basic blocks and store it in the
   // vector ordered_loop_blocks.
-  std::vector<ir::BasicBlock*> ordered_loop_blocks;
+  std::vector<opt::BasicBlock*> ordered_loop_blocks;
   loop_->ComputeLoopStructuredOrder(&ordered_loop_blocks);
 
   // Clone the loop.
   return CloneLoop(cloning_result, ordered_loop_blocks);
 }
 
-ir::Loop* LoopUtils::CloneAndAttachLoopToHeader(
+opt::Loop* LoopUtils::CloneAndAttachLoopToHeader(
     LoopCloningResult* cloning_result) {
   // Clone the loop.
-  ir::Loop* new_loop = CloneLoop(cloning_result);
+  opt::Loop* new_loop = CloneLoop(cloning_result);
 
   // Create a new exit block/label for the new loop.
-  std::unique_ptr<ir::Instruction> new_label{new ir::Instruction(
+  std::unique_ptr<opt::Instruction> new_label{new opt::Instruction(
       context_, SpvOp::SpvOpLabel, 0, context_->TakeNextId(), {})};
-  std::unique_ptr<ir::BasicBlock> new_exit_bb{
-      new ir::BasicBlock(std::move(new_label))};
+  std::unique_ptr<opt::BasicBlock> new_exit_bb{
+      new opt::BasicBlock(std::move(new_label))};
   new_exit_bb->SetParent(loop_->GetMergeBlock()->GetParent());
 
   // Create an unconditional branch to the header block.
@@ -513,9 +514,9 @@
 
   // Replace the uses of the old merge block in the new loop with the new merge
   // block.
-  for (std::unique_ptr<ir::BasicBlock>& basic_block :
+  for (std::unique_ptr<opt::BasicBlock>& basic_block :
        cloning_result->cloned_bb_) {
-    for (ir::Instruction& inst : *basic_block) {
+    for (opt::Instruction& inst : *basic_block) {
       // For each operand in each instruction check if it is using the old merge
       // block and change it to be the new merge block.
       auto replace_merge_use = [old_merge_block,
@@ -531,14 +532,14 @@
   opt::analysis::DefUseManager* def_use = context_->get_def_use_mgr();
 
   def_use->ForEachUse(
-      old_header, [new_header, this](ir::Instruction* inst, uint32_t operand) {
+      old_header, [new_header, this](opt::Instruction* inst, uint32_t operand) {
         if (!this->loop_->IsInsideLoop(inst))
           inst->SetOperand(operand, {new_header});
       });
 
   def_use->ForEachUse(
       loop_->GetOrCreatePreHeaderBlock()->id(),
-      [new_merge_block, this](ir::Instruction* inst, uint32_t operand) {
+      [new_merge_block, this](opt::Instruction* inst, uint32_t operand) {
         if (this->loop_->IsInsideLoop(inst))
           inst->SetOperand(operand, {new_merge_block});
 
@@ -553,20 +554,20 @@
   return new_loop;
 }
 
-ir::Loop* LoopUtils::CloneLoop(
+opt::Loop* LoopUtils::CloneLoop(
     LoopCloningResult* cloning_result,
-    const std::vector<ir::BasicBlock*>& ordered_loop_blocks) const {
+    const std::vector<opt::BasicBlock*>& ordered_loop_blocks) const {
   analysis::DefUseManager* def_use_mgr = context_->get_def_use_mgr();
 
-  std::unique_ptr<ir::Loop> new_loop = MakeUnique<ir::Loop>(context_);
+  std::unique_ptr<opt::Loop> new_loop = MakeUnique<opt::Loop>(context_);
 
-  ir::CFG& cfg = *context_->cfg();
+  opt::CFG& cfg = *context_->cfg();
 
   // Clone and place blocks in a SPIR-V compliant order (dominators first).
-  for (ir::BasicBlock* old_bb : ordered_loop_blocks) {
+  for (opt::BasicBlock* old_bb : ordered_loop_blocks) {
     // For each basic block in the loop, we clone it and register the mapping
     // between old and new ids.
-    ir::BasicBlock* new_bb = old_bb->Clone(context_);
+    opt::BasicBlock* new_bb = old_bb->Clone(context_);
     new_bb->SetParent(&function_);
     new_bb->GetLabelInst()->SetResultId(context_->TakeNextId());
     def_use_mgr->AnalyzeInstDef(new_bb->GetLabelInst());
@@ -595,10 +596,10 @@
 
   // All instructions (including all labels) have been cloned,
   // remap instruction operands id with the new ones.
-  for (std::unique_ptr<ir::BasicBlock>& bb_ref : cloning_result->cloned_bb_) {
-    ir::BasicBlock* bb = bb_ref.get();
+  for (std::unique_ptr<opt::BasicBlock>& bb_ref : cloning_result->cloned_bb_) {
+    opt::BasicBlock* bb = bb_ref.get();
 
-    for (ir::Instruction& insn : *bb) {
+    for (opt::Instruction& insn : *bb) {
       insn.ForEachInId([cloning_result](uint32_t* old_id) {
         // If the operand is defined in the loop, remap the id.
         auto id_it = cloning_result->value_map_.find(*old_id);
@@ -620,32 +621,32 @@
 }
 
 void LoopUtils::PopulateLoopNest(
-    ir::Loop* new_loop, const LoopCloningResult& cloning_result) const {
-  std::unordered_map<ir::Loop*, ir::Loop*> loop_mapping;
+    opt::Loop* new_loop, const LoopCloningResult& cloning_result) const {
+  std::unordered_map<opt::Loop*, opt::Loop*> loop_mapping;
   loop_mapping[loop_] = new_loop;
 
   if (loop_->HasParent()) loop_->GetParent()->AddNestedLoop(new_loop);
   PopulateLoopDesc(new_loop, loop_, cloning_result);
 
-  for (ir::Loop& sub_loop :
-       ir::make_range(++opt::TreeDFIterator<ir::Loop>(loop_),
-                      opt::TreeDFIterator<ir::Loop>())) {
-    ir::Loop* cloned = new ir::Loop(context_);
-    if (ir::Loop* parent = loop_mapping[sub_loop.GetParent()])
+  for (opt::Loop& sub_loop :
+       opt::make_range(++opt::TreeDFIterator<opt::Loop>(loop_),
+                       opt::TreeDFIterator<opt::Loop>())) {
+    opt::Loop* cloned = new opt::Loop(context_);
+    if (opt::Loop* parent = loop_mapping[sub_loop.GetParent()])
       parent->AddNestedLoop(cloned);
     loop_mapping[&sub_loop] = cloned;
     PopulateLoopDesc(cloned, &sub_loop, cloning_result);
   }
 
-  loop_desc_->AddLoopNest(std::unique_ptr<ir::Loop>(new_loop));
+  loop_desc_->AddLoopNest(std::unique_ptr<opt::Loop>(new_loop));
 }
 
 // Populates |new_loop| descriptor according to |old_loop|'s one.
 void LoopUtils::PopulateLoopDesc(
-    ir::Loop* new_loop, ir::Loop* old_loop,
+    opt::Loop* new_loop, opt::Loop* old_loop,
     const LoopCloningResult& cloning_result) const {
   for (uint32_t bb_id : old_loop->GetBlocks()) {
-    ir::BasicBlock* bb = cloning_result.old_to_new_bb_.at(bb_id);
+    opt::BasicBlock* bb = cloning_result.old_to_new_bb_.at(bb_id);
     new_loop->AddBasicBlock(bb);
   }
   new_loop->SetHeaderBlock(
@@ -659,9 +660,9 @@
   if (old_loop->GetMergeBlock()) {
     auto it =
         cloning_result.old_to_new_bb_.find(old_loop->GetMergeBlock()->id());
-    ir::BasicBlock* bb = it != cloning_result.old_to_new_bb_.end()
-                             ? it->second
-                             : old_loop->GetMergeBlock();
+    opt::BasicBlock* bb = it != cloning_result.old_to_new_bb_.end()
+                              ? it->second
+                              : old_loop->GetMergeBlock();
     new_loop->SetMergeBlock(bb);
   }
   if (old_loop->GetPreHeaderBlock()) {
@@ -674,16 +675,16 @@
 }
 
 // Class to gather some metrics about a region of interest.
-void CodeMetrics::Analyze(const ir::Loop& loop) {
-  ir::CFG& cfg = *loop.GetContext()->cfg();
+void CodeMetrics::Analyze(const opt::Loop& loop) {
+  opt::CFG& cfg = *loop.GetContext()->cfg();
 
   roi_size_ = 0;
   block_sizes_.clear();
 
   for (uint32_t id : loop.GetBlocks()) {
-    const ir::BasicBlock* bb = cfg.block(id);
+    const opt::BasicBlock* bb = cfg.block(id);
     size_t bb_size = 0;
-    bb->ForEachInst([&bb_size](const ir::Instruction* insn) {
+    bb->ForEachInst([&bb_size](const opt::Instruction* insn) {
       if (insn->opcode() == SpvOpLabel) return;
       if (insn->IsNop()) return;
       if (insn->opcode() == SpvOpPhi) return;
diff --git a/source/opt/loop_utils.h b/source/opt/loop_utils.h
index de3ff2b..a3845b4 100644
--- a/source/opt/loop_utils.h
+++ b/source/opt/loop_utils.h
@@ -28,7 +28,7 @@
 // So far it counts the number of instructions in a ROI (excluding debug
 // and label instructions) per basic block and in total.
 struct CodeMetrics {
-  void Analyze(const ir::Loop& loop);
+  void Analyze(const opt::Loop& loop);
 
   // The number of instructions per basic block in the ROI.
   std::unordered_map<uint32_t, size_t> block_sizes_;
@@ -45,8 +45,8 @@
   // Holds a auxiliary results of the loop cloning procedure.
   struct LoopCloningResult {
     using ValueMapTy = std::unordered_map<uint32_t, uint32_t>;
-    using BlockMapTy = std::unordered_map<uint32_t, ir::BasicBlock*>;
-    using PtrMap = std::unordered_map<ir::Instruction*, ir::Instruction*>;
+    using BlockMapTy = std::unordered_map<uint32_t, opt::BasicBlock*>;
+    using PtrMap = std::unordered_map<opt::Instruction*, opt::Instruction*>;
 
     PtrMap ptr_map_;
 
@@ -57,10 +57,10 @@
     // Mapping between the cloned loop blocks to original one.
     BlockMapTy new_to_old_bb_;
     // List of cloned basic block.
-    std::vector<std::unique_ptr<ir::BasicBlock>> cloned_bb_;
+    std::vector<std::unique_ptr<opt::BasicBlock>> cloned_bb_;
   };
 
-  LoopUtils(ir::IRContext* context, ir::Loop* loop)
+  LoopUtils(opt::IRContext* context, opt::Loop* loop)
       : context_(context),
         loop_desc_(
             context->GetLoopDescriptor(loop->GetHeaderBlock()->GetParent())),
@@ -111,15 +111,15 @@
   // The function preserves the def/use, cfg and instr to block analyses.
   // The cloned loop nest will be added to the loop descriptor and will have
   // ownership.
-  ir::Loop* CloneLoop(
+  opt::Loop* CloneLoop(
       LoopCloningResult* cloning_result,
-      const std::vector<ir::BasicBlock*>& ordered_loop_blocks) const;
+      const std::vector<opt::BasicBlock*>& ordered_loop_blocks) const;
   // Clone |loop_| and remap its instructions, as above. Overload to compute
   // loop block ordering within method rather than taking in as parameter.
-  ir::Loop* CloneLoop(LoopCloningResult* cloning_result) const;
+  opt::Loop* CloneLoop(LoopCloningResult* cloning_result) const;
 
   // Clone the |loop_| and make the new loop branch to the second loop on exit.
-  ir::Loop* CloneAndAttachLoopToHeader(LoopCloningResult* cloning_result);
+  opt::Loop* CloneAndAttachLoopToHeader(LoopCloningResult* cloning_result);
 
   // Perfom a partial unroll of |loop| by given |factor|. This will copy the
   // body of the loop |factor| times. So a |factor| of one would give a new loop
@@ -151,26 +151,26 @@
   void Finalize();
 
   // Returns the context associate to |loop_|.
-  ir::IRContext* GetContext() { return context_; }
+  opt::IRContext* GetContext() { return context_; }
   // Returns the loop descriptor owning |loop_|.
-  ir::LoopDescriptor* GetLoopDescriptor() { return loop_desc_; }
+  opt::LoopDescriptor* GetLoopDescriptor() { return loop_desc_; }
   // Returns the loop on which the object operates on.
-  ir::Loop* GetLoop() const { return loop_; }
+  opt::Loop* GetLoop() const { return loop_; }
   // Returns the function that |loop_| belong to.
-  ir::Function* GetFunction() const { return &function_; }
+  opt::Function* GetFunction() const { return &function_; }
 
  private:
-  ir::IRContext* context_;
-  ir::LoopDescriptor* loop_desc_;
-  ir::Loop* loop_;
-  ir::Function& function_;
+  opt::IRContext* context_;
+  opt::LoopDescriptor* loop_desc_;
+  opt::Loop* loop_;
+  opt::Function& function_;
 
   // Populates the loop nest of |new_loop| according to |loop_| nest.
-  void PopulateLoopNest(ir::Loop* new_loop,
+  void PopulateLoopNest(opt::Loop* new_loop,
                         const LoopCloningResult& cloning_result) const;
 
   // Populates |new_loop| descriptor according to |old_loop|'s one.
-  void PopulateLoopDesc(ir::Loop* new_loop, ir::Loop* old_loop,
+  void PopulateLoopDesc(opt::Loop* new_loop, opt::Loop* old_loop,
                         const LoopCloningResult& cloning_result) const;
 };
 
diff --git a/source/opt/mem_pass.cpp b/source/opt/mem_pass.cpp
index f8e3f4f..5f226c4 100644
--- a/source/opt/mem_pass.cpp
+++ b/source/opt/mem_pass.cpp
@@ -33,7 +33,7 @@
 
 }  // namespace
 
-bool MemPass::IsBaseTargetType(const ir::Instruction* typeInst) const {
+bool MemPass::IsBaseTargetType(const opt::Instruction* typeInst) const {
   switch (typeInst->opcode()) {
     case SpvOpTypeInt:
     case SpvOpTypeFloat:
@@ -51,7 +51,7 @@
   return false;
 }
 
-bool MemPass::IsTargetType(const ir::Instruction* typeInst) const {
+bool MemPass::IsTargetType(const opt::Instruction* typeInst) const {
   if (IsBaseTargetType(typeInst)) return true;
   if (typeInst->opcode() == SpvOpTypeArray) {
     if (!IsTargetType(
@@ -63,7 +63,7 @@
   if (typeInst->opcode() != SpvOpTypeStruct) return false;
   // All struct members must be math type
   return typeInst->WhileEachInId([this](const uint32_t* tid) {
-    ir::Instruction* compTypeInst = get_def_use_mgr()->GetDef(*tid);
+    opt::Instruction* compTypeInst = get_def_use_mgr()->GetDef(*tid);
     if (!IsTargetType(compTypeInst)) return false;
     return true;
   });
@@ -75,7 +75,7 @@
 
 bool MemPass::IsPtr(uint32_t ptrId) {
   uint32_t varId = ptrId;
-  ir::Instruction* ptrInst = get_def_use_mgr()->GetDef(varId);
+  opt::Instruction* ptrInst = get_def_use_mgr()->GetDef(varId);
   while (ptrInst->opcode() == SpvOpCopyObject) {
     varId = ptrInst->GetSingleWordInOperand(kCopyObjectOperandInIdx);
     ptrInst = get_def_use_mgr()->GetDef(varId);
@@ -84,14 +84,14 @@
   if (op == SpvOpVariable || IsNonPtrAccessChain(op)) return true;
   if (op != SpvOpFunctionParameter) return false;
   const uint32_t varTypeId = ptrInst->type_id();
-  const ir::Instruction* varTypeInst = get_def_use_mgr()->GetDef(varTypeId);
+  const opt::Instruction* varTypeInst = get_def_use_mgr()->GetDef(varTypeId);
   return varTypeInst->opcode() == SpvOpTypePointer;
 }
 
-ir::Instruction* MemPass::GetPtr(uint32_t ptrId, uint32_t* varId) {
+opt::Instruction* MemPass::GetPtr(uint32_t ptrId, uint32_t* varId) {
   *varId = ptrId;
-  ir::Instruction* ptrInst = get_def_use_mgr()->GetDef(*varId);
-  ir::Instruction* varInst;
+  opt::Instruction* ptrInst = get_def_use_mgr()->GetDef(*varId);
+  opt::Instruction* varInst;
 
   if (ptrInst->opcode() != SpvOpVariable &&
       ptrInst->opcode() != SpvOpFunctionParameter) {
@@ -113,7 +113,7 @@
   return ptrInst;
 }
 
-ir::Instruction* MemPass::GetPtr(ir::Instruction* ip, uint32_t* varId) {
+opt::Instruction* MemPass::GetPtr(opt::Instruction* ip, uint32_t* varId) {
   assert(ip->opcode() == SpvOpStore || ip->opcode() == SpvOpLoad ||
          ip->opcode() == SpvOpImageTexelPointer);
 
@@ -123,7 +123,7 @@
 }
 
 bool MemPass::HasOnlyNamesAndDecorates(uint32_t id) const {
-  return get_def_use_mgr()->WhileEachUser(id, [this](ir::Instruction* user) {
+  return get_def_use_mgr()->WhileEachUser(id, [this](opt::Instruction* user) {
     SpvOp op = user->opcode();
     if (op != SpvOpName && !IsNonTypeDecorate(op)) {
       return false;
@@ -132,13 +132,13 @@
   });
 }
 
-void MemPass::KillAllInsts(ir::BasicBlock* bp, bool killLabel) {
+void MemPass::KillAllInsts(opt::BasicBlock* bp, bool killLabel) {
   bp->KillAllInsts(killLabel);
 }
 
 bool MemPass::HasLoads(uint32_t varId) const {
   return !get_def_use_mgr()->WhileEachUser(varId, [this](
-                                                      ir::Instruction* user) {
+                                                      opt::Instruction* user) {
     SpvOp op = user->opcode();
     // TODO(): The following is slightly conservative. Could be
     // better handling of non-store/name.
@@ -154,12 +154,12 @@
 }
 
 bool MemPass::IsLiveVar(uint32_t varId) const {
-  const ir::Instruction* varInst = get_def_use_mgr()->GetDef(varId);
+  const opt::Instruction* varInst = get_def_use_mgr()->GetDef(varId);
   // assume live if not a variable eg. function parameter
   if (varInst->opcode() != SpvOpVariable) return true;
   // non-function scope vars are live
   const uint32_t varTypeId = varInst->type_id();
-  const ir::Instruction* varTypeInst = get_def_use_mgr()->GetDef(varTypeId);
+  const opt::Instruction* varTypeInst = get_def_use_mgr()->GetDef(varTypeId);
   if (varTypeInst->GetSingleWordInOperand(kTypePointerStorageClassInIdx) !=
       SpvStorageClassFunction)
     return true;
@@ -167,8 +167,8 @@
   return HasLoads(varId);
 }
 
-void MemPass::AddStores(uint32_t ptr_id, std::queue<ir::Instruction*>* insts) {
-  get_def_use_mgr()->ForEachUser(ptr_id, [this, insts](ir::Instruction* user) {
+void MemPass::AddStores(uint32_t ptr_id, std::queue<opt::Instruction*>* insts) {
+  get_def_use_mgr()->ForEachUser(ptr_id, [this, insts](opt::Instruction* user) {
     SpvOp op = user->opcode();
     if (IsNonPtrAccessChain(op)) {
       AddStores(user->result_id(), insts);
@@ -178,12 +178,12 @@
   });
 }
 
-void MemPass::DCEInst(ir::Instruction* inst,
-                      const function<void(ir::Instruction*)>& call_back) {
-  std::queue<ir::Instruction*> deadInsts;
+void MemPass::DCEInst(opt::Instruction* inst,
+                      const function<void(opt::Instruction*)>& call_back) {
+  std::queue<opt::Instruction*> deadInsts;
   deadInsts.push(inst);
   while (!deadInsts.empty()) {
-    ir::Instruction* di = deadInsts.front();
+    opt::Instruction* di = deadInsts.front();
     // Don't delete labels
     if (di->opcode() == SpvOpLabel) {
       deadInsts.pop();
@@ -203,7 +203,7 @@
     // to the dead instruction queue.
     for (auto id : ids)
       if (HasOnlyNamesAndDecorates(id)) {
-        ir::Instruction* odi = get_def_use_mgr()->GetDef(id);
+        opt::Instruction* odi = get_def_use_mgr()->GetDef(id);
         if (context()->IsCombinatorInstruction(odi)) deadInsts.push(odi);
       }
     // if a load was deleted and it was the variable's
@@ -216,7 +216,8 @@
 MemPass::MemPass() {}
 
 bool MemPass::HasOnlySupportedRefs(uint32_t varId) {
-  return get_def_use_mgr()->WhileEachUser(varId, [this](ir::Instruction* user) {
+  return get_def_use_mgr()->WhileEachUser(varId, [this](
+                                                     opt::Instruction* user) {
     SpvOp op = user->opcode();
     if (op != SpvOpStore && op != SpvOpLoad && op != SpvOpName &&
         !IsNonTypeDecorate(op)) {
@@ -230,8 +231,8 @@
   const auto uitr = type2undefs_.find(type_id);
   if (uitr != type2undefs_.end()) return uitr->second;
   const uint32_t undefId = TakeNextId();
-  std::unique_ptr<ir::Instruction> undef_inst(
-      new ir::Instruction(context(), SpvOpUndef, type_id, undefId, {}));
+  std::unique_ptr<opt::Instruction> undef_inst(
+      new opt::Instruction(context(), SpvOpUndef, type_id, undefId, {}));
   get_def_use_mgr()->AnalyzeInstDefUse(&*undef_inst);
   get_module()->AddGlobalValue(std::move(undef_inst));
   type2undefs_[type_id] = undefId;
@@ -246,10 +247,10 @@
   if (seen_non_target_vars_.find(varId) != seen_non_target_vars_.end())
     return false;
   if (seen_target_vars_.find(varId) != seen_target_vars_.end()) return true;
-  const ir::Instruction* varInst = get_def_use_mgr()->GetDef(varId);
+  const opt::Instruction* varInst = get_def_use_mgr()->GetDef(varId);
   if (varInst->opcode() != SpvOpVariable) return false;
   const uint32_t varTypeId = varInst->type_id();
-  const ir::Instruction* varTypeInst = get_def_use_mgr()->GetDef(varTypeId);
+  const opt::Instruction* varTypeInst = get_def_use_mgr()->GetDef(varTypeId);
   if (varTypeInst->GetSingleWordInOperand(kTypePointerStorageClassInIdx) !=
       SpvStorageClassFunction) {
     seen_non_target_vars_.insert(varId);
@@ -257,7 +258,7 @@
   }
   const uint32_t varPteTypeId =
       varTypeInst->GetSingleWordInOperand(kTypePointerTypeIdInIdx);
-  ir::Instruction* varPteTypeInst = get_def_use_mgr()->GetDef(varPteTypeId);
+  opt::Instruction* varPteTypeInst = get_def_use_mgr()->GetDef(varPteTypeId);
   if (!IsTargetType(varPteTypeInst)) {
     seen_non_target_vars_.insert(varId);
     return false;
@@ -311,9 +312,9 @@
 //           [ ... ]
 //           %30 = OpPhi %int %int_42 %13 %50 %14 %50 %15
 void MemPass::RemovePhiOperands(
-    ir::Instruction* phi,
-    const unordered_set<ir::BasicBlock*>& reachable_blocks) {
-  std::vector<ir::Operand> keep_operands;
+    opt::Instruction* phi,
+    const unordered_set<opt::BasicBlock*>& reachable_blocks) {
+  std::vector<opt::Operand> keep_operands;
   uint32_t type_id = 0;
   // The id of an undefined value we've generated.
   uint32_t undef_id = 0;
@@ -333,7 +334,7 @@
     assert(i % 2 == 0 && i < phi->NumOperands() - 1 &&
            "malformed Phi arguments");
 
-    ir::BasicBlock* in_block = cfg()->block(phi->GetSingleWordOperand(i + 1));
+    opt::BasicBlock* in_block = cfg()->block(phi->GetSingleWordOperand(i + 1));
     if (reachable_blocks.find(in_block) == reachable_blocks.end()) {
       // If the incoming block is unreachable, remove both operands as this
       // means that the |phi| has lost an incoming edge.
@@ -343,8 +344,8 @@
 
     // In all other cases, the operand must be kept but may need to be changed.
     uint32_t arg_id = phi->GetSingleWordOperand(i);
-    ir::Instruction* arg_def_instr = get_def_use_mgr()->GetDef(arg_id);
-    ir::BasicBlock* def_block = context()->get_instr_block(arg_def_instr);
+    opt::Instruction* arg_def_instr = get_def_use_mgr()->GetDef(arg_id);
+    opt::BasicBlock* def_block = context()->get_instr_block(arg_def_instr);
     if (def_block &&
         reachable_blocks.find(def_block) == reachable_blocks.end()) {
       // If the current |phi| argument was defined in an unreachable block, it
@@ -355,7 +356,7 @@
         undef_id = Type2Undef(type_id);
       }
       keep_operands.push_back(
-          ir::Operand(spv_operand_type_t::SPV_OPERAND_TYPE_ID, {undef_id}));
+          opt::Operand(spv_operand_type_t::SPV_OPERAND_TYPE_ID, {undef_id}));
     } else {
       // Otherwise, the argument comes from a reachable block or from no block
       // at all (meaning that it was defined in the global section of the
@@ -373,11 +374,11 @@
   context()->AnalyzeUses(phi);
 }
 
-void MemPass::RemoveBlock(ir::Function::iterator* bi) {
+void MemPass::RemoveBlock(opt::Function::iterator* bi) {
   auto& rm_block = **bi;
 
   // Remove instructions from the block.
-  rm_block.ForEachInst([&rm_block, this](ir::Instruction* inst) {
+  rm_block.ForEachInst([&rm_block, this](opt::Instruction* inst) {
     // Note that we do not kill the block label instruction here. The label
     // instruction is needed to identify the block, which is needed by the
     // removal of phi operands.
@@ -393,13 +394,13 @@
   *bi = bi->Erase();
 }
 
-bool MemPass::RemoveUnreachableBlocks(ir::Function* func) {
+bool MemPass::RemoveUnreachableBlocks(opt::Function* func) {
   bool modified = false;
 
   // Mark reachable all blocks reachable from the function's entry block.
-  std::unordered_set<ir::BasicBlock*> reachable_blocks;
-  std::unordered_set<ir::BasicBlock*> visited_blocks;
-  std::queue<ir::BasicBlock*> worklist;
+  std::unordered_set<opt::BasicBlock*> reachable_blocks;
+  std::unordered_set<opt::BasicBlock*> visited_blocks;
+  std::queue<opt::BasicBlock*> worklist;
   reachable_blocks.insert(func->entry().get());
 
   // Initially mark the function entry point as reachable.
@@ -417,11 +418,11 @@
 
   // Transitively mark all blocks reachable from the entry as reachable.
   while (!worklist.empty()) {
-    ir::BasicBlock* block = worklist.front();
+    opt::BasicBlock* block = worklist.front();
     worklist.pop();
 
     // All the successors of a live block are also live.
-    static_cast<const ir::BasicBlock*>(block)->ForEachSuccessorLabel(
+    static_cast<const opt::BasicBlock*>(block)->ForEachSuccessorLabel(
         mark_reachable);
 
     // All the Merge and ContinueTarget blocks of a live block are also live.
@@ -439,7 +440,7 @@
     // If the block is reachable and has Phi instructions, remove all
     // operands from its Phi instructions that reference unreachable blocks.
     // If the block has no Phi instructions, this is a no-op.
-    block.ForEachPhiInst([&reachable_blocks, this](ir::Instruction* phi) {
+    block.ForEachPhiInst([&reachable_blocks, this](opt::Instruction* phi) {
       RemovePhiOperands(phi, reachable_blocks);
     });
   }
@@ -457,13 +458,13 @@
   return modified;
 }
 
-bool MemPass::CFGCleanup(ir::Function* func) {
+bool MemPass::CFGCleanup(opt::Function* func) {
   bool modified = false;
   modified |= RemoveUnreachableBlocks(func);
   return modified;
 }
 
-void MemPass::CollectTargetVars(ir::Function* func) {
+void MemPass::CollectTargetVars(opt::Function* func) {
   seen_target_vars_.clear();
   seen_non_target_vars_.clear();
   type2undefs_.clear();
diff --git a/source/opt/mem_pass.h b/source/opt/mem_pass.h
index 3778fc1..51ba834 100644
--- a/source/opt/mem_pass.h
+++ b/source/opt/mem_pass.h
@@ -49,7 +49,7 @@
   // Given a load or store |ip|, return the pointer instruction.
   // Also return the base variable's id in |varId|.  If no base variable is
   // found, |varId| will be 0.
-  ir::Instruction* GetPtr(ir::Instruction* ip, uint32_t* varId);
+  opt::Instruction* GetPtr(opt::Instruction* ip, uint32_t* varId);
 
   // Return true if |varId| is a previously identified target variable.
   // Return false if |varId| is a previously identified non-target variable.
@@ -66,17 +66,17 @@
   // Collect target SSA variables.  This traverses all the loads and stores in
   // function |func| looking for variables that can be replaced with SSA IDs. It
   // populates the sets |seen_target_vars_| and |seen_non_target_vars_|.
-  void CollectTargetVars(ir::Function* func);
+  void CollectTargetVars(opt::Function* func);
 
  protected:
   // Returns true if |typeInst| is a scalar type
   // or a vector or matrix
-  bool IsBaseTargetType(const ir::Instruction* typeInst) const;
+  bool IsBaseTargetType(const opt::Instruction* typeInst) const;
 
   // Returns true if |typeInst| is a math type or a struct or array
   // of a math type.
   // TODO(): Add more complex types to convert
-  bool IsTargetType(const ir::Instruction* typeInst) const;
+  bool IsTargetType(const opt::Instruction* typeInst) const;
 
   // Returns true if |opcode| is a non-ptr access chain op
   bool IsNonPtrAccessChain(const SpvOp opcode) const;
@@ -88,14 +88,14 @@
   // Given the id of a pointer |ptrId|, return the top-most non-CopyObj.
   // Also return the base variable's id in |varId|.  If no base variable is
   // found, |varId| will be 0.
-  ir::Instruction* GetPtr(uint32_t ptrId, uint32_t* varId);
+  opt::Instruction* GetPtr(uint32_t ptrId, uint32_t* varId);
 
   // Return true if all uses of |id| are only name or decorate ops.
   bool HasOnlyNamesAndDecorates(uint32_t id) const;
 
   // Kill all instructions in block |bp|. Whether or not to kill the label is
   // indicated by |killLabel|.
-  void KillAllInsts(ir::BasicBlock* bp, bool killLabel = true);
+  void KillAllInsts(opt::BasicBlock* bp, bool killLabel = true);
 
   // Return true if any instruction loads from |varId|
   bool HasLoads(uint32_t varId) const;
@@ -105,16 +105,16 @@
   bool IsLiveVar(uint32_t varId) const;
 
   // Add stores using |ptr_id| to |insts|
-  void AddStores(uint32_t ptr_id, std::queue<ir::Instruction*>* insts);
+  void AddStores(uint32_t ptr_id, std::queue<opt::Instruction*>* insts);
 
   // Delete |inst| and iterate DCE on all its operands if they are now
   // useless. If a load is deleted and its variable has no other loads,
   // delete all its variable's stores.
-  void DCEInst(ir::Instruction* inst,
-               const std::function<void(ir::Instruction*)>&);
+  void DCEInst(opt::Instruction* inst,
+               const std::function<void(opt::Instruction*)>&);
 
   // Call all the cleanup helper functions on |func|.
-  bool CFGCleanup(ir::Function* func);
+  bool CFGCleanup(opt::Function* func);
 
   // Return true if |op| is supported decorate.
   inline bool IsNonTypeDecorate(uint32_t op) const {
@@ -141,17 +141,17 @@
   bool HasOnlySupportedRefs(uint32_t varId);
 
   // Remove all the unreachable basic blocks in |func|.
-  bool RemoveUnreachableBlocks(ir::Function* func);
+  bool RemoveUnreachableBlocks(opt::Function* func);
 
   // Remove the block pointed by the iterator |*bi|. This also removes
   // all the instructions in the pointed-to block.
-  void RemoveBlock(ir::Function::iterator* bi);
+  void RemoveBlock(opt::Function::iterator* bi);
 
   // Remove Phi operands in |phi| that are coming from blocks not in
   // |reachable_blocks|.
   void RemovePhiOperands(
-      ir::Instruction* phi,
-      const std::unordered_set<ir::BasicBlock*>& reachable_blocks);
+      opt::Instruction* phi,
+      const std::unordered_set<opt::BasicBlock*>& reachable_blocks);
 
   // Map from type to undef
   std::unordered_map<uint32_t, uint32_t> type2undefs_;
diff --git a/source/opt/merge_return_pass.cpp b/source/opt/merge_return_pass.cpp
index 10d336c..f768e9f 100644
--- a/source/opt/merge_return_pass.cpp
+++ b/source/opt/merge_return_pass.cpp
@@ -23,14 +23,15 @@
 namespace spvtools {
 namespace opt {
 
-Pass::Status MergeReturnPass::Process(ir::IRContext* irContext) {
+Pass::Status MergeReturnPass::Process(opt::IRContext* irContext) {
   InitializeProcessing(irContext);
 
   bool modified = false;
   bool is_shader =
       context()->get_feature_mgr()->HasCapability(SpvCapabilityShader);
   for (auto& function : *get_module()) {
-    std::vector<ir::BasicBlock*> return_blocks = CollectReturnBlocks(&function);
+    std::vector<opt::BasicBlock*> return_blocks =
+        CollectReturnBlocks(&function);
     if (return_blocks.size() <= 1) continue;
 
     function_ = &function;
@@ -50,8 +51,9 @@
 }
 
 void MergeReturnPass::ProcessStructured(
-    ir::Function* function, const std::vector<ir::BasicBlock*>& return_blocks) {
-  std::list<ir::BasicBlock*> order;
+    opt::Function* function,
+    const std::vector<opt::BasicBlock*>& return_blocks) {
+  std::list<opt::BasicBlock*> order;
   cfg()->ComputeStructuredOrder(function, &*function->begin(), &order);
 
   // Create the new return block
@@ -78,8 +80,8 @@
     ProcessStructuredBlock(block);
 
     // Generate state for next block
-    if (ir::Instruction* mergeInst = block->GetMergeInst()) {
-      ir::Instruction* loopMergeInst = block->GetLoopMergeInst();
+    if (opt::Instruction* mergeInst = block->GetMergeInst()) {
+      opt::Instruction* loopMergeInst = block->GetLoopMergeInst();
       if (!loopMergeInst) loopMergeInst = state_.back().LoopMergeInst();
       state_.emplace_back(loopMergeInst, mergeInst);
     }
@@ -96,12 +98,12 @@
 
 void MergeReturnPass::CreateReturnBlock() {
   // Create a label for the new return block
-  std::unique_ptr<ir::Instruction> return_label(
-      new ir::Instruction(context(), SpvOpLabel, 0u, TakeNextId(), {}));
+  std::unique_ptr<opt::Instruction> return_label(
+      new opt::Instruction(context(), SpvOpLabel, 0u, TakeNextId(), {}));
 
   // Create the new basic block
-  std::unique_ptr<ir::BasicBlock> return_block(
-      new ir::BasicBlock(std::move(return_label)));
+  std::unique_ptr<opt::BasicBlock> return_block(
+      new opt::BasicBlock(std::move(return_label)));
   function_->AddBasicBlock(std::move(return_block));
   final_return_block_ = &*(--function_->end());
   context()->AnalyzeDefUse(final_return_block_->GetLabelInst());
@@ -110,33 +112,33 @@
   final_return_block_->SetParent(function_);
 }
 
-void MergeReturnPass::CreateReturn(ir::BasicBlock* block) {
+void MergeReturnPass::CreateReturn(opt::BasicBlock* block) {
   AddReturnValue();
 
   if (return_value_) {
     // Load and return the final return value
     uint32_t loadId = TakeNextId();
-    block->AddInstruction(MakeUnique<ir::Instruction>(
+    block->AddInstruction(MakeUnique<opt::Instruction>(
         context(), SpvOpLoad, function_->type_id(), loadId,
-        std::initializer_list<ir::Operand>{
+        std::initializer_list<opt::Operand>{
             {SPV_OPERAND_TYPE_ID, {return_value_->result_id()}}}));
-    ir::Instruction* var_inst = block->terminator();
+    opt::Instruction* var_inst = block->terminator();
     context()->AnalyzeDefUse(var_inst);
     context()->set_instr_block(var_inst, block);
 
-    block->AddInstruction(MakeUnique<ir::Instruction>(
+    block->AddInstruction(MakeUnique<opt::Instruction>(
         context(), SpvOpReturnValue, 0, 0,
-        std::initializer_list<ir::Operand>{{SPV_OPERAND_TYPE_ID, {loadId}}}));
+        std::initializer_list<opt::Operand>{{SPV_OPERAND_TYPE_ID, {loadId}}}));
     context()->AnalyzeDefUse(block->terminator());
     context()->set_instr_block(block->terminator(), block);
   } else {
-    block->AddInstruction(MakeUnique<ir::Instruction>(context(), SpvOpReturn));
+    block->AddInstruction(MakeUnique<opt::Instruction>(context(), SpvOpReturn));
     context()->AnalyzeDefUse(block->terminator());
     context()->set_instr_block(block->terminator(), block);
   }
 }
 
-void MergeReturnPass::ProcessStructuredBlock(ir::BasicBlock* block) {
+void MergeReturnPass::ProcessStructuredBlock(opt::BasicBlock* block) {
   SpvOp tail_opcode = block->tail()->opcode();
   if (tail_opcode == SpvOpReturn || tail_opcode == SpvOpReturnValue) {
     if (!return_flag_) {
@@ -157,7 +159,7 @@
   }
 }
 
-void MergeReturnPass::BranchToBlock(ir::BasicBlock* block, uint32_t target) {
+void MergeReturnPass::BranchToBlock(opt::BasicBlock* block, uint32_t target) {
   if (block->tail()->opcode() == SpvOpReturn ||
       block->tail()->opcode() == SpvOpReturnValue) {
     RecordReturned(block);
@@ -168,8 +170,8 @@
   //
   // A new edge is being added from |block| to |target|, so go through
   // |target|'s phi nodes add an undef incoming value for |block|.
-  ir::BasicBlock* target_block = context()->get_instr_block(target);
-  target_block->ForEachPhiInst([this, block](ir::Instruction* inst) {
+  opt::BasicBlock* target_block = context()->get_instr_block(target);
+  target_block->ForEachPhiInst([this, block](opt::Instruction* inst) {
     uint32_t undefId = Type2Undef(inst->type_id());
     inst->AddOperand({SPV_OPERAND_TYPE_ID, {undefId}});
     inst->AddOperand({SPV_OPERAND_TYPE_ID, {block->id()}});
@@ -182,25 +184,25 @@
                        context()->get_instr_block(target_pred[0]));
   }
 
-  ir::Instruction* return_inst = block->terminator();
+  opt::Instruction* return_inst = block->terminator();
   return_inst->SetOpcode(SpvOpBranch);
   return_inst->ReplaceOperands({{SPV_OPERAND_TYPE_ID, {target}}});
   context()->get_def_use_mgr()->AnalyzeInstDefUse(return_inst);
   cfg()->AddEdge(block->id(), target);
 }
 
-void MergeReturnPass::CreatePhiNodesForInst(ir::BasicBlock* merge_block,
+void MergeReturnPass::CreatePhiNodesForInst(opt::BasicBlock* merge_block,
                                             uint32_t predecessor,
-                                            ir::Instruction& inst) {
+                                            opt::Instruction& inst) {
   opt::DominatorAnalysis* dom_tree =
       context()->GetDominatorAnalysis(merge_block->GetParent());
-  ir::BasicBlock* inst_bb = context()->get_instr_block(&inst);
+  opt::BasicBlock* inst_bb = context()->get_instr_block(&inst);
 
   if (inst.result_id() != 0) {
-    std::vector<ir::Instruction*> users_to_update;
+    std::vector<opt::Instruction*> users_to_update;
     context()->get_def_use_mgr()->ForEachUser(
         &inst,
-        [&users_to_update, &dom_tree, inst_bb, this](ir::Instruction* user) {
+        [&users_to_update, &dom_tree, inst_bb, this](opt::Instruction* user) {
           if (!dom_tree->Dominates(inst_bb, context()->get_instr_block(user))) {
             users_to_update.push_back(user);
           }
@@ -213,7 +215,7 @@
     // There is at least one values that needs to be replaced.
     // First create the OpPhi instruction.
     InstructionBuilder builder(context(), &*merge_block->begin(),
-                               ir::IRContext::kAnalysisDefUse);
+                               opt::IRContext::kAnalysisDefUse);
     uint32_t undef_id = Type2Undef(inst.type_id());
     std::vector<uint32_t> phi_operands;
 
@@ -230,11 +232,11 @@
       }
     }
 
-    ir::Instruction* new_phi = builder.AddPhi(inst.type_id(), phi_operands);
+    opt::Instruction* new_phi = builder.AddPhi(inst.type_id(), phi_operands);
     uint32_t result_of_phi = new_phi->result_id();
 
     // Update all of the users to use the result of the new OpPhi.
-    for (ir::Instruction* user : users_to_update) {
+    for (opt::Instruction* user : users_to_update) {
       user->ForEachInId([&inst, result_of_phi](uint32_t* id) {
         if (*id == inst.result_id()) {
           *id = result_of_phi;
@@ -246,26 +248,26 @@
 }
 
 void MergeReturnPass::PredicateBlocks(
-    const std::vector<ir::BasicBlock*>& return_blocks) {
+    const std::vector<opt::BasicBlock*>& return_blocks) {
   // The CFG is being modified as the function proceeds so avoid caching
   // successors.
-  std::vector<ir::BasicBlock*> stack;
-  auto add_successors = [this, &stack](ir::BasicBlock* block) {
-    const ir::BasicBlock* const_block =
-        const_cast<const ir::BasicBlock*>(block);
+  std::vector<opt::BasicBlock*> stack;
+  auto add_successors = [this, &stack](opt::BasicBlock* block) {
+    const opt::BasicBlock* const_block =
+        const_cast<const opt::BasicBlock*>(block);
     const_block->ForEachSuccessorLabel([this, &stack](const uint32_t idx) {
       stack.push_back(context()->get_instr_block(idx));
     });
   };
 
-  std::unordered_set<ir::BasicBlock*> seen;
-  std::unordered_set<ir::BasicBlock*> predicated;
+  std::unordered_set<opt::BasicBlock*> seen;
+  std::unordered_set<opt::BasicBlock*> predicated;
   for (auto b : return_blocks) {
     seen.clear();
     add_successors(b);
 
     while (!stack.empty()) {
-      ir::BasicBlock* block = stack.back();
+      opt::BasicBlock* block = stack.back();
       assert(block);
       stack.pop_back();
 
@@ -275,7 +277,7 @@
       if (!predicated.insert(block).second) continue;
 
       // Skip structured subgraphs.
-      ir::BasicBlock* next = block;
+      opt::BasicBlock* next = block;
       while (next->GetMergeInst()) {
         next = context()->get_instr_block(next->MergeBlockIdIfAny());
       }
@@ -286,15 +288,15 @@
 }
 
 bool MergeReturnPass::RequiresPredication(
-    const ir::BasicBlock* block, const ir::BasicBlock* tail_block) const {
+    const opt::BasicBlock* block, const opt::BasicBlock* tail_block) const {
   // This is intentionally conservative.
   // TODO(alanbaker): re-visit this when more performance data is available.
   if (block != tail_block) return true;
 
   bool requires_predicate = false;
-  block->ForEachInst([&requires_predicate](const ir::Instruction* inst) {
+  block->ForEachInst([&requires_predicate](const opt::Instruction* inst) {
     if (inst->opcode() != SpvOpPhi && inst->opcode() != SpvOpLabel &&
-        !ir::IsTerminatorInst(inst->opcode())) {
+        !opt::IsTerminatorInst(inst->opcode())) {
       requires_predicate = true;
     }
   });
@@ -302,15 +304,15 @@
 }
 
 void MergeReturnPass::PredicateBlock(
-    ir::BasicBlock* block, ir::BasicBlock* tail_block,
-    std::unordered_set<ir::BasicBlock*>* predicated) {
+    opt::BasicBlock* block, opt::BasicBlock* tail_block,
+    std::unordered_set<opt::BasicBlock*>* predicated) {
   if (!RequiresPredication(block, tail_block)) {
     return;
   }
 
   // Make sure the cfg is build here.  If we don't then it becomes very hard to
   // know which new blocks need to be updated.
-  context()->BuildInvalidAnalyses(ir::IRContext::kAnalysisCFG);
+  context()->BuildInvalidAnalyses(opt::IRContext::kAnalysisCFG);
 
   // When predicating, be aware of whether this block is a header block, a merge
   // block or both.
@@ -336,9 +338,9 @@
   // Forget about the edges leaving block.  They will be removed.
   cfg()->RemoveSuccessorEdges(block);
 
-  std::unique_ptr<ir::BasicBlock> new_block(
+  std::unique_ptr<opt::BasicBlock> new_block(
       block->SplitBasicBlock(context(), TakeNextId(), iter));
-  ir::BasicBlock* old_body =
+  opt::BasicBlock* old_body =
       function_->InsertBasicBlockAfter(std::move(new_block), block);
   predicated->insert(old_body);
 
@@ -346,21 +348,21 @@
     tail_block = old_body;
   }
 
-  const ir::BasicBlock* const_old_body =
-      static_cast<const ir::BasicBlock*>(old_body);
+  const opt::BasicBlock* const_old_body =
+      static_cast<const opt::BasicBlock*>(old_body);
   const_old_body->ForEachSuccessorLabel(
       [old_body, block, this](const uint32_t label) {
-        ir::BasicBlock* target_bb = context()->get_instr_block(label);
+        opt::BasicBlock* target_bb = context()->get_instr_block(label);
         if (MarkedSinglePred(target_bb) == block) {
           MarkForNewPhiNodes(target_bb, old_body);
         }
       });
 
-  std::unique_ptr<ir::BasicBlock> new_merge_block(new ir::BasicBlock(
-      MakeUnique<ir::Instruction>(context(), SpvOpLabel, 0, TakeNextId(),
-                                  std::initializer_list<ir::Operand>{})));
+  std::unique_ptr<opt::BasicBlock> new_merge_block(new opt::BasicBlock(
+      MakeUnique<opt::Instruction>(context(), SpvOpLabel, 0, TakeNextId(),
+                                   std::initializer_list<opt::Operand>{})));
 
-  ir::BasicBlock* new_merge =
+  opt::BasicBlock* new_merge =
       function_->InsertBasicBlockAfter(std::move(new_merge_block), tail_block);
   predicated->insert(new_merge);
   new_merge->SetParent(function_);
@@ -374,8 +376,8 @@
   // Move the tail branch into the new merge and fix the mapping. If a single
   // block is being predicated then its branch was moved to the old body
   // previously.
-  std::unique_ptr<ir::Instruction> inst;
-  ir::Instruction* i = tail_block->terminator();
+  std::unique_ptr<opt::Instruction> inst;
+  opt::Instruction* i = tail_block->terminator();
   cfg()->RemoveSuccessorEdges(tail_block);
   get_def_use_mgr()->ClearInst(i);
   inst.reset(std::move(i));
@@ -386,9 +388,9 @@
 
   // Add a branch to the new merge. If we jumped multiple blocks, the branch is
   // added to tail_block, otherwise the branch belongs in old_body.
-  tail_block->AddInstruction(MakeUnique<ir::Instruction>(
+  tail_block->AddInstruction(MakeUnique<opt::Instruction>(
       context(), SpvOpBranch, 0, 0,
-      std::initializer_list<ir::Operand>{
+      std::initializer_list<opt::Operand>{
           {SPV_OPERAND_TYPE_ID, {new_merge->id()}}}));
   get_def_use_mgr()->AnalyzeInstUse(tail_block->terminator());
   context()->set_instr_block(tail_block->terminator(), tail_block);
@@ -403,27 +405,27 @@
   uint32_t bool_id = context()->get_type_mgr()->GetId(&bool_type);
   assert(bool_id != 0);
   uint32_t load_id = TakeNextId();
-  block->AddInstruction(MakeUnique<ir::Instruction>(
+  block->AddInstruction(MakeUnique<opt::Instruction>(
       context(), SpvOpLoad, bool_id, load_id,
-      std::initializer_list<ir::Operand>{
+      std::initializer_list<opt::Operand>{
           {SPV_OPERAND_TYPE_ID, {return_flag_->result_id()}}}));
   get_def_use_mgr()->AnalyzeInstDefUse(block->terminator());
   context()->set_instr_block(block->terminator(), block);
 
   // 2. Declare the merge block
   block->AddInstruction(
-      MakeUnique<ir::Instruction>(context(), SpvOpSelectionMerge, 0, 0,
-                                  std::initializer_list<ir::Operand>{
-                                      {SPV_OPERAND_TYPE_ID, {new_merge->id()}},
-                                      {SPV_OPERAND_TYPE_SELECTION_CONTROL,
-                                       {SpvSelectionControlMaskNone}}}));
+      MakeUnique<opt::Instruction>(context(), SpvOpSelectionMerge, 0, 0,
+                                   std::initializer_list<opt::Operand>{
+                                       {SPV_OPERAND_TYPE_ID, {new_merge->id()}},
+                                       {SPV_OPERAND_TYPE_SELECTION_CONTROL,
+                                        {SpvSelectionControlMaskNone}}}));
   get_def_use_mgr()->AnalyzeInstUse(block->terminator());
   context()->set_instr_block(block->terminator(), block);
 
   // 3. Branch to new merge (true) or old body (false)
-  block->AddInstruction(MakeUnique<ir::Instruction>(
+  block->AddInstruction(MakeUnique<opt::Instruction>(
       context(), SpvOpBranchConditional, 0, 0,
-      std::initializer_list<ir::Operand>{
+      std::initializer_list<opt::Operand>{
           {SPV_OPERAND_TYPE_ID, {load_id}},
           {SPV_OPERAND_TYPE_ID, {new_merge->id()}},
           {SPV_OPERAND_TYPE_ID, {old_body->id()}}}));
@@ -444,7 +446,7 @@
   MarkForNewPhiNodes(new_merge, tail_block);
 }
 
-void MergeReturnPass::RecordReturned(ir::BasicBlock* block) {
+void MergeReturnPass::RecordReturned(opt::BasicBlock* block) {
   if (block->tail()->opcode() != SpvOpReturn &&
       block->tail()->opcode() != SpvOpReturnValue)
     return;
@@ -463,19 +465,19 @@
     context()->UpdateDefUse(constant_true_);
   }
 
-  std::unique_ptr<ir::Instruction> return_store(new ir::Instruction(
+  std::unique_ptr<opt::Instruction> return_store(new opt::Instruction(
       context(), SpvOpStore, 0, 0,
-      std::initializer_list<ir::Operand>{
+      std::initializer_list<opt::Operand>{
           {SPV_OPERAND_TYPE_ID, {return_flag_->result_id()}},
           {SPV_OPERAND_TYPE_ID, {constant_true_->result_id()}}}));
 
-  ir::Instruction* store_inst =
+  opt::Instruction* store_inst =
       &*block->tail().InsertBefore(std::move(return_store));
   context()->set_instr_block(store_inst, block);
   context()->AnalyzeDefUse(store_inst);
 }
 
-void MergeReturnPass::RecordReturnValue(ir::BasicBlock* block) {
+void MergeReturnPass::RecordReturnValue(opt::BasicBlock* block) {
   auto terminator = *block->tail();
   if (terminator.opcode() != SpvOpReturnValue) {
     return;
@@ -484,13 +486,13 @@
   assert(return_value_ &&
          "Did not generate the variable to hold the return value.");
 
-  std::unique_ptr<ir::Instruction> value_store(new ir::Instruction(
+  std::unique_ptr<opt::Instruction> value_store(new opt::Instruction(
       context(), SpvOpStore, 0, 0,
-      std::initializer_list<ir::Operand>{
+      std::initializer_list<opt::Operand>{
           {SPV_OPERAND_TYPE_ID, {return_value_->result_id()}},
           {SPV_OPERAND_TYPE_ID, {terminator.GetSingleWordInOperand(0u)}}}));
 
-  ir::Instruction* store_inst =
+  opt::Instruction* store_inst =
       &*block->tail().InsertBefore(std::move(value_store));
   context()->set_instr_block(store_inst, block);
   context()->AnalyzeDefUse(store_inst);
@@ -507,14 +509,14 @@
       return_type_id, SpvStorageClassFunction);
 
   uint32_t var_id = TakeNextId();
-  std::unique_ptr<ir::Instruction> returnValue(new ir::Instruction(
+  std::unique_ptr<opt::Instruction> returnValue(new opt::Instruction(
       context(), SpvOpVariable, return_ptr_type, var_id,
-      std::initializer_list<ir::Operand>{
+      std::initializer_list<opt::Operand>{
           {SPV_OPERAND_TYPE_STORAGE_CLASS, {SpvStorageClassFunction}}}));
 
   auto insert_iter = function_->begin()->begin();
   insert_iter.InsertBefore(std::move(returnValue));
-  ir::BasicBlock* entry_block = &*function_->begin();
+  opt::BasicBlock* entry_block = &*function_->begin();
   return_value_ = &*entry_block->begin();
   context()->AnalyzeDefUse(return_value_);
   context()->set_instr_block(return_value_, entry_block);
@@ -539,26 +541,26 @@
       type_mgr->FindPointerToType(bool_id, SpvStorageClassFunction);
 
   uint32_t var_id = TakeNextId();
-  std::unique_ptr<ir::Instruction> returnFlag(new ir::Instruction(
+  std::unique_ptr<opt::Instruction> returnFlag(new opt::Instruction(
       context(), SpvOpVariable, bool_ptr_id, var_id,
-      std::initializer_list<ir::Operand>{
+      std::initializer_list<opt::Operand>{
           {SPV_OPERAND_TYPE_STORAGE_CLASS, {SpvStorageClassFunction}},
           {SPV_OPERAND_TYPE_ID, {const_false_id}}}));
 
   auto insert_iter = function_->begin()->begin();
 
   insert_iter.InsertBefore(std::move(returnFlag));
-  ir::BasicBlock* entry_block = &*function_->begin();
+  opt::BasicBlock* entry_block = &*function_->begin();
   return_flag_ = &*entry_block->begin();
   context()->AnalyzeDefUse(return_flag_);
   context()->set_instr_block(return_flag_, entry_block);
 }
 
-std::vector<ir::BasicBlock*> MergeReturnPass::CollectReturnBlocks(
-    ir::Function* function) {
-  std::vector<ir::BasicBlock*> return_blocks;
+std::vector<opt::BasicBlock*> MergeReturnPass::CollectReturnBlocks(
+    opt::Function* function) {
+  std::vector<opt::BasicBlock*> return_blocks;
   for (auto& block : *function) {
-    ir::Instruction& terminator = *block.tail();
+    opt::Instruction& terminator = *block.tail();
     if (terminator.opcode() == SpvOpReturn ||
         terminator.opcode() == SpvOpReturnValue) {
       return_blocks.push_back(&block);
@@ -568,7 +570,8 @@
 }
 
 void MergeReturnPass::MergeReturnBlocks(
-    ir::Function* function, const std::vector<ir::BasicBlock*>& return_blocks) {
+    opt::Function* function,
+    const std::vector<opt::BasicBlock*>& return_blocks) {
   if (return_blocks.size() <= 1) {
     // No work to do.
     return;
@@ -579,7 +582,7 @@
   auto ret_block_iter = --function->end();
   // Create the PHI for the merged block (if necessary).
   // Create new return.
-  std::vector<ir::Operand> phi_ops;
+  std::vector<opt::Operand> phi_ops;
   for (auto block : return_blocks) {
     if (block->tail()->opcode() == SpvOpReturnValue) {
       phi_ops.push_back(
@@ -592,23 +595,23 @@
     // Need a PHI node to select the correct return value.
     uint32_t phi_result_id = TakeNextId();
     uint32_t phi_type_id = function->type_id();
-    std::unique_ptr<ir::Instruction> phi_inst(new ir::Instruction(
+    std::unique_ptr<opt::Instruction> phi_inst(new opt::Instruction(
         context(), SpvOpPhi, phi_type_id, phi_result_id, phi_ops));
     ret_block_iter->AddInstruction(std::move(phi_inst));
-    ir::BasicBlock::iterator phiIter = ret_block_iter->tail();
+    opt::BasicBlock::iterator phiIter = ret_block_iter->tail();
 
-    std::unique_ptr<ir::Instruction> return_inst(
-        new ir::Instruction(context(), SpvOpReturnValue, 0u, 0u,
-                            {{SPV_OPERAND_TYPE_ID, {phi_result_id}}}));
+    std::unique_ptr<opt::Instruction> return_inst(
+        new opt::Instruction(context(), SpvOpReturnValue, 0u, 0u,
+                             {{SPV_OPERAND_TYPE_ID, {phi_result_id}}}));
     ret_block_iter->AddInstruction(std::move(return_inst));
-    ir::BasicBlock::iterator ret = ret_block_iter->tail();
+    opt::BasicBlock::iterator ret = ret_block_iter->tail();
 
     // Register the phi def and mark instructions for use updates.
     get_def_use_mgr()->AnalyzeInstDefUse(&*phiIter);
     get_def_use_mgr()->AnalyzeInstDef(&*ret);
   } else {
-    std::unique_ptr<ir::Instruction> return_inst(
-        new ir::Instruction(context(), SpvOpReturn));
+    std::unique_ptr<opt::Instruction> return_inst(
+        new opt::Instruction(context(), SpvOpReturn));
     ret_block_iter->AddInstruction(std::move(return_inst));
   }
 
@@ -626,32 +629,32 @@
 
 void MergeReturnPass::AddNewPhiNodes() {
   opt::DominatorAnalysis* dom_tree = context()->GetDominatorAnalysis(function_);
-  std::list<ir::BasicBlock*> order;
+  std::list<opt::BasicBlock*> order;
   cfg()->ComputeStructuredOrder(function_, &*function_->begin(), &order);
 
-  for (ir::BasicBlock* bb : order) {
+  for (opt::BasicBlock* bb : order) {
     AddNewPhiNodes(bb, new_merge_nodes_[bb],
                    dom_tree->ImmediateDominator(bb)->id());
   }
 }
 
-void MergeReturnPass::AddNewPhiNodes(ir::BasicBlock* bb, ir::BasicBlock* pred,
+void MergeReturnPass::AddNewPhiNodes(opt::BasicBlock* bb, opt::BasicBlock* pred,
                                      uint32_t header_id) {
   opt::DominatorAnalysis* dom_tree = context()->GetDominatorAnalysis(function_);
   // Insert as a stopping point.  We do not have to add anything in the block or
   // above because the header dominates |bb|.
 
-  ir::BasicBlock* current_bb = pred;
+  opt::BasicBlock* current_bb = pred;
   while (current_bb != nullptr && current_bb->id() != header_id) {
-    for (ir::Instruction& inst : *current_bb) {
+    for (opt::Instruction& inst : *current_bb) {
       CreatePhiNodesForInst(bb, pred->id(), inst);
     }
     current_bb = dom_tree->ImmediateDominator(current_bb);
   }
 }
 
-void MergeReturnPass::MarkForNewPhiNodes(ir::BasicBlock* block,
-                                         ir::BasicBlock* single_original_pred) {
+void MergeReturnPass::MarkForNewPhiNodes(
+    opt::BasicBlock* block, opt::BasicBlock* single_original_pred) {
   new_merge_nodes_[block] = single_original_pred;
 }
 
diff --git a/source/opt/merge_return_pass.h b/source/opt/merge_return_pass.h
index b4f47e3..fe21b5e 100644
--- a/source/opt/merge_return_pass.h
+++ b/source/opt/merge_return_pass.h
@@ -103,11 +103,11 @@
         final_return_block_(nullptr) {}
 
   const char* name() const override { return "merge-return"; }
-  Status Process(ir::IRContext*) override;
+  Status Process(opt::IRContext*) override;
 
-  ir::IRContext::Analysis GetPreservedAnalyses() override {
-    // return ir::IRContext::kAnalysisDefUse;
-    return ir::IRContext::kAnalysisNone;
+  opt::IRContext::Analysis GetPreservedAnalyses() override {
+    // return opt::IRContext::kAnalysisDefUse;
+    return opt::IRContext::kAnalysisNone;
   }
 
  private:
@@ -116,7 +116,7 @@
   // contain selection construct and the inner most loop construct.
   class StructuredControlState {
    public:
-    StructuredControlState(ir::Instruction* loop, ir::Instruction* merge)
+    StructuredControlState(opt::Instruction* loop, opt::Instruction* merge)
         : loop_merge_(loop), current_merge_(merge) {}
 
     StructuredControlState(const StructuredControlState&) = default;
@@ -145,29 +145,29 @@
                  : 0;
     }
 
-    ir::Instruction* LoopMergeInst() const { return loop_merge_; }
+    opt::Instruction* LoopMergeInst() const { return loop_merge_; }
 
    private:
-    ir::Instruction* loop_merge_;
-    ir::Instruction* current_merge_;
+    opt::Instruction* loop_merge_;
+    opt::Instruction* current_merge_;
   };
 
   // Returns all BasicBlocks terminated by OpReturn or OpReturnValue in
   // |function|.
-  std::vector<ir::BasicBlock*> CollectReturnBlocks(ir::Function* function);
+  std::vector<opt::BasicBlock*> CollectReturnBlocks(opt::Function* function);
 
   // Creates a new basic block with a single return. If |function| returns a
   // value, a phi node is created to select the correct value to return.
   // Replaces old returns with an unconditional branch to the new block.
-  void MergeReturnBlocks(ir::Function* function,
-                         const std::vector<ir::BasicBlock*>& returnBlocks);
+  void MergeReturnBlocks(opt::Function* function,
+                         const std::vector<opt::BasicBlock*>& returnBlocks);
 
   // Merges the return instruction in |function| so that it has a single return
   // statement.  It is assumed that |function| has structured control flow, and
   // that |return_blocks| is a list of all of the basic blocks in |function|
   // that have a return.
-  void ProcessStructured(ir::Function* function,
-                         const std::vector<ir::BasicBlock*>& return_blocks);
+  void ProcessStructured(opt::Function* function,
+                         const std::vector<opt::BasicBlock*>& return_blocks);
 
   // Changes an OpReturn* or OpUnreachable instruction at the end of |block|
   // into a store to |return_flag_|, a store to |return_value_| (if necessary),
@@ -178,7 +178,7 @@
   //
   // Note this will break the semantics.  To fix this, PredicateBlock will have
   // to be called on the merge block the branch targets.
-  void ProcessStructuredBlock(ir::BasicBlock* block);
+  void ProcessStructuredBlock(opt::BasicBlock* block);
 
   // Creates a variable used to store whether or not the control flow has
   // traversed a block that used to have a return.  A pointer to the instruction
@@ -192,7 +192,7 @@
   // Adds a store that stores true to |return_flag_| immediately before the
   // terminator of |block|. It is assumed that |AddReturnFlag| has already been
   // called.
-  void RecordReturned(ir::BasicBlock* block);
+  void RecordReturned(opt::BasicBlock* block);
 
   // Adds an instruction that stores the value being returned in the
   // OpReturnValue in |block|.  The value is stored to |return_value_|, and the
@@ -201,35 +201,35 @@
   // If |block| does not contain an OpReturnValue, then this function has no
   // effect. If |block| contains an OpReturnValue, then |AddReturnValue| must
   // have already been called to create the variable to store to.
-  void RecordReturnValue(ir::BasicBlock* block);
+  void RecordReturnValue(opt::BasicBlock* block);
 
   // Adds an unconditional branch in |block| that branches to |target|.  It also
   // adds stores to |return_flag_| and |return_value_| as needed.
   // |AddReturnFlag| and |AddReturnValue| must have already been called.
-  void BranchToBlock(ir::BasicBlock* block, uint32_t target);
+  void BranchToBlock(opt::BasicBlock* block, uint32_t target);
 
   // Returns true if we need to pridicate |block| where |tail_block| is the
   // merge point.  (See |PredicateBlocks|).  There is no need to predicate if
   // there is no code that could be executed.
-  bool RequiresPredication(const ir::BasicBlock* block,
-                           const ir::BasicBlock* tail_block) const;
+  bool RequiresPredication(const opt::BasicBlock* block,
+                           const opt::BasicBlock* tail_block) const;
 
   // For every basic block that is reachable from a basic block in
   // |return_blocks|, extra code is added to jump around any code that should
   // not be executed because the original code would have already returned. This
   // involves adding new selections constructs to jump around these
   // instructions.
-  void PredicateBlocks(const std::vector<ir::BasicBlock*>& return_blocks);
+  void PredicateBlocks(const std::vector<opt::BasicBlock*>& return_blocks);
 
   // Add the predication code (see |PredicateBlocks|) to |tail_block| if it
   // requires predication.  |tail_block| and any new blocks that are known to
   // not require predication will be added to |predicated|.
-  void PredicateBlock(ir::BasicBlock* block, ir::BasicBlock* tail_block,
-                      std::unordered_set<ir::BasicBlock*>* predicated);
+  void PredicateBlock(opt::BasicBlock* block, opt::BasicBlock* tail_block,
+                      std::unordered_set<opt::BasicBlock*>* predicated);
 
   // Add an |OpReturn| or |OpReturnValue| to the end of |block|.  If an
   // |OpReturnValue| is needed, the return value is loaded from |return_value_|.
-  void CreateReturn(ir::BasicBlock* block);
+  void CreateReturn(opt::BasicBlock* block);
 
   // Creates a block at the end of the function that will become the single
   // return block at the end of the pass.
@@ -239,8 +239,8 @@
   // |predecessor|.  Any uses of the result of |inst| that are no longer
   // dominated by |inst|, are replaced with the result of the new |OpPhi|
   // instruction.
-  void CreatePhiNodesForInst(ir::BasicBlock* merge_block, uint32_t predecessor,
-                             ir::Instruction& inst);
+  void CreatePhiNodesForInst(opt::BasicBlock* merge_block, uint32_t predecessor,
+                             opt::Instruction& inst);
 
   // Traverse the nodes in |new_merge_nodes_|, and adds the OpPhi instructions
   // that are needed to make the code correct.  It is assumed that at this point
@@ -250,18 +250,18 @@
   // Creates any new phi nodes that are needed in |bb| now that |pred| is no
   // longer the only block that preceedes |bb|.  |header_id| is the id of the
   // basic block for the loop or selection construct that merges at |bb|.
-  void AddNewPhiNodes(ir::BasicBlock* bb, ir::BasicBlock* pred,
+  void AddNewPhiNodes(opt::BasicBlock* bb, opt::BasicBlock* pred,
                       uint32_t header_id);
 
   // Saves |block| to a list of basic block that will require OpPhi nodes to be
   // added by calling |AddNewPhiNodes|.  It is assumed that |block| used to have
   // a single predecessor, |single_original_pred|, but now has more.
-  void MarkForNewPhiNodes(ir::BasicBlock* block,
-                          ir::BasicBlock* single_original_pred);
+  void MarkForNewPhiNodes(opt::BasicBlock* block,
+                          opt::BasicBlock* single_original_pred);
 
   // Return the original single predcessor of |block| if it was flagged as
   // having a single predecessor.  |nullptr| is returned otherwise.
-  ir::BasicBlock* MarkedSinglePred(ir::BasicBlock* block) {
+  opt::BasicBlock* MarkedSinglePred(opt::BasicBlock* block) {
     auto it = new_merge_nodes_.find(block);
     if (it != new_merge_nodes_.end()) {
       return it->second;
@@ -277,28 +277,28 @@
   std::vector<StructuredControlState> state_;
 
   // The current function being transformed.
-  ir::Function* function_;
+  opt::Function* function_;
 
   // The |OpVariable| instruction defining a boolean variable used to keep track
   // of whether or not the function is trying to return.
-  ir::Instruction* return_flag_;
+  opt::Instruction* return_flag_;
 
   // The |OpVariable| instruction defining a variabled to used to keep track of
   // the value that was returned when passing through a block that use to
   // contain an |OpReturnValue|.
-  ir::Instruction* return_value_;
+  opt::Instruction* return_value_;
 
   // The instruction defining the boolean constant true.
-  ir::Instruction* constant_true_;
+  opt::Instruction* constant_true_;
 
   // The basic block that is suppose to become the contain the only return value
   // after processing the current function.
-  ir::BasicBlock* final_return_block_;
+  opt::BasicBlock* final_return_block_;
   // This map contains the set of nodes that use to have a single predcessor,
   // but now have more.  They will need new OpPhi nodes.  For each of the nodes,
   // it is mapped to it original single predcessor.  It is assumed there are no
   // values that will need a phi on the new edges.
-  std::unordered_map<ir::BasicBlock*, ir::BasicBlock*> new_merge_nodes_;
+  std::unordered_map<opt::BasicBlock*, opt::BasicBlock*> new_merge_nodes_;
 };
 
 }  // namespace opt
diff --git a/source/opt/module.cpp b/source/opt/module.cpp
index 1e87c2c..9c5b1d8 100644
--- a/source/opt/module.cpp
+++ b/source/opt/module.cpp
@@ -22,7 +22,7 @@
 #include "reflect.h"
 
 namespace spvtools {
-namespace ir {
+namespace opt {
 
 std::vector<Instruction*> Module::GetTypes() {
   std::vector<Instruction*> type_insts;
@@ -65,8 +65,8 @@
 
 void Module::AddGlobalValue(SpvOp opcode, uint32_t result_id,
                             uint32_t type_id) {
-  std::unique_ptr<ir::Instruction> newGlobal(
-      new ir::Instruction(context(), opcode, type_id, result_id, {}));
+  std::unique_ptr<opt::Instruction> newGlobal(
+      new opt::Instruction(context(), opcode, type_id, result_id, {}));
   AddGlobalValue(std::move(newGlobal));
 }
 
@@ -160,7 +160,7 @@
 }
 
 std::ostream& operator<<(std::ostream& str, const Module& module) {
-  module.ForEachInst([&str](const ir::Instruction* inst) {
+  module.ForEachInst([&str](const opt::Instruction* inst) {
     str << *inst;
     if (inst->opcode() != SpvOpFunctionEnd) {
       str << std::endl;
@@ -169,5 +169,5 @@
   return str;
 }
 
-}  // namespace ir
+}  // namespace opt
 }  // namespace spvtools
diff --git a/source/opt/module.h b/source/opt/module.h
index 163c4e3..7571c9b 100644
--- a/source/opt/module.h
+++ b/source/opt/module.h
@@ -25,7 +25,7 @@
 #include "iterator.h"
 
 namespace spvtools {
-namespace ir {
+namespace opt {
 
 class IRContext;
 
@@ -470,7 +470,7 @@
   return const_iterator(&functions_, functions_.cend());
 }
 
-}  // namespace ir
+}  // namespace opt
 }  // namespace spvtools
 
 #endif  // LIBSPIRV_OPT_MODULE_H_
diff --git a/source/opt/null_pass.h b/source/opt/null_pass.h
index 54ea06e..2f1a976 100644
--- a/source/opt/null_pass.h
+++ b/source/opt/null_pass.h
@@ -25,7 +25,7 @@
 class NullPass : public Pass {
  public:
   const char* name() const override { return "null"; }
-  Status Process(ir::IRContext*) override {
+  Status Process(opt::IRContext*) override {
     return Status::SuccessWithoutChange;
   }
 };
diff --git a/source/opt/optimizer.cpp b/source/opt/optimizer.cpp
index 500af89..5cddbe4 100644
--- a/source/opt/optimizer.cpp
+++ b/source/opt/optimizer.cpp
@@ -204,7 +204,7 @@
 bool Optimizer::Run(const uint32_t* original_binary,
                     const size_t original_binary_size,
                     std::vector<uint32_t>* optimized_binary) const {
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(impl_->target_env, impl_->pass_manager.consumer(),
                   original_binary, original_binary_size);
   if (context == nullptr) return false;
diff --git a/source/opt/pass.cpp b/source/opt/pass.cpp
index bceeba0..0e3d98a 100644
--- a/source/opt/pass.cpp
+++ b/source/opt/pass.cpp
@@ -30,16 +30,17 @@
 
 Pass::Pass() : consumer_(nullptr), context_(nullptr), already_run_(false) {}
 
-void Pass::AddCalls(ir::Function* func, std::queue<uint32_t>* todo) {
+void Pass::AddCalls(opt::Function* func, std::queue<uint32_t>* todo) {
   for (auto bi = func->begin(); bi != func->end(); ++bi)
     for (auto ii = bi->begin(); ii != bi->end(); ++ii)
       if (ii->opcode() == SpvOpFunctionCall)
         todo->push(ii->GetSingleWordInOperand(0));
 }
 
-bool Pass::ProcessEntryPointCallTree(ProcessFunction& pfn, ir::Module* module) {
+bool Pass::ProcessEntryPointCallTree(ProcessFunction& pfn,
+                                     opt::Module* module) {
   // Map from function's result id to function
-  std::unordered_map<uint32_t, ir::Function*> id2function;
+  std::unordered_map<uint32_t, opt::Function*> id2function;
   for (auto& fn : *module) id2function[fn.result_id()] = &fn;
 
   // Collect all of the entry points as the roots.
@@ -50,9 +51,9 @@
 }
 
 bool Pass::ProcessReachableCallTree(ProcessFunction& pfn,
-                                    ir::IRContext* irContext) {
+                                    opt::IRContext* irContext) {
   // Map from function's result id to function
-  std::unordered_map<uint32_t, ir::Function*> id2function;
+  std::unordered_map<uint32_t, opt::Function*> id2function;
   for (auto& fn : *irContext->module()) id2function[fn.result_id()] = &fn;
 
   std::queue<uint32_t> roots;
@@ -84,7 +85,7 @@
 
 bool Pass::ProcessCallTreeFromRoots(
     ProcessFunction& pfn,
-    const std::unordered_map<uint32_t, ir::Function*>& id2function,
+    const std::unordered_map<uint32_t, opt::Function*>& id2function,
     std::queue<uint32_t>* roots) {
   // Process call tree
   bool modified = false;
@@ -94,7 +95,7 @@
     const uint32_t fi = roots->front();
     roots->pop();
     if (done.insert(fi).second) {
-      ir::Function* fn = id2function.at(fi);
+      opt::Function* fn = id2function.at(fi);
       modified = pfn(fn) || modified;
       AddCalls(fn, roots);
     }
@@ -102,7 +103,7 @@
   return modified;
 }
 
-Pass::Status Pass::Run(ir::IRContext* ctx) {
+Pass::Status Pass::Run(opt::IRContext* ctx) {
   if (already_run_) {
     return Status::Failure;
   }
@@ -116,9 +117,9 @@
   return status;
 }
 
-uint32_t Pass::GetPointeeTypeId(const ir::Instruction* ptrInst) const {
+uint32_t Pass::GetPointeeTypeId(const opt::Instruction* ptrInst) const {
   const uint32_t ptrTypeId = ptrInst->type_id();
-  const ir::Instruction* ptrTypeInst = get_def_use_mgr()->GetDef(ptrTypeId);
+  const opt::Instruction* ptrTypeInst = get_def_use_mgr()->GetDef(ptrTypeId);
   return ptrTypeInst->GetSingleWordInOperand(kTypePointerTypeIdInIdx);
 }
 
diff --git a/source/opt/pass.h b/source/opt/pass.h
index 468b537..7b038a3 100644
--- a/source/opt/pass.h
+++ b/source/opt/pass.h
@@ -45,7 +45,7 @@
     SuccessWithoutChange = 0x11,
   };
 
-  using ProcessFunction = std::function<bool(ir::Function*)>;
+  using ProcessFunction = std::function<bool(opt::Function*)>;
 
   // Constructs a new pass.
   //
@@ -87,26 +87,27 @@
   }
 
   // Returns a pointer to the current module for this pass.
-  ir::Module* get_module() const { return context_->module(); }
+  opt::Module* get_module() const { return context_->module(); }
 
   // Returns a pointer to the current context for this pass.
-  ir::IRContext* context() const { return context_; }
+  opt::IRContext* context() const { return context_; }
 
   // Returns a pointer to the CFG for current module.
-  ir::CFG* cfg() const { return context()->cfg(); }
+  opt::CFG* cfg() const { return context()->cfg(); }
 
   // Add to |todo| all ids of functions called in |func|.
-  void AddCalls(ir::Function* func, std::queue<uint32_t>* todo);
+  void AddCalls(opt::Function* func, std::queue<uint32_t>* todo);
 
   // Applies |pfn| to every function in the call trees that are rooted at the
   // entry points.  Returns true if any call |pfn| returns true.  By convention
   // |pfn| should return true if it modified the module.
-  bool ProcessEntryPointCallTree(ProcessFunction& pfn, ir::Module* module);
+  bool ProcessEntryPointCallTree(ProcessFunction& pfn, opt::Module* module);
 
   // Applies |pfn| to every function in the call trees rooted at the entry
   // points and exported functions.  Returns true if any call |pfn| returns
   // true.  By convention |pfn| should return true if it modified the module.
-  bool ProcessReachableCallTree(ProcessFunction& pfn, ir::IRContext* irContext);
+  bool ProcessReachableCallTree(ProcessFunction& pfn,
+                                opt::IRContext* irContext);
 
   // Applies |pfn| to every function in the call trees rooted at the elements of
   // |roots|.  Returns true if any call to |pfn| returns true.  By convention
@@ -114,7 +115,7 @@
   // |roots| will be empty.
   bool ProcessCallTreeFromRoots(
       ProcessFunction& pfn,
-      const std::unordered_map<uint32_t, ir::Function*>& id2function,
+      const std::unordered_map<uint32_t, opt::Function*>& id2function,
       std::queue<uint32_t>* roots);
 
   // Run the pass on the given |module|. Returns Status::Failure if errors occur
@@ -125,25 +126,25 @@
   //
   // It is an error if |Run| is called twice with the same instance of the pass.
   // If this happens the return value will be |Failure|.
-  virtual Status Run(ir::IRContext* ctx) final;
+  virtual Status Run(opt::IRContext* ctx) final;
 
   // Returns the set of analyses that the pass is guaranteed to preserve.
-  virtual ir::IRContext::Analysis GetPreservedAnalyses() {
-    return ir::IRContext::kAnalysisNone;
+  virtual opt::IRContext::Analysis GetPreservedAnalyses() {
+    return opt::IRContext::kAnalysisNone;
   }
 
   // Return type id for |ptrInst|'s pointee
-  uint32_t GetPointeeTypeId(const ir::Instruction* ptrInst) const;
+  uint32_t GetPointeeTypeId(const opt::Instruction* ptrInst) const;
 
  protected:
   // Initialize basic data structures for the pass. This sets up the def-use
   // manager, module and other attributes.
-  virtual void InitializeProcessing(ir::IRContext* c) { context_ = c; }
+  virtual void InitializeProcessing(opt::IRContext* c) { context_ = c; }
 
   // Processes the given |module|. Returns Status::Failure if errors occur when
   // processing. Returns the corresponding Status::Success if processing is
   // succesful to indicate whether changes are made to the module.
-  virtual Status Process(ir::IRContext* context) = 0;
+  virtual Status Process(opt::IRContext* context) = 0;
 
   // Return the next available SSA id and increment it.
   uint32_t TakeNextId() { return context_->TakeNextId(); }
@@ -152,7 +153,7 @@
   MessageConsumer consumer_;  // Message consumer.
 
   // The context that this pass belongs to.
-  ir::IRContext* context_;
+  opt::IRContext* context_;
 
   // An instance of a pass can only be run once because it is too hard to
   // enforce proper resetting of internal state for each instance.  This member
diff --git a/source/opt/pass_manager.cpp b/source/opt/pass_manager.cpp
index 45c9c04..ffdf86a 100644
--- a/source/opt/pass_manager.cpp
+++ b/source/opt/pass_manager.cpp
@@ -25,7 +25,7 @@
 
 namespace opt {
 
-Pass::Status PassManager::Run(ir::IRContext* context) {
+Pass::Status PassManager::Run(opt::IRContext* context) {
   auto status = Pass::Status::SuccessWithoutChange;
 
   // If print_all_stream_ is not null, prints the disassembly of the module
diff --git a/source/opt/pass_manager.h b/source/opt/pass_manager.h
index da3620a..41b7391 100644
--- a/source/opt/pass_manager.h
+++ b/source/opt/pass_manager.h
@@ -70,7 +70,7 @@
   // whether changes are made to the module.
   //
   // After running all the passes, they are removed from the list.
-  Pass::Status Run(ir::IRContext* context);
+  Pass::Status Run(opt::IRContext* context);
 
   // Sets the option to print the disassembly before each pass and after the
   // last pass.   Output is written to |out| if that is not null.  No output
diff --git a/source/opt/private_to_local_pass.cpp b/source/opt/private_to_local_pass.cpp
index 9c9d272..35de7ce 100644
--- a/source/opt/private_to_local_pass.cpp
+++ b/source/opt/private_to_local_pass.cpp
@@ -24,7 +24,7 @@
 namespace spvtools {
 namespace opt {
 
-Pass::Status PrivateToLocalPass::Process(ir::IRContext* c) {
+Pass::Status PrivateToLocalPass::Process(opt::IRContext* c) {
   InitializeProcessing(c);
   bool modified = false;
 
@@ -33,7 +33,7 @@
   if (context()->get_feature_mgr()->HasCapability(SpvCapabilityAddresses))
     return Status::SuccessWithoutChange;
 
-  std::vector<std::pair<ir::Instruction*, ir::Function*>> variables_to_move;
+  std::vector<std::pair<opt::Instruction*, opt::Function*>> variables_to_move;
   for (auto& inst : context()->types_values()) {
     if (inst.opcode() != SpvOpVariable) {
       continue;
@@ -44,7 +44,7 @@
       continue;
     }
 
-    ir::Function* target_function = FindLocalFunction(inst);
+    opt::Function* target_function = FindLocalFunction(inst);
     if (target_function != nullptr) {
       variables_to_move.push_back({&inst, target_function});
     }
@@ -58,14 +58,14 @@
   return (modified ? Status::SuccessWithChange : Status::SuccessWithoutChange);
 }
 
-ir::Function* PrivateToLocalPass::FindLocalFunction(
-    const ir::Instruction& inst) const {
+opt::Function* PrivateToLocalPass::FindLocalFunction(
+    const opt::Instruction& inst) const {
   bool found_first_use = false;
-  ir::Function* target_function = nullptr;
+  opt::Function* target_function = nullptr;
   context()->get_def_use_mgr()->ForEachUser(
       inst.result_id(),
-      [&target_function, &found_first_use, this](ir::Instruction* use) {
-        ir::BasicBlock* current_block = context()->get_instr_block(use);
+      [&target_function, &found_first_use, this](opt::Instruction* use) {
+        opt::BasicBlock* current_block = context()->get_instr_block(use);
         if (current_block == nullptr) {
           return;
         }
@@ -75,7 +75,7 @@
           target_function = nullptr;
           return;
         }
-        ir::Function* current_function = current_block->GetParent();
+        opt::Function* current_function = current_block->GetParent();
         if (!found_first_use) {
           found_first_use = true;
           target_function = current_function;
@@ -86,12 +86,12 @@
   return target_function;
 }  // namespace opt
 
-void PrivateToLocalPass::MoveVariable(ir::Instruction* variable,
-                                      ir::Function* function) {
+void PrivateToLocalPass::MoveVariable(opt::Instruction* variable,
+                                      opt::Function* function) {
   // The variable needs to be removed from the global section, and placed in the
   // header of the function.  First step remove from the global list.
   variable->RemoveFromList();
-  std::unique_ptr<ir::Instruction> var(variable);  // Take ownership.
+  std::unique_ptr<opt::Instruction> var(variable);  // Take ownership.
   context()->ForgetUses(variable);
 
   // Update the storage class of the variable.
@@ -112,7 +112,7 @@
 
 uint32_t PrivateToLocalPass::GetNewType(uint32_t old_type_id) {
   auto type_mgr = context()->get_type_mgr();
-  ir::Instruction* old_type_inst = get_def_use_mgr()->GetDef(old_type_id);
+  opt::Instruction* old_type_inst = get_def_use_mgr()->GetDef(old_type_id);
   uint32_t pointee_type_id =
       old_type_inst->GetSingleWordInOperand(kSpvTypePointerTypeIdInIdx);
   uint32_t new_type_id =
@@ -121,7 +121,7 @@
   return new_type_id;
 }
 
-bool PrivateToLocalPass::IsValidUse(const ir::Instruction* inst) const {
+bool PrivateToLocalPass::IsValidUse(const opt::Instruction* inst) const {
   // The cases in this switch have to match the cases in |UpdateUse|.
   // If we don't know how to update it, it is not valid.
   switch (inst->opcode()) {
@@ -131,7 +131,7 @@
       return true;
     case SpvOpAccessChain:
       return context()->get_def_use_mgr()->WhileEachUser(
-          inst, [this](const ir::Instruction* user) {
+          inst, [this](const opt::Instruction* user) {
             if (!IsValidUse(user)) return false;
             return true;
           });
@@ -142,7 +142,7 @@
   }
 }
 
-void PrivateToLocalPass::UpdateUse(ir::Instruction* inst) {
+void PrivateToLocalPass::UpdateUse(opt::Instruction* inst) {
   // The cases in this switch have to match the cases in |IsValidUse|.  If we
   // don't think it is valid, the optimization will not view the variable as a
   // candidate, and therefore the use will not be updated.
@@ -170,11 +170,11 @@
   }
 }
 void PrivateToLocalPass::UpdateUses(uint32_t id) {
-  std::vector<ir::Instruction*> uses;
+  std::vector<opt::Instruction*> uses;
   this->context()->get_def_use_mgr()->ForEachUser(
-      id, [&uses](ir::Instruction* use) { uses.push_back(use); });
+      id, [&uses](opt::Instruction* use) { uses.push_back(use); });
 
-  for (ir::Instruction* use : uses) {
+  for (opt::Instruction* use : uses) {
     UpdateUse(use);
   }
 }
diff --git a/source/opt/private_to_local_pass.h b/source/opt/private_to_local_pass.h
index 7bd4696..a902ea4 100644
--- a/source/opt/private_to_local_pass.h
+++ b/source/opt/private_to_local_pass.h
@@ -28,31 +28,31 @@
 class PrivateToLocalPass : public Pass {
  public:
   const char* name() const override { return "private-to-local"; }
-  Status Process(ir::IRContext*) override;
-  ir::IRContext::Analysis GetPreservedAnalyses() override {
-    return ir::IRContext::kAnalysisDefUse |
-           ir::IRContext::kAnalysisInstrToBlockMapping |
-           ir::IRContext::kAnalysisDecorations |
-           ir::IRContext::kAnalysisCombinators | ir::IRContext::kAnalysisCFG |
-           ir::IRContext::kAnalysisDominatorAnalysis |
-           ir::IRContext::kAnalysisNameMap;
+  Status Process(opt::IRContext*) override;
+  opt::IRContext::Analysis GetPreservedAnalyses() override {
+    return opt::IRContext::kAnalysisDefUse |
+           opt::IRContext::kAnalysisInstrToBlockMapping |
+           opt::IRContext::kAnalysisDecorations |
+           opt::IRContext::kAnalysisCombinators | opt::IRContext::kAnalysisCFG |
+           opt::IRContext::kAnalysisDominatorAnalysis |
+           opt::IRContext::kAnalysisNameMap;
   }
 
  private:
   // Moves |variable| from the private storage class to the function storage
   // class of |function|.
-  void MoveVariable(ir::Instruction* variable, ir::Function* function);
+  void MoveVariable(opt::Instruction* variable, opt::Function* function);
 
   // |inst| is an instruction declaring a varible.  If that variable is
   // referenced in a single function and all of uses are valid as defined by
   // |IsValidUse|, then that function is returned.  Otherwise, the return
   // value is |nullptr|.
-  ir::Function* FindLocalFunction(const ir::Instruction& inst) const;
+  opt::Function* FindLocalFunction(const opt::Instruction& inst) const;
 
   // Returns true is |inst| is a valid use of a pointer.  In this case, a
   // valid use is one where the transformation is able to rewrite the type to
   // match a change in storage class of the original variable.
-  bool IsValidUse(const ir::Instruction* inst) const;
+  bool IsValidUse(const opt::Instruction* inst) const;
 
   // Given the result id of a pointer type, |old_type_id|, this function
   // returns the id of a the same pointer type except the storage class has
@@ -62,7 +62,7 @@
 
   // Updates |inst|, and any instruction dependent on |inst|, to reflect the
   // change of the base pointer now pointing to the function storage class.
-  void UpdateUse(ir::Instruction* inst);
+  void UpdateUse(opt::Instruction* inst);
   void UpdateUses(uint32_t id);
 };
 
diff --git a/source/opt/propagator.cpp b/source/opt/propagator.cpp
index d5d7612..4844ac3 100644
--- a/source/opt/propagator.cpp
+++ b/source/opt/propagator.cpp
@@ -18,7 +18,7 @@
 namespace opt {
 
 void SSAPropagator::AddControlEdge(const Edge& edge) {
-  ir::BasicBlock* dest_bb = edge.dest;
+  opt::BasicBlock* dest_bb = edge.dest;
 
   // Refuse to add the exit block to the work list.
   if (dest_bb == ctx_->cfg()->pseudo_exit_block()) {
@@ -36,14 +36,14 @@
   blocks_.push(dest_bb);
 }
 
-void SSAPropagator::AddSSAEdges(ir::Instruction* instr) {
+void SSAPropagator::AddSSAEdges(opt::Instruction* instr) {
   // Ignore instructions that produce no result.
   if (instr->result_id() == 0) {
     return;
   }
 
   get_def_use_mgr()->ForEachUser(
-      instr->result_id(), [this](ir::Instruction* use_instr) {
+      instr->result_id(), [this](opt::Instruction* use_instr) {
         // If the basic block for |use_instr| has not been simulated yet, do
         // nothing.  The instruction |use_instr| will be simulated next time the
         // block is scheduled.
@@ -57,17 +57,18 @@
       });
 }
 
-bool SSAPropagator::IsPhiArgExecutable(ir::Instruction* phi, uint32_t i) const {
-  ir::BasicBlock* phi_bb = ctx_->get_instr_block(phi);
+bool SSAPropagator::IsPhiArgExecutable(opt::Instruction* phi,
+                                       uint32_t i) const {
+  opt::BasicBlock* phi_bb = ctx_->get_instr_block(phi);
 
   uint32_t in_label_id = phi->GetSingleWordOperand(i + 1);
-  ir::Instruction* in_label_instr = get_def_use_mgr()->GetDef(in_label_id);
-  ir::BasicBlock* in_bb = ctx_->get_instr_block(in_label_instr);
+  opt::Instruction* in_label_instr = get_def_use_mgr()->GetDef(in_label_id);
+  opt::BasicBlock* in_bb = ctx_->get_instr_block(in_label_instr);
 
   return IsEdgeExecutable(Edge(in_bb, phi_bb));
 }
 
-bool SSAPropagator::SetStatus(ir::Instruction* inst, PropStatus status) {
+bool SSAPropagator::SetStatus(opt::Instruction* inst, PropStatus status) {
   bool has_old_status = false;
   PropStatus old_status = kVarying;
   if (HasStatus(inst)) {
@@ -84,7 +85,7 @@
   return status_changed;
 }
 
-bool SSAPropagator::Simulate(ir::Instruction* instr) {
+bool SSAPropagator::Simulate(opt::Instruction* instr) {
   bool changed = false;
 
   // Don't bother visiting instructions that should not be simulated again.
@@ -92,7 +93,7 @@
     return changed;
   }
 
-  ir::BasicBlock* dest_bb = nullptr;
+  opt::BasicBlock* dest_bb = nullptr;
   PropStatus status = visit_fn_(instr, &dest_bb);
   bool status_changed = SetStatus(instr, status);
 
@@ -107,7 +108,7 @@
     // If |instr| is a block terminator, add all the control edges out of its
     // block.
     if (instr->IsBlockTerminator()) {
-      ir::BasicBlock* block = ctx_->get_instr_block(instr);
+      opt::BasicBlock* block = ctx_->get_instr_block(instr);
       for (const auto& e : bb_succs_.at(block)) {
         AddControlEdge(e);
       }
@@ -145,7 +146,7 @@
              "malformed Phi arguments");
 
       uint32_t arg_id = instr->GetSingleWordOperand(i);
-      ir::Instruction* arg_def_instr = get_def_use_mgr()->GetDef(arg_id);
+      opt::Instruction* arg_def_instr = get_def_use_mgr()->GetDef(arg_id);
       if (!IsPhiArgExecutable(instr, i) || ShouldSimulateAgain(arg_def_instr)) {
         has_operands_to_simulate = true;
         break;
@@ -157,7 +158,7 @@
     // also be simulated again.
     has_operands_to_simulate =
         !instr->WhileEachInId([this](const uint32_t* use) {
-          ir::Instruction* def_instr = get_def_use_mgr()->GetDef(*use);
+          opt::Instruction* def_instr = get_def_use_mgr()->GetDef(*use);
           if (ShouldSimulateAgain(def_instr)) {
             return false;
           }
@@ -172,7 +173,7 @@
   return changed;
 }
 
-bool SSAPropagator::Simulate(ir::BasicBlock* block) {
+bool SSAPropagator::Simulate(opt::BasicBlock* block) {
   if (block == ctx_->cfg()->pseudo_exit_block()) {
     return false;
   }
@@ -182,13 +183,14 @@
   // incoming edges. When those edges are marked executable, the corresponding
   // operand can be simulated.
   bool changed = false;
-  block->ForEachPhiInst(
-      [&changed, this](ir::Instruction* instr) { changed |= Simulate(instr); });
+  block->ForEachPhiInst([&changed, this](opt::Instruction* instr) {
+    changed |= Simulate(instr);
+  });
 
   // If this is the first time this block is being simulated, simulate every
   // statement in it.
   if (!BlockHasBeenSimulated(block)) {
-    block->ForEachInst([this, &changed](ir::Instruction* instr) {
+    block->ForEachInst([this, &changed](opt::Instruction* instr) {
       if (instr->opcode() != SpvOpPhi) {
         changed |= Simulate(instr);
       }
@@ -206,9 +208,9 @@
   return changed;
 }
 
-void SSAPropagator::Initialize(ir::Function* fn) {
+void SSAPropagator::Initialize(opt::Function* fn) {
   // Compute predecessor and successor blocks for every block in |fn|'s CFG.
-  // TODO(dnovillo): Move this to ir::CFG and always build them. Alternately,
+  // TODO(dnovillo): Move this to opt::CFG and always build them. Alternately,
   // move it to IRContext and build CFG preds/succs on-demand.
   bb_succs_[ctx_->cfg()->pseudo_entry_block()].push_back(
       Edge(ctx_->cfg()->pseudo_entry_block(), fn->entry().get()));
@@ -216,7 +218,7 @@
   for (auto& block : *fn) {
     const auto& const_block = block;
     const_block.ForEachSuccessorLabel([this, &block](const uint32_t label_id) {
-      ir::BasicBlock* succ_bb =
+      opt::BasicBlock* succ_bb =
           ctx_->get_instr_block(get_def_use_mgr()->GetDef(label_id));
       bb_succs_[&block].push_back(Edge(&block, succ_bb));
       bb_preds_[succ_bb].push_back(Edge(succ_bb, &block));
@@ -236,7 +238,7 @@
   }
 }
 
-bool SSAPropagator::Run(ir::Function* fn) {
+bool SSAPropagator::Run(opt::Function* fn) {
   Initialize(fn);
 
   bool changed = false;
@@ -252,7 +254,7 @@
 
     // Simulate edges from the SSA queue.
     if (!ssa_edge_uses_.empty()) {
-      ir::Instruction* instr = ssa_edge_uses_.front();
+      opt::Instruction* instr = ssa_edge_uses_.front();
       changed |= Simulate(instr);
       ssa_edge_uses_.pop();
     }
@@ -261,7 +263,7 @@
 #ifndef NDEBUG
   // Verify all visited values have settled. No value that has been simulated
   // should end on not interesting.
-  fn->ForEachInst([this](ir::Instruction* inst) {
+  fn->ForEachInst([this](opt::Instruction* inst) {
     assert(
         (!HasStatus(inst) || Status(inst) != SSAPropagator::kNotInteresting) &&
         "Unsettled value");
diff --git a/source/opt/propagator.h b/source/opt/propagator.h
index 5ab2ec1..52e7bba 100644
--- a/source/opt/propagator.h
+++ b/source/opt/propagator.h
@@ -30,12 +30,12 @@
 
 // Represents a CFG control edge.
 struct Edge {
-  Edge(ir::BasicBlock* b1, ir::BasicBlock* b2) : source(b1), dest(b2) {
+  Edge(opt::BasicBlock* b1, opt::BasicBlock* b2) : source(b1), dest(b2) {
     assert(source && "CFG edges cannot have a null source block.");
     assert(dest && "CFG edges cannot have a null destination block.");
   }
-  ir::BasicBlock* source;
-  ir::BasicBlock* dest;
+  opt::BasicBlock* source;
+  opt::BasicBlock* dest;
   bool operator<(const Edge& o) const {
     return std::make_pair(source->id(), dest->id()) <
            std::make_pair(o.source->id(), o.dest->id());
@@ -150,11 +150,11 @@
 //
 //   auto ctx = BuildModule(...);
 //   std::map<uint32_t, uint32_t> values;
-//   const auto visit_fn = [&ctx, &values](ir::Instruction* instr,
-//                                         ir::BasicBlock** dest_bb) {
+//   const auto visit_fn = [&ctx, &values](opt::Instruction* instr,
+//                                         opt::BasicBlock** dest_bb) {
 //     if (instr->opcode() == SpvOpStore) {
 //       uint32_t rhs_id = instr->GetSingleWordOperand(1);
-//       ir::Instruction* rhs_def = ctx->get_def_use_mgr()->GetDef(rhs_id);
+//       opt::Instruction* rhs_def = ctx->get_def_use_mgr()->GetDef(rhs_id);
 //       if (rhs_def->opcode() == SpvOpConstant) {
 //         uint32_t val = rhs_def->GetSingleWordOperand(2);
 //         values[rhs_id] = val;
@@ -184,65 +184,65 @@
   enum PropStatus { kNotInteresting, kInteresting, kVarying };
 
   using VisitFunction =
-      std::function<PropStatus(ir::Instruction*, ir::BasicBlock**)>;
+      std::function<PropStatus(opt::Instruction*, opt::BasicBlock**)>;
 
-  SSAPropagator(ir::IRContext* context, const VisitFunction& visit_fn)
+  SSAPropagator(opt::IRContext* context, const VisitFunction& visit_fn)
       : ctx_(context), visit_fn_(visit_fn) {}
 
   // Runs the propagator on function |fn|. Returns true if changes were made to
   // the function. Otherwise, it returns false.
-  bool Run(ir::Function* fn);
+  bool Run(opt::Function* fn);
 
   // Returns true if the |i|th argument for |phi| comes through a CFG edge that
   // has been marked executable. |i| should be an index value accepted by
   // Instruction::GetSingleWordOperand.
-  bool IsPhiArgExecutable(ir::Instruction* phi, uint32_t i) const;
+  bool IsPhiArgExecutable(opt::Instruction* phi, uint32_t i) const;
 
   // Returns true if |inst| has a recorded status. This will be true once |inst|
   // has been simulated once.
-  bool HasStatus(ir::Instruction* inst) const { return statuses_.count(inst); }
+  bool HasStatus(opt::Instruction* inst) const { return statuses_.count(inst); }
 
   // Returns the current propagation status of |inst|. Assumes
   // |HasStatus(inst)| returns true.
-  PropStatus Status(ir::Instruction* inst) const {
+  PropStatus Status(opt::Instruction* inst) const {
     return statuses_.find(inst)->second;
   }
 
   // Records the propagation status |status| for |inst|. Returns true if the
   // status for |inst| has changed or set was set for the first time.
-  bool SetStatus(ir::Instruction* inst, PropStatus status);
+  bool SetStatus(opt::Instruction* inst, PropStatus status);
 
  private:
   // Initialize processing.
-  void Initialize(ir::Function* fn);
+  void Initialize(opt::Function* fn);
 
   // Simulate the execution |block| by calling |visit_fn_| on every instruction
   // in it.
-  bool Simulate(ir::BasicBlock* block);
+  bool Simulate(opt::BasicBlock* block);
 
   // Simulate the execution of |instr| by replacing all the known values in
   // every operand and determining whether the result is interesting for
   // propagation. This invokes the callback function |visit_fn_| to determine
   // the value computed by |instr|.
-  bool Simulate(ir::Instruction* instr);
+  bool Simulate(opt::Instruction* instr);
 
   // Returns true if |instr| should be simulated again.
-  bool ShouldSimulateAgain(ir::Instruction* instr) const {
+  bool ShouldSimulateAgain(opt::Instruction* instr) const {
     return do_not_simulate_.find(instr) == do_not_simulate_.end();
   }
 
   // Add |instr| to the set of instructions not to simulate again.
-  void DontSimulateAgain(ir::Instruction* instr) {
+  void DontSimulateAgain(opt::Instruction* instr) {
     do_not_simulate_.insert(instr);
   }
 
   // Returns true if |block| has been simulated already.
-  bool BlockHasBeenSimulated(ir::BasicBlock* block) const {
+  bool BlockHasBeenSimulated(opt::BasicBlock* block) const {
     return simulated_blocks_.find(block) != simulated_blocks_.end();
   }
 
   // Marks block |block| as simulated.
-  void MarkBlockSimulated(ir::BasicBlock* block) {
+  void MarkBlockSimulated(opt::BasicBlock* block) {
     simulated_blocks_.insert(block);
   }
 
@@ -268,10 +268,10 @@
 
   // Adds all the instructions that use the result of |instr| to the SSA edges
   // work list. If |instr| produces no result id, this does nothing.
-  void AddSSAEdges(ir::Instruction* instr);
+  void AddSSAEdges(opt::Instruction* instr);
 
   // IR context to use.
-  ir::IRContext* ctx_;
+  opt::IRContext* ctx_;
 
   // Function that visits instructions during simulation. The output of this
   // function is used to determine if the simulated instruction produced a value
@@ -281,33 +281,33 @@
 
   // SSA def-use edges to traverse. Each entry is a destination statement for an
   // SSA def-use edge as returned by |def_use_manager_|.
-  std::queue<ir::Instruction*> ssa_edge_uses_;
+  std::queue<opt::Instruction*> ssa_edge_uses_;
 
   // Blocks to simulate.
-  std::queue<ir::BasicBlock*> blocks_;
+  std::queue<opt::BasicBlock*> blocks_;
 
   // Blocks simulated during propagation.
-  std::unordered_set<ir::BasicBlock*> simulated_blocks_;
+  std::unordered_set<opt::BasicBlock*> simulated_blocks_;
 
   // Set of instructions that should not be simulated again because they have
   // been found to be in the kVarying state.
-  std::unordered_set<ir::Instruction*> do_not_simulate_;
+  std::unordered_set<opt::Instruction*> do_not_simulate_;
 
   // Map between a basic block and its predecessor edges.
-  // TODO(dnovillo): Move this to ir::CFG and always build them. Alternately,
+  // TODO(dnovillo): Move this to opt::CFG and always build them. Alternately,
   // move it to IRContext and build CFG preds/succs on-demand.
-  std::unordered_map<ir::BasicBlock*, std::vector<Edge>> bb_preds_;
+  std::unordered_map<opt::BasicBlock*, std::vector<Edge>> bb_preds_;
 
   // Map between a basic block and its successor edges.
-  // TODO(dnovillo): Move this to ir::CFG and always build them. Alternately,
+  // TODO(dnovillo): Move this to opt::CFG and always build them. Alternately,
   // move it to IRContext and build CFG preds/succs on-demand.
-  std::unordered_map<ir::BasicBlock*, std::vector<Edge>> bb_succs_;
+  std::unordered_map<opt::BasicBlock*, std::vector<Edge>> bb_succs_;
 
   // Set of executable CFG edges.
   std::set<Edge> executable_edges_;
 
   // Tracks instruction propagation status.
-  std::unordered_map<ir::Instruction*, SSAPropagator::PropStatus> statuses_;
+  std::unordered_map<opt::Instruction*, SSAPropagator::PropStatus> statuses_;
 };
 
 std::ostream& operator<<(std::ostream& str,
diff --git a/source/opt/reduce_load_size.cpp b/source/opt/reduce_load_size.cpp
index 551c72b..1e984f3 100644
--- a/source/opt/reduce_load_size.cpp
+++ b/source/opt/reduce_load_size.cpp
@@ -29,12 +29,12 @@
 namespace spvtools {
 namespace opt {
 
-Pass::Status ReduceLoadSize::Process(ir::IRContext* ctx) {
+Pass::Status ReduceLoadSize::Process(opt::IRContext* ctx) {
   InitializeProcessing(ctx);
   bool modified = false;
 
   for (auto& func : *get_module()) {
-    func.ForEachInst([&modified, this](ir::Instruction* inst) {
+    func.ForEachInst([&modified, this](opt::Instruction* inst) {
       if (inst->opcode() == SpvOpCompositeExtract) {
         if (ShouldReplaceExtract(inst)) {
           modified |= ReplaceExtract(inst);
@@ -46,7 +46,7 @@
   return modified ? Status::SuccessWithChange : Status::SuccessWithoutChange;
 }
 
-bool ReduceLoadSize::ReplaceExtract(ir::Instruction* inst) {
+bool ReduceLoadSize::ReplaceExtract(opt::Instruction* inst) {
   assert(inst->opcode() == SpvOpCompositeExtract &&
          "Wrong opcode.  Should be OpCompositeExtract.");
   analysis::DefUseManager* def_use_mgr = inst->context()->get_def_use_mgr();
@@ -55,7 +55,7 @@
 
   uint32_t composite_id =
       inst->GetSingleWordInOperand(kExtractCompositeIdInIdx);
-  ir::Instruction* composite_inst = def_use_mgr->GetDef(composite_id);
+  opt::Instruction* composite_inst = def_use_mgr->GetDef(composite_id);
 
   if (composite_inst->opcode() != SpvOpLoad) {
     return false;
@@ -67,7 +67,7 @@
     return false;
   }
 
-  ir::Instruction* var = composite_inst->GetBaseAddress();
+  opt::Instruction* var = composite_inst->GetBaseAddress();
   if (var == nullptr || var->opcode() != SpvOpVariable) {
     return false;
   }
@@ -87,8 +87,8 @@
   // We cannot create the new access chain load in the position of the extract
   // because the storage may have been written to in between.
   InstructionBuilder ir_builder(inst->context(), composite_inst,
-                                ir::IRContext::kAnalysisInstrToBlockMapping |
-                                    ir::IRContext::kAnalysisDefUse);
+                                opt::IRContext::kAnalysisInstrToBlockMapping |
+                                    opt::IRContext::kAnalysisDefUse);
 
   uint32_t pointer_to_result_type_id =
       type_mgr->FindPointerToType(inst->type_id(), storage_class);
@@ -105,10 +105,10 @@
     ids.push_back(const_mgr->GetDefiningInstruction(index_const)->result_id());
   }
 
-  ir::Instruction* new_access_chain = ir_builder.AddAccessChain(
+  opt::Instruction* new_access_chain = ir_builder.AddAccessChain(
       pointer_to_result_type_id,
       composite_inst->GetSingleWordInOperand(kLoadPointerInIdx), ids);
-  ir::Instruction* new_laod =
+  opt::Instruction* new_laod =
       ir_builder.AddLoad(inst->type_id(), new_access_chain->result_id());
 
   context()->ReplaceAllUsesWith(inst->result_id(), new_laod->result_id());
@@ -116,9 +116,9 @@
   return true;
 }
 
-bool ReduceLoadSize::ShouldReplaceExtract(ir::Instruction* inst) {
+bool ReduceLoadSize::ShouldReplaceExtract(opt::Instruction* inst) {
   analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr();
-  ir::Instruction* op_inst = def_use_mgr->GetDef(
+  opt::Instruction* op_inst = def_use_mgr->GetDef(
       inst->GetSingleWordInOperand(kExtractCompositeIdInIdx));
 
   if (op_inst->opcode() != SpvOpLoad) {
@@ -134,7 +134,7 @@
   std::set<uint32_t> elements_used;
 
   all_elements_used = !def_use_mgr->WhileEachUser(
-      op_inst, [&elements_used](ir::Instruction* use) {
+      op_inst, [&elements_used](opt::Instruction* use) {
         if (use->opcode() != SpvOpCompositeExtract) {
           return false;
         }
diff --git a/source/opt/reduce_load_size.h b/source/opt/reduce_load_size.h
index beec520..e5f948a 100644
--- a/source/opt/reduce_load_size.h
+++ b/source/opt/reduce_load_size.h
@@ -26,16 +26,16 @@
 class ReduceLoadSize : public Pass {
  public:
   const char* name() const override { return "reduce-load-size"; }
-  Status Process(ir::IRContext* irContext) override;
+  Status Process(opt::IRContext* irContext) override;
 
   // Return the mask of preserved Analyses.
-  ir::IRContext::Analysis GetPreservedAnalyses() override {
-    return ir::IRContext::kAnalysisDefUse |
-           ir::IRContext::kAnalysisInstrToBlockMapping |
-           ir::IRContext::kAnalysisCombinators | ir::IRContext::kAnalysisCFG |
-           ir::IRContext::kAnalysisDominatorAnalysis |
-           ir::IRContext::kAnalysisLoopAnalysis |
-           ir::IRContext::kAnalysisNameMap;
+  opt::IRContext::Analysis GetPreservedAnalyses() override {
+    return opt::IRContext::kAnalysisDefUse |
+           opt::IRContext::kAnalysisInstrToBlockMapping |
+           opt::IRContext::kAnalysisCombinators | opt::IRContext::kAnalysisCFG |
+           opt::IRContext::kAnalysisDominatorAnalysis |
+           opt::IRContext::kAnalysisLoopAnalysis |
+           opt::IRContext::kAnalysisNameMap;
   }
 
  private:
@@ -44,13 +44,13 @@
   // feeding |inst|.  Returns true if the substitution happened.  The position
   // of the new instructions will be in the same place as the load feeding the
   // extract.
-  bool ReplaceExtract(ir::Instruction* inst);
+  bool ReplaceExtract(opt::Instruction* inst);
 
   // Returns true if the OpCompositeExtract instruction |inst| should be replace
   // or not.  This is determined by looking at the load that feeds |inst| if
   // it is a load.  |should_replace_cache_| is used to cache the results based
   // on the load feeding |inst|.
-  bool ShouldReplaceExtract(ir::Instruction* inst);
+  bool ShouldReplaceExtract(opt::Instruction* inst);
 
   // Maps the result id of an OpLoad instruction to the result of whether or
   // not the OpCompositeExtract that use the id should be replaced.
diff --git a/source/opt/redundancy_elimination.cpp b/source/opt/redundancy_elimination.cpp
index 347e2fe..a3b645b 100644
--- a/source/opt/redundancy_elimination.cpp
+++ b/source/opt/redundancy_elimination.cpp
@@ -19,7 +19,7 @@
 namespace spvtools {
 namespace opt {
 
-Pass::Status RedundancyEliminationPass::Process(ir::IRContext* c) {
+Pass::Status RedundancyEliminationPass::Process(opt::IRContext* c) {
   InitializeProcessing(c);
 
   bool modified = false;
diff --git a/source/opt/redundancy_elimination.h b/source/opt/redundancy_elimination.h
index 634ecc3..bcf4735 100644
--- a/source/opt/redundancy_elimination.h
+++ b/source/opt/redundancy_elimination.h
@@ -30,7 +30,7 @@
 class RedundancyEliminationPass : public LocalRedundancyEliminationPass {
  public:
   const char* name() const override { return "redundancy-elimination"; }
-  Status Process(ir::IRContext*) override;
+  Status Process(opt::IRContext*) override;
 
  protected:
   // Removes for all total redundancies in the function starting at |bb|.
diff --git a/source/opt/reflect.h b/source/opt/reflect.h
index ef2d849..f6ea50a 100644
--- a/source/opt/reflect.h
+++ b/source/opt/reflect.h
@@ -18,7 +18,7 @@
 #include "latest_version_spirv_header.h"
 
 namespace spvtools {
-namespace ir {
+namespace opt {
 
 // Note that as SPIR-V evolves over time, new opcodes may appear. So the
 // following functions tend to be outdated and should be updated when SPIR-V
@@ -59,7 +59,7 @@
   return opcode >= SpvOpBranch && opcode <= SpvOpUnreachable;
 }
 
-}  // namespace ir
+}  // namespace opt
 }  // namespace spvtools
 
 #endif  // LIBSPIRV_OPT_REFLECT_H_
diff --git a/source/opt/register_pressure.cpp b/source/opt/register_pressure.cpp
index d414e70..a73a026 100644
--- a/source/opt/register_pressure.cpp
+++ b/source/opt/register_pressure.cpp
@@ -31,25 +31,25 @@
 // phi instructions defined in the basic block |bb|.
 class ExcludePhiDefinedInBlock {
  public:
-  ExcludePhiDefinedInBlock(ir::IRContext* context, const ir::BasicBlock* bb)
+  ExcludePhiDefinedInBlock(opt::IRContext* context, const opt::BasicBlock* bb)
       : context_(context), bb_(bb) {}
 
-  bool operator()(ir::Instruction* insn) const {
+  bool operator()(opt::Instruction* insn) const {
     return !(insn->opcode() == SpvOpPhi &&
              context_->get_instr_block(insn) == bb_);
   }
 
  private:
-  ir::IRContext* context_;
-  const ir::BasicBlock* bb_;
+  opt::IRContext* context_;
+  const opt::BasicBlock* bb_;
 };
 
 // Returns true if |insn| generates a SSA register that is likely to require a
 // physical register.
-bool CreatesRegisterUsage(ir::Instruction* insn) {
+bool CreatesRegisterUsage(opt::Instruction* insn) {
   if (!insn->HasResultId()) return false;
   if (insn->opcode() == SpvOpUndef) return false;
-  if (ir::IsConstantInst(insn->opcode())) return false;
+  if (opt::IsConstantInst(insn->opcode())) return false;
   if (insn->opcode() == SpvOpLabel) return false;
   return true;
 }
@@ -60,7 +60,7 @@
 // computing liveness sets in strict ssa programs" from Boissinot et al.
 class ComputeRegisterLiveness {
  public:
-  ComputeRegisterLiveness(RegisterLiveness* reg_pressure, ir::Function* f)
+  ComputeRegisterLiveness(RegisterLiveness* reg_pressure, opt::Function* f)
       : reg_pressure_(reg_pressure),
         context_(reg_pressure->GetContext()),
         function_(f),
@@ -79,7 +79,7 @@
   void Compute() {
     cfg_.ForEachBlockInPostOrder(
         &*function_->begin(),
-        [this](ir::BasicBlock* bb) { ComputePartialLiveness(bb); });
+        [this](opt::BasicBlock* bb) { ComputePartialLiveness(bb); });
     DoLoopLivenessUnification();
     EvaluateRegisterRequirements();
   }
@@ -87,15 +87,15 @@
  private:
   // Registers all SSA register used by successors of |bb| in their phi
   // instructions.
-  void ComputePhiUses(const ir::BasicBlock& bb,
+  void ComputePhiUses(const opt::BasicBlock& bb,
                       RegisterLiveness::RegionRegisterLiveness::LiveSet* live) {
     uint32_t bb_id = bb.id();
     bb.ForEachSuccessorLabel([live, bb_id, this](uint32_t sid) {
-      ir::BasicBlock* succ_bb = cfg_.block(sid);
-      succ_bb->ForEachPhiInst([live, bb_id, this](const ir::Instruction* phi) {
+      opt::BasicBlock* succ_bb = cfg_.block(sid);
+      succ_bb->ForEachPhiInst([live, bb_id, this](const opt::Instruction* phi) {
         for (uint32_t i = 0; i < phi->NumInOperands(); i += 2) {
           if (phi->GetSingleWordInOperand(i + 1) == bb_id) {
-            ir::Instruction* insn_op =
+            opt::Instruction* insn_op =
                 def_use_manager_.GetDef(phi->GetSingleWordInOperand(i));
             if (CreatesRegisterUsage(insn_op)) {
               live->insert(insn_op);
@@ -109,7 +109,7 @@
 
   // Computes register liveness for each basic blocks but ignores all
   // back-edges.
-  void ComputePartialLiveness(ir::BasicBlock* bb) {
+  void ComputePartialLiveness(opt::BasicBlock* bb) {
     assert(reg_pressure_->Get(bb) == nullptr &&
            "Basic block already processed");
 
@@ -117,35 +117,35 @@
         reg_pressure_->GetOrInsert(bb->id());
     ComputePhiUses(*bb, &live_inout->live_out_);
 
-    const ir::BasicBlock* cbb = bb;
+    const opt::BasicBlock* cbb = bb;
     cbb->ForEachSuccessorLabel([&live_inout, bb, this](uint32_t sid) {
       // Skip back edges.
       if (dom_tree_.Dominates(sid, bb->id())) {
         return;
       }
 
-      ir::BasicBlock* succ_bb = cfg_.block(sid);
+      opt::BasicBlock* succ_bb = cfg_.block(sid);
       RegisterLiveness::RegionRegisterLiveness* succ_live_inout =
           reg_pressure_->Get(succ_bb);
       assert(succ_live_inout &&
              "Successor liveness analysis was not performed");
 
       ExcludePhiDefinedInBlock predicate(context_, succ_bb);
-      auto filter = ir::MakeFilterIteratorRange(
+      auto filter = opt::MakeFilterIteratorRange(
           succ_live_inout->live_in_.begin(), succ_live_inout->live_in_.end(),
           predicate);
       live_inout->live_out_.insert(filter.begin(), filter.end());
     });
 
     live_inout->live_in_ = live_inout->live_out_;
-    for (ir::Instruction& insn : ir::make_range(bb->rbegin(), bb->rend())) {
+    for (opt::Instruction& insn : opt::make_range(bb->rbegin(), bb->rend())) {
       if (insn.opcode() == SpvOpPhi) {
         live_inout->live_in_.insert(&insn);
         break;
       }
       live_inout->live_in_.erase(&insn);
       insn.ForEachInId([live_inout, this](uint32_t* id) {
-        ir::Instruction* insn_op = def_use_manager_.GetDef(*id);
+        opt::Instruction* insn_op = def_use_manager_.GetDef(*id);
         if (CreatesRegisterUsage(insn_op)) {
           live_inout->live_in_.insert(insn_op);
         }
@@ -155,15 +155,15 @@
 
   // Propagates the register liveness information of each loop iterators.
   void DoLoopLivenessUnification() {
-    for (const ir::Loop* loop : *loop_desc_.GetDummyRootLoop()) {
+    for (const opt::Loop* loop : *loop_desc_.GetDummyRootLoop()) {
       DoLoopLivenessUnification(*loop);
     }
   }
 
   // Propagates the register liveness information of loop iterators trough-out
   // the loop body.
-  void DoLoopLivenessUnification(const ir::Loop& loop) {
-    auto blocks_in_loop = ir::MakeFilterIteratorRange(
+  void DoLoopLivenessUnification(const opt::Loop& loop) {
+    auto blocks_in_loop = opt::MakeFilterIteratorRange(
         loop.GetBlocks().begin(), loop.GetBlocks().end(),
         [&loop, this](uint32_t bb_id) {
           return bb_id != loop.GetHeaderBlock()->id() &&
@@ -176,12 +176,12 @@
            "Liveness analysis was not performed for the current block");
 
     ExcludePhiDefinedInBlock predicate(context_, loop.GetHeaderBlock());
-    auto live_loop = ir::MakeFilterIteratorRange(
+    auto live_loop = opt::MakeFilterIteratorRange(
         header_live_inout->live_in_.begin(), header_live_inout->live_in_.end(),
         predicate);
 
     for (uint32_t bb_id : blocks_in_loop) {
-      ir::BasicBlock* bb = cfg_.block(bb_id);
+      opt::BasicBlock* bb = cfg_.block(bb_id);
 
       RegisterLiveness::RegionRegisterLiveness* live_inout =
           reg_pressure_->Get(bb);
@@ -189,7 +189,7 @@
       live_inout->live_out_.insert(live_loop.begin(), live_loop.end());
     }
 
-    for (const ir::Loop* inner_loop : loop) {
+    for (const opt::Loop* inner_loop : loop) {
       RegisterLiveness::RegionRegisterLiveness* live_inout =
           reg_pressure_->Get(inner_loop->GetHeaderBlock());
       live_inout->live_in_.insert(live_loop.begin(), live_loop.end());
@@ -201,19 +201,19 @@
 
   // Get the number of required registers for this each basic block.
   void EvaluateRegisterRequirements() {
-    for (ir::BasicBlock& bb : *function_) {
+    for (opt::BasicBlock& bb : *function_) {
       RegisterLiveness::RegionRegisterLiveness* live_inout =
           reg_pressure_->Get(bb.id());
       assert(live_inout != nullptr && "Basic block not processed");
 
       size_t reg_count = live_inout->live_out_.size();
-      for (ir::Instruction* insn : live_inout->live_out_) {
+      for (opt::Instruction* insn : live_inout->live_out_) {
         live_inout->AddRegisterClass(insn);
       }
       live_inout->used_registers_ = reg_count;
 
       std::unordered_set<uint32_t> die_in_block;
-      for (ir::Instruction& insn : ir::make_range(bb.rbegin(), bb.rend())) {
+      for (opt::Instruction& insn : opt::make_range(bb.rbegin(), bb.rend())) {
         // If it is a phi instruction, the register pressure will not change
         // anymore.
         if (insn.opcode() == SpvOpPhi) {
@@ -222,7 +222,7 @@
 
         insn.ForEachInId(
             [live_inout, &die_in_block, &reg_count, this](uint32_t* id) {
-              ir::Instruction* op_insn = def_use_manager_.GetDef(*id);
+              opt::Instruction* op_insn = def_use_manager_.GetDef(*id);
               if (!CreatesRegisterUsage(op_insn) ||
                   live_inout->live_out_.count(op_insn)) {
                 // already taken into account.
@@ -244,18 +244,18 @@
   }
 
   RegisterLiveness* reg_pressure_;
-  ir::IRContext* context_;
-  ir::Function* function_;
-  ir::CFG& cfg_;
+  opt::IRContext* context_;
+  opt::Function* function_;
+  opt::CFG& cfg_;
   analysis::DefUseManager& def_use_manager_;
   DominatorTree& dom_tree_;
-  ir::LoopDescriptor& loop_desc_;
+  opt::LoopDescriptor& loop_desc_;
 };
 }  // namespace
 
 // Get the number of required registers for each basic block.
 void RegisterLiveness::RegionRegisterLiveness::AddRegisterClass(
-    ir::Instruction* insn) {
+    opt::Instruction* insn) {
   assert(CreatesRegisterUsage(insn) && "Instruction does not use a register");
   analysis::Type* type =
       insn->context()->get_type_mgr()->GetType(insn->type_id());
@@ -264,7 +264,7 @@
 
   insn->context()->get_decoration_mgr()->WhileEachDecoration(
       insn->result_id(), SpvDecorationUniform,
-      [&reg_class](const ir::Instruction&) {
+      [&reg_class](const opt::Instruction&) {
         reg_class.is_uniform_ = true;
         return false;
       });
@@ -272,13 +272,13 @@
   AddRegisterClass(reg_class);
 }
 
-void RegisterLiveness::Analyze(ir::Function* f) {
+void RegisterLiveness::Analyze(opt::Function* f) {
   block_pressure_.clear();
   ComputeRegisterLiveness(this, f).Compute();
 }
 
 void RegisterLiveness::ComputeLoopRegisterPressure(
-    const ir::Loop& loop, RegionRegisterLiveness* loop_reg_pressure) const {
+    const opt::Loop& loop, RegionRegisterLiveness* loop_reg_pressure) const {
   loop_reg_pressure->Clear();
 
   const RegionRegisterLiveness* header_live_inout = Get(loop.GetHeaderBlock());
@@ -294,11 +294,11 @@
   }
 
   std::unordered_set<uint32_t> seen_insn;
-  for (ir::Instruction* insn : loop_reg_pressure->live_out_) {
+  for (opt::Instruction* insn : loop_reg_pressure->live_out_) {
     loop_reg_pressure->AddRegisterClass(insn);
     seen_insn.insert(insn->result_id());
   }
-  for (ir::Instruction* insn : loop_reg_pressure->live_in_) {
+  for (opt::Instruction* insn : loop_reg_pressure->live_in_) {
     if (!seen_insn.count(insn->result_id())) {
       continue;
     }
@@ -309,14 +309,14 @@
   loop_reg_pressure->used_registers_ = 0;
 
   for (uint32_t bb_id : loop.GetBlocks()) {
-    ir::BasicBlock* bb = context_->cfg()->block(bb_id);
+    opt::BasicBlock* bb = context_->cfg()->block(bb_id);
 
     const RegionRegisterLiveness* live_inout = Get(bb_id);
     assert(live_inout != nullptr && "Basic block not processed");
     loop_reg_pressure->used_registers_ = std::max(
         loop_reg_pressure->used_registers_, live_inout->used_registers_);
 
-    for (ir::Instruction& insn : *bb) {
+    for (opt::Instruction& insn : *bb) {
       if (insn.opcode() == SpvOpPhi || !CreatesRegisterUsage(&insn) ||
           seen_insn.count(insn.result_id())) {
         continue;
@@ -327,7 +327,7 @@
 }
 
 void RegisterLiveness::SimulateFusion(
-    const ir::Loop& l1, const ir::Loop& l2,
+    const opt::Loop& l1, const opt::Loop& l2,
     RegionRegisterLiveness* sim_result) const {
   sim_result->Clear();
 
@@ -354,11 +354,11 @@
 
   // Compute the register usage information.
   std::unordered_set<uint32_t> seen_insn;
-  for (ir::Instruction* insn : sim_result->live_out_) {
+  for (opt::Instruction* insn : sim_result->live_out_) {
     sim_result->AddRegisterClass(insn);
     seen_insn.insert(insn->result_id());
   }
-  for (ir::Instruction* insn : sim_result->live_in_) {
+  for (opt::Instruction* insn : sim_result->live_in_) {
     if (!seen_insn.count(insn->result_id())) {
       continue;
     }
@@ -374,17 +374,17 @@
   // l2 live-in header blocks) into the the live in/out of each basic block of
   // l1 to get the peak register usage. We then repeat the operation to for l2
   // basic blocks but in this case we inject the live-out of the latch of l1.
-  auto live_loop = ir::MakeFilterIteratorRange(
+  auto live_loop = opt::MakeFilterIteratorRange(
       sim_result->live_in_.begin(), sim_result->live_in_.end(),
-      [&l1, &l2](ir::Instruction* insn) {
-        ir::BasicBlock* bb = insn->context()->get_instr_block(insn);
+      [&l1, &l2](opt::Instruction* insn) {
+        opt::BasicBlock* bb = insn->context()->get_instr_block(insn);
         return insn->HasResultId() &&
                !(insn->opcode() == SpvOpPhi &&
                  (bb == l1.GetHeaderBlock() || bb == l2.GetHeaderBlock()));
       });
 
   for (uint32_t bb_id : l1.GetBlocks()) {
-    ir::BasicBlock* bb = context_->cfg()->block(bb_id);
+    opt::BasicBlock* bb = context_->cfg()->block(bb_id);
 
     const RegionRegisterLiveness* live_inout_info = Get(bb_id);
     assert(live_inout_info != nullptr && "Basic block not processed");
@@ -395,7 +395,7 @@
                  live_inout_info->used_registers_ + live_out.size() -
                      live_inout_info->live_out_.size());
 
-    for (ir::Instruction& insn : *bb) {
+    for (opt::Instruction& insn : *bb) {
       if (insn.opcode() == SpvOpPhi || !CreatesRegisterUsage(&insn) ||
           seen_insn.count(insn.result_id())) {
         continue;
@@ -412,10 +412,10 @@
   l1_latch_live_out.insert(live_loop.begin(), live_loop.end());
 
   auto live_loop_l2 =
-      ir::make_range(l1_latch_live_out.begin(), l1_latch_live_out.end());
+      opt::make_range(l1_latch_live_out.begin(), l1_latch_live_out.end());
 
   for (uint32_t bb_id : l2.GetBlocks()) {
-    ir::BasicBlock* bb = context_->cfg()->block(bb_id);
+    opt::BasicBlock* bb = context_->cfg()->block(bb_id);
 
     const RegionRegisterLiveness* live_inout_info = Get(bb_id);
     assert(live_inout_info != nullptr && "Basic block not processed");
@@ -426,7 +426,7 @@
                  live_inout_info->used_registers_ + live_out.size() -
                      live_inout_info->live_out_.size());
 
-    for (ir::Instruction& insn : *bb) {
+    for (opt::Instruction& insn : *bb) {
       if (insn.opcode() == SpvOpPhi || !CreatesRegisterUsage(&insn) ||
           seen_insn.count(insn.result_id())) {
         continue;
@@ -437,9 +437,9 @@
 }
 
 void RegisterLiveness::SimulateFission(
-    const ir::Loop& loop,
-    const std::unordered_set<ir::Instruction*>& moved_inst,
-    const std::unordered_set<ir::Instruction*>& copied_inst,
+    const opt::Loop& loop,
+    const std::unordered_set<opt::Instruction*>& moved_inst,
+    const std::unordered_set<opt::Instruction*>& copied_inst,
     RegionRegisterLiveness* l1_sim_result,
     RegionRegisterLiveness* l2_sim_result) const {
   l1_sim_result->Clear();
@@ -448,25 +448,25 @@
   // Filter predicates: consider instructions that only belong to the first and
   // second loop.
   auto belong_to_loop1 = [&moved_inst, &copied_inst,
-                          &loop](ir::Instruction* insn) {
+                          &loop](opt::Instruction* insn) {
     return moved_inst.count(insn) || copied_inst.count(insn) ||
            !loop.IsInsideLoop(insn);
   };
-  auto belong_to_loop2 = [&moved_inst](ir::Instruction* insn) {
+  auto belong_to_loop2 = [&moved_inst](opt::Instruction* insn) {
     return !moved_inst.count(insn);
   };
 
   const RegionRegisterLiveness* header_live_inout = Get(loop.GetHeaderBlock());
   // l1 live-in
   {
-    auto live_loop = ir::MakeFilterIteratorRange(
+    auto live_loop = opt::MakeFilterIteratorRange(
         header_live_inout->live_in_.begin(), header_live_inout->live_in_.end(),
         belong_to_loop1);
     l1_sim_result->live_in_.insert(live_loop.begin(), live_loop.end());
   }
   // l2 live-in
   {
-    auto live_loop = ir::MakeFilterIteratorRange(
+    auto live_loop = opt::MakeFilterIteratorRange(
         header_live_inout->live_in_.begin(), header_live_inout->live_in_.end(),
         belong_to_loop2);
     l2_sim_result->live_in_.insert(live_loop.begin(), live_loop.end());
@@ -483,25 +483,25 @@
   }
   // l1 live-out.
   {
-    auto live_out = ir::MakeFilterIteratorRange(
+    auto live_out = opt::MakeFilterIteratorRange(
         l2_sim_result->live_out_.begin(), l2_sim_result->live_out_.end(),
         belong_to_loop1);
     l1_sim_result->live_out_.insert(live_out.begin(), live_out.end());
   }
   {
-    auto live_out = ir::MakeFilterIteratorRange(l2_sim_result->live_in_.begin(),
-                                                l2_sim_result->live_in_.end(),
-                                                belong_to_loop1);
+    auto live_out = opt::MakeFilterIteratorRange(
+        l2_sim_result->live_in_.begin(), l2_sim_result->live_in_.end(),
+        belong_to_loop1);
     l1_sim_result->live_out_.insert(live_out.begin(), live_out.end());
   }
   // Lives out of l1 are live out of l2 so are live in of l2 as well.
   l2_sim_result->live_in_.insert(l1_sim_result->live_out_.begin(),
                                  l1_sim_result->live_out_.end());
 
-  for (ir::Instruction* insn : l1_sim_result->live_in_) {
+  for (opt::Instruction* insn : l1_sim_result->live_in_) {
     l1_sim_result->AddRegisterClass(insn);
   }
-  for (ir::Instruction* insn : l2_sim_result->live_in_) {
+  for (opt::Instruction* insn : l2_sim_result->live_in_) {
     l2_sim_result->AddRegisterClass(insn);
   }
 
@@ -509,14 +509,14 @@
   l2_sim_result->used_registers_ = 0;
 
   for (uint32_t bb_id : loop.GetBlocks()) {
-    ir::BasicBlock* bb = context_->cfg()->block(bb_id);
+    opt::BasicBlock* bb = context_->cfg()->block(bb_id);
 
     const RegisterLiveness::RegionRegisterLiveness* live_inout = Get(bb_id);
     assert(live_inout != nullptr && "Basic block not processed");
-    auto l1_block_live_out = ir::MakeFilterIteratorRange(
+    auto l1_block_live_out = opt::MakeFilterIteratorRange(
         live_inout->live_out_.begin(), live_inout->live_out_.end(),
         belong_to_loop1);
-    auto l2_block_live_out = ir::MakeFilterIteratorRange(
+    auto l2_block_live_out = opt::MakeFilterIteratorRange(
         live_inout->live_out_.begin(), live_inout->live_out_.end(),
         belong_to_loop2);
 
@@ -526,7 +526,7 @@
         std::distance(l2_block_live_out.begin(), l2_block_live_out.end());
 
     std::unordered_set<uint32_t> die_in_block;
-    for (ir::Instruction& insn : ir::make_range(bb->rbegin(), bb->rend())) {
+    for (opt::Instruction& insn : opt::make_range(bb->rbegin(), bb->rend())) {
       if (insn.opcode() == SpvOpPhi) {
         break;
       }
@@ -536,7 +536,7 @@
       insn.ForEachInId([live_inout, &die_in_block, &l1_reg_count, &l2_reg_count,
                         does_belong_to_loop1, does_belong_to_loop2,
                         this](uint32_t* id) {
-        ir::Instruction* op_insn = context_->get_def_use_mgr()->GetDef(*id);
+        opt::Instruction* op_insn = context_->get_def_use_mgr()->GetDef(*id);
         if (!CreatesRegisterUsage(op_insn) ||
             live_inout->live_out_.count(op_insn)) {
           // already taken into account.
diff --git a/source/opt/register_pressure.h b/source/opt/register_pressure.h
index d827a20..77383e3 100644
--- a/source/opt/register_pressure.h
+++ b/source/opt/register_pressure.h
@@ -24,13 +24,11 @@
 #include "types.h"
 
 namespace spvtools {
-namespace ir {
+namespace opt {
+
 class IRContext;
 class Loop;
 class LoopDescriptor;
-}  // namespace ir
-
-namespace opt {
 
 // Handles the register pressure of a function for different regions (function,
 // loop, basic block). It also contains some utilities to foresee the register
@@ -49,7 +47,7 @@
   };
 
   struct RegionRegisterLiveness {
-    using LiveSet = std::unordered_set<ir::Instruction*>;
+    using LiveSet = std::unordered_set<opt::Instruction*>;
     using RegClassSetTy = std::vector<std::pair<RegisterClass, size_t>>;
 
     // SSA register live when entering the basic block.
@@ -83,17 +81,17 @@
       }
     }
 
-    void AddRegisterClass(ir::Instruction* insn);
+    void AddRegisterClass(opt::Instruction* insn);
   };
 
-  RegisterLiveness(ir::IRContext* context, ir::Function* f)
+  RegisterLiveness(opt::IRContext* context, opt::Function* f)
       : context_(context) {
     Analyze(f);
   }
 
   // Returns liveness and register information for the basic block |bb|. If no
   // entry exist for the basic block, the function returns null.
-  const RegionRegisterLiveness* Get(const ir::BasicBlock* bb) const {
+  const RegionRegisterLiveness* Get(const opt::BasicBlock* bb) const {
     return Get(bb->id());
   }
 
@@ -107,11 +105,11 @@
     return nullptr;
   }
 
-  ir::IRContext* GetContext() const { return context_; }
+  opt::IRContext* GetContext() const { return context_; }
 
   // Returns liveness and register information for the basic block |bb|. If no
   // entry exist for the basic block, the function returns null.
-  RegionRegisterLiveness* Get(const ir::BasicBlock* bb) {
+  RegionRegisterLiveness* Get(const opt::BasicBlock* bb) {
     return Get(bb->id());
   }
 
@@ -135,12 +133,12 @@
   // |reg_pressure|. The live-in set corresponds to the live-in set of the
   // header block, the live-out set of the loop corresponds to the union of the
   // live-in sets of each exit basic block.
-  void ComputeLoopRegisterPressure(const ir::Loop& loop,
+  void ComputeLoopRegisterPressure(const opt::Loop& loop,
                                    RegionRegisterLiveness* reg_pressure) const;
 
   // Estimate the register pressure for the |l1| and |l2| as if they were making
   // one unique loop. The result is stored into |simulation_result|.
-  void SimulateFusion(const ir::Loop& l1, const ir::Loop& l2,
+  void SimulateFusion(const opt::Loop& l1, const opt::Loop& l2,
                       RegionRegisterLiveness* simulation_result) const;
 
   // Estimate the register pressure of |loop| after it has been fissioned
@@ -152,9 +150,9 @@
   // moved instructions. The set |loop2_sim_result| store the simulation result
   // of the loop with the removed instructions.
   void SimulateFission(
-      const ir::Loop& loop,
-      const std::unordered_set<ir::Instruction*>& moved_instructions,
-      const std::unordered_set<ir::Instruction*>& copied_instructions,
+      const opt::Loop& loop,
+      const std::unordered_set<opt::Instruction*>& moved_instructions,
+      const std::unordered_set<opt::Instruction*>& copied_instructions,
       RegionRegisterLiveness* loop1_sim_result,
       RegionRegisterLiveness* loop2_sim_result) const;
 
@@ -162,10 +160,10 @@
   using RegionRegisterLivenessMap =
       std::unordered_map<uint32_t, RegionRegisterLiveness>;
 
-  ir::IRContext* context_;
+  opt::IRContext* context_;
   RegionRegisterLivenessMap block_pressure_;
 
-  void Analyze(ir::Function* f);
+  void Analyze(opt::Function* f);
 };
 
 // Handles the register pressure of a function for different regions (function,
@@ -173,15 +171,15 @@
 // pressure following code transformations.
 class LivenessAnalysis {
   using LivenessAnalysisMap =
-      std::unordered_map<const ir::Function*, RegisterLiveness>;
+      std::unordered_map<const opt::Function*, RegisterLiveness>;
 
  public:
-  LivenessAnalysis(ir::IRContext* context) : context_(context) {}
+  LivenessAnalysis(opt::IRContext* context) : context_(context) {}
 
   // Computes the liveness analysis for the function |f| and cache the result.
   // If the analysis was performed for this function, then the cached analysis
   // is returned.
-  const RegisterLiveness* Get(ir::Function* f) {
+  const RegisterLiveness* Get(opt::Function* f) {
     LivenessAnalysisMap::iterator it = analysis_cache_.find(f);
     if (it != analysis_cache_.end()) {
       return &it->second;
@@ -191,7 +189,7 @@
   }
 
  private:
-  ir::IRContext* context_;
+  opt::IRContext* context_;
   LivenessAnalysisMap analysis_cache_;
 };
 
diff --git a/source/opt/remove_duplicates_pass.cpp b/source/opt/remove_duplicates_pass.cpp
index 0a54d76..a4cb49e 100644
--- a/source/opt/remove_duplicates_pass.cpp
+++ b/source/opt/remove_duplicates_pass.cpp
@@ -30,13 +30,13 @@
 namespace spvtools {
 namespace opt {
 
-using ir::Instruction;
-using ir::Module;
-using ir::Operand;
+using opt::Instruction;
+using opt::Module;
+using opt::Operand;
 using opt::analysis::DecorationManager;
 using opt::analysis::DefUseManager;
 
-Pass::Status RemoveDuplicatesPass::Process(ir::IRContext* ir_context) {
+Pass::Status RemoveDuplicatesPass::Process(opt::IRContext* ir_context) {
   bool modified = RemoveDuplicateCapabilities(ir_context);
   modified |= RemoveDuplicatesExtInstImports(ir_context);
   modified |= RemoveDuplicateTypes(ir_context);
@@ -46,7 +46,7 @@
 }
 
 bool RemoveDuplicatesPass::RemoveDuplicateCapabilities(
-    ir::IRContext* ir_context) const {
+    opt::IRContext* ir_context) const {
   bool modified = false;
 
   if (ir_context->capabilities().empty()) {
@@ -71,7 +71,7 @@
 }
 
 bool RemoveDuplicatesPass::RemoveDuplicatesExtInstImports(
-    ir::IRContext* ir_context) const {
+    opt::IRContext* ir_context) const {
   bool modified = false;
 
   if (ir_context->ext_inst_imports().empty()) {
@@ -98,7 +98,7 @@
 }
 
 bool RemoveDuplicatesPass::RemoveDuplicateTypes(
-    ir::IRContext* ir_context) const {
+    opt::IRContext* ir_context) const {
   bool modified = false;
 
   if (ir_context->types_values().empty()) {
@@ -154,7 +154,7 @@
 //     OpGroupDecorate %2 %4
 // group %2 could be removed.
 bool RemoveDuplicatesPass::RemoveDuplicateDecorations(
-    ir::IRContext* ir_context) const {
+    opt::IRContext* ir_context) const {
   bool modified = false;
 
   std::vector<const Instruction*> visited_decorations;
@@ -189,9 +189,9 @@
 
 bool RemoveDuplicatesPass::AreTypesEqual(const Instruction& inst1,
                                          const Instruction& inst2,
-                                         ir::IRContext* context) {
+                                         opt::IRContext* context) {
   if (inst1.opcode() != inst2.opcode()) return false;
-  if (!ir::IsTypeInst(inst1.opcode())) return false;
+  if (!opt::IsTypeInst(inst1.opcode())) return false;
 
   const analysis::Type* type1 =
       context->get_type_mgr()->GetType(inst1.result_id());
diff --git a/source/opt/remove_duplicates_pass.h b/source/opt/remove_duplicates_pass.h
index d766f67..d64ea5c 100644
--- a/source/opt/remove_duplicates_pass.h
+++ b/source/opt/remove_duplicates_pass.h
@@ -27,38 +27,38 @@
 namespace opt {
 
 using IdDecorationsList =
-    std::unordered_map<uint32_t, std::vector<ir::Instruction*>>;
+    std::unordered_map<uint32_t, std::vector<opt::Instruction*>>;
 
 // See optimizer.hpp for documentation.
 class RemoveDuplicatesPass : public Pass {
  public:
   const char* name() const override { return "remove-duplicates"; }
-  Status Process(ir::IRContext*) override;
+  Status Process(opt::IRContext*) override;
   // TODO(pierremoreau): Move this function somewhere else (e.g. pass.h or
   // within the type manager)
   // Returns whether two types are equal, and have the same decorations.
-  static bool AreTypesEqual(const ir::Instruction& inst1,
-                            const ir::Instruction& inst2,
-                            ir::IRContext* context);
+  static bool AreTypesEqual(const opt::Instruction& inst1,
+                            const opt::Instruction& inst2,
+                            opt::IRContext* context);
 
  private:
   // Remove duplicate capabilities from the module attached to |ir_context|.
   //
   // Returns true if the module was modified, false otherwise.
-  bool RemoveDuplicateCapabilities(ir::IRContext* ir_context) const;
+  bool RemoveDuplicateCapabilities(opt::IRContext* ir_context) const;
   // Remove duplicate extended instruction imports from the module attached to
   // |ir_context|.
   //
   // Returns true if the module was modified, false otherwise.
-  bool RemoveDuplicatesExtInstImports(ir::IRContext* ir_context) const;
+  bool RemoveDuplicatesExtInstImports(opt::IRContext* ir_context) const;
   // Remove duplicate types from the module attached to |ir_context|.
   //
   // Returns true if the module was modified, false otherwise.
-  bool RemoveDuplicateTypes(ir::IRContext* ir_context) const;
+  bool RemoveDuplicateTypes(opt::IRContext* ir_context) const;
   // Remove duplicate decorations from the module attached to |ir_context|.
   //
   // Returns true if the module was modified, false otherwise.
-  bool RemoveDuplicateDecorations(ir::IRContext* ir_context) const;
+  bool RemoveDuplicateDecorations(opt::IRContext* ir_context) const;
 };
 
 }  // namespace opt
diff --git a/source/opt/replace_invalid_opc.cpp b/source/opt/replace_invalid_opc.cpp
index a025c3c..88a875c 100644
--- a/source/opt/replace_invalid_opc.cpp
+++ b/source/opt/replace_invalid_opc.cpp
@@ -19,7 +19,7 @@
 namespace spvtools {
 namespace opt {
 
-Pass::Status ReplaceInvalidOpcodePass::Process(ir::IRContext* c) {
+Pass::Status ReplaceInvalidOpcodePass::Process(opt::IRContext* c) {
   InitializeProcessing(c);
   bool modified = false;
 
@@ -38,7 +38,7 @@
     return Status::SuccessWithoutChange;
   }
 
-  for (ir::Function& func : *get_module()) {
+  for (opt::Function& func : *get_module()) {
     modified |= RewriteFunction(&func, execution_model);
   }
   return (modified ? Status::SuccessWithChange : Status::SuccessWithoutChange);
@@ -47,7 +47,7 @@
 SpvExecutionModel ReplaceInvalidOpcodePass::GetExecutionModel() {
   SpvExecutionModel result = SpvExecutionModelMax;
   bool first = true;
-  for (ir::Instruction& entry_point : get_module()->entry_points()) {
+  for (opt::Instruction& entry_point : get_module()->entry_points()) {
     if (first) {
       result =
           static_cast<SpvExecutionModel>(entry_point.GetSingleWordInOperand(0));
@@ -64,12 +64,12 @@
   return result;
 }
 
-bool ReplaceInvalidOpcodePass::RewriteFunction(ir::Function* function,
+bool ReplaceInvalidOpcodePass::RewriteFunction(opt::Function* function,
                                                SpvExecutionModel model) {
   bool modified = false;
-  ir::Instruction* last_line_dbg_inst = nullptr;
+  opt::Instruction* last_line_dbg_inst = nullptr;
   function->ForEachInst(
-      [model, &modified, &last_line_dbg_inst, this](ir::Instruction* inst) {
+      [model, &modified, &last_line_dbg_inst, this](opt::Instruction* inst) {
         // Track the debug information so we can have a meaningful message.
         if (inst->opcode() == SpvOpLabel || inst->opcode() == SpvOpNoLine) {
           last_line_dbg_inst = nullptr;
@@ -100,7 +100,7 @@
             ReplaceInstruction(inst, nullptr, 0, 0);
           } else {
             // Get the name of the source file.
-            ir::Instruction* file_name = context()->get_def_use_mgr()->GetDef(
+            opt::Instruction* file_name = context()->get_def_use_mgr()->GetDef(
                 last_line_dbg_inst->GetSingleWordInOperand(0));
             const char* source = reinterpret_cast<const char*>(
                 &file_name->GetInOperand(0).words[0]);
@@ -120,7 +120,7 @@
 }
 
 bool ReplaceInvalidOpcodePass::IsFragmentShaderOnlyInstruction(
-    ir::Instruction* inst) {
+    opt::Instruction* inst) {
   switch (inst->opcode()) {
     case SpvOpDPdx:
     case SpvOpDPdy:
@@ -147,7 +147,7 @@
   }
 }
 
-void ReplaceInvalidOpcodePass::ReplaceInstruction(ir::Instruction* inst,
+void ReplaceInvalidOpcodePass::ReplaceInstruction(opt::Instruction* inst,
                                                   const char* source,
                                                   uint32_t line_number,
                                                   uint32_t column_number) {
@@ -172,7 +172,7 @@
   analysis::ConstantManager* const_mgr = context()->get_constant_mgr();
   analysis::TypeManager* type_mgr = context()->get_type_mgr();
 
-  ir::Instruction* type = context()->get_def_use_mgr()->GetDef(type_id);
+  opt::Instruction* type = context()->get_def_use_mgr()->GetDef(type_id);
   if (type->opcode() == SpvOpTypeVector) {
     uint32_t component_const =
         GetSpecialConstant(type->GetSingleWordInOperand(0));
diff --git a/source/opt/replace_invalid_opc.h b/source/opt/replace_invalid_opc.h
index e661fce..42e278e 100644
--- a/source/opt/replace_invalid_opc.h
+++ b/source/opt/replace_invalid_opc.h
@@ -27,7 +27,7 @@
 class ReplaceInvalidOpcodePass : public Pass {
  public:
   const char* name() const override { return "replace-invalid-opcodes"; }
-  Status Process(ir::IRContext*) override;
+  Status Process(opt::IRContext*) override;
 
  private:
   // Returns the execution model that is used by every entry point in the
@@ -38,16 +38,16 @@
   // Replaces all instructions in |function| that are invalid with execution
   // model |mode|, but valid for another shader model, with a special constant
   // value.  See |GetSpecialConstant|.
-  bool RewriteFunction(ir::Function* function, SpvExecutionModel mode);
+  bool RewriteFunction(opt::Function* function, SpvExecutionModel mode);
 
   // Returns true if |inst| is valid for fragment shaders only.
-  bool IsFragmentShaderOnlyInstruction(ir::Instruction* inst);
+  bool IsFragmentShaderOnlyInstruction(opt::Instruction* inst);
 
   // Replaces all uses of the result of |inst|, if there is one, with the id of
   // a special constant.  Then |inst| is killed.  |inst| cannot be a block
   // terminator because the basic block will then become invalid.  |inst| is no
   // longer valid after calling this function.
-  void ReplaceInstruction(ir::Instruction* inst, const char* source,
+  void ReplaceInstruction(opt::Instruction* inst, const char* source,
                           uint32_t line_number, uint32_t column_number);
 
   // Returns the id of a constant with type |type_id|.  The type must be an
diff --git a/source/opt/scalar_analysis.cpp b/source/opt/scalar_analysis.cpp
index a67afb8..785653e 100644
--- a/source/opt/scalar_analysis.cpp
+++ b/source/opt/scalar_analysis.cpp
@@ -48,7 +48,7 @@
 
 uint32_t SENode::NumberOfNodes = 0;
 
-ScalarEvolutionAnalysis::ScalarEvolutionAnalysis(ir::IRContext* context)
+ScalarEvolutionAnalysis::ScalarEvolutionAnalysis(opt::IRContext* context)
     : context_(context), pretend_equal_{} {
   // Create and cached the CantComputeNode.
   cached_cant_compute_ =
@@ -73,14 +73,14 @@
 }
 
 SENode* ScalarEvolutionAnalysis::CreateRecurrentExpression(
-    const ir::Loop* loop, SENode* offset, SENode* coefficient) {
+    const opt::Loop* loop, SENode* offset, SENode* coefficient) {
   assert(loop && "Recurrent add expressions must have a valid loop.");
 
   // If operands are can't compute then the whole graph is can't compute.
   if (offset->IsCantCompute() || coefficient->IsCantCompute())
     return CreateCantComputeNode();
 
-  const ir::Loop* loop_to_use = nullptr;
+  const opt::Loop* loop_to_use = nullptr;
   if (pretend_equal_[loop]) {
     loop_to_use = pretend_equal_[loop];
   } else {
@@ -96,7 +96,7 @@
 }
 
 SENode* ScalarEvolutionAnalysis::AnalyzeMultiplyOp(
-    const ir::Instruction* multiply) {
+    const opt::Instruction* multiply) {
   assert(multiply->opcode() == SpvOp::SpvOpIMul &&
          "Multiply node did not come from a multiply instruction");
   opt::analysis::DefUseManager* def_use = context_->get_def_use_mgr();
@@ -163,7 +163,7 @@
 }
 
 SENode* ScalarEvolutionAnalysis::AnalyzeInstruction(
-    const ir::Instruction* inst) {
+    const opt::Instruction* inst) {
   auto itr = recurrent_node_map_.find(inst);
   if (itr != recurrent_node_map_.end()) return itr->second;
 
@@ -196,7 +196,7 @@
   return output;
 }
 
-SENode* ScalarEvolutionAnalysis::AnalyzeConstant(const ir::Instruction* inst) {
+SENode* ScalarEvolutionAnalysis::AnalyzeConstant(const opt::Instruction* inst) {
   if (inst->opcode() == SpvOp::SpvOpConstantNull) return CreateConstant(0);
 
   assert(inst->opcode() == SpvOp::SpvOpConstant);
@@ -226,7 +226,7 @@
 
 // Handles both addition and subtraction. If the |sub| flag is set then the
 // addition will be op1+(-op2) otherwise op1+op2.
-SENode* ScalarEvolutionAnalysis::AnalyzeAddOp(const ir::Instruction* inst) {
+SENode* ScalarEvolutionAnalysis::AnalyzeAddOp(const opt::Instruction* inst) {
   assert((inst->opcode() == SpvOp::SpvOpIAdd ||
           inst->opcode() == SpvOp::SpvOpISub) &&
          "Add node must be created from a OpIAdd or OpISub instruction");
@@ -248,7 +248,7 @@
 }
 
 SENode* ScalarEvolutionAnalysis::AnalyzePhiInstruction(
-    const ir::Instruction* phi) {
+    const opt::Instruction* phi) {
   // The phi should only have two incoming value pairs.
   if (phi->NumInOperands() != 4) {
     return CreateCantComputeNode();
@@ -257,20 +257,20 @@
   opt::analysis::DefUseManager* def_use = context_->get_def_use_mgr();
 
   // Get the basic block this instruction belongs to.
-  ir::BasicBlock* basic_block =
-      context_->get_instr_block(const_cast<ir::Instruction*>(phi));
+  opt::BasicBlock* basic_block =
+      context_->get_instr_block(const_cast<opt::Instruction*>(phi));
 
   // And then the function that the basic blocks belongs to.
-  ir::Function* function = basic_block->GetParent();
+  opt::Function* function = basic_block->GetParent();
 
   // Use the function to get the loop descriptor.
-  ir::LoopDescriptor* loop_descriptor = context_->GetLoopDescriptor(function);
+  opt::LoopDescriptor* loop_descriptor = context_->GetLoopDescriptor(function);
 
   // We only handle phis in loops at the moment.
   if (!loop_descriptor) return CreateCantComputeNode();
 
   // Get the innermost loop which this block belongs to.
-  ir::Loop* loop = (*loop_descriptor)[basic_block->id()];
+  opt::Loop* loop = (*loop_descriptor)[basic_block->id()];
 
   // If the loop doesn't exist or doesn't have a preheader or latch block, exit
   // out.
@@ -278,7 +278,7 @@
       loop->GetHeaderBlock() != basic_block)
     return recurrent_node_map_[phi] = CreateCantComputeNode();
 
-  const ir::Loop* loop_to_use = nullptr;
+  const opt::Loop* loop_to_use = nullptr;
   if (pretend_equal_[loop]) {
     loop_to_use = pretend_equal_[loop];
   } else {
@@ -298,7 +298,7 @@
     uint32_t value_id = phi->GetSingleWordInOperand(i);
     uint32_t incoming_label_id = phi->GetSingleWordInOperand(i + 1);
 
-    ir::Instruction* value_inst = def_use->GetDef(value_id);
+    opt::Instruction* value_inst = def_use->GetDef(value_id);
     SENode* value_node = AnalyzeInstruction(value_inst);
 
     // If any operand is CantCompute then the whole graph is CantCompute.
@@ -352,7 +352,7 @@
 }
 
 SENode* ScalarEvolutionAnalysis::CreateValueUnknownNode(
-    const ir::Instruction* inst) {
+    const opt::Instruction* inst) {
   std::unique_ptr<SEValueUnknown> load_node{
       new SEValueUnknown(this, inst->result_id())};
   return GetCachedOrAdd(std::move(load_node));
@@ -375,11 +375,11 @@
   return raw_ptr_to_node;
 }
 
-bool ScalarEvolutionAnalysis::IsLoopInvariant(const ir::Loop* loop,
+bool ScalarEvolutionAnalysis::IsLoopInvariant(const opt::Loop* loop,
                                               const SENode* node) const {
   for (auto itr = node->graph_cbegin(); itr != node->graph_cend(); ++itr) {
     if (const SERecurrentNode* rec = itr->AsSERecurrentNode()) {
-      const ir::BasicBlock* header = rec->GetLoop()->GetHeaderBlock();
+      const opt::BasicBlock* header = rec->GetLoop()->GetHeaderBlock();
 
       // If the loop which the recurrent expression belongs to is either |loop
       // or a nested loop inside |loop| then we assume it is variant.
@@ -397,7 +397,7 @@
 }
 
 SENode* ScalarEvolutionAnalysis::GetCoefficientFromRecurrentTerm(
-    SENode* node, const ir::Loop* loop) {
+    SENode* node, const opt::Loop* loop) {
   // Traverse the DAG to find the recurrent expression belonging to |loop|.
   for (auto itr = node->graph_begin(); itr != node->graph_end(); ++itr) {
     SERecurrentNode* rec = itr->AsSERecurrentNode();
@@ -434,7 +434,7 @@
 // Rebuild the |node| eliminating, if it exists, the recurrent term which
 // belongs to the |loop|.
 SENode* ScalarEvolutionAnalysis::BuildGraphWithoutRecurrentTerm(
-    SENode* node, const ir::Loop* loop) {
+    SENode* node, const opt::Loop* loop) {
   // If the node is already a recurrent expression belonging to loop then just
   // return the offset.
   SERecurrentNode* recurrent = node->AsSERecurrentNode();
@@ -468,7 +468,7 @@
 // Return the recurrent term belonging to |loop| if it appears in the graph
 // starting at |node| or null if it doesn't.
 SERecurrentNode* ScalarEvolutionAnalysis::GetRecurrentTerm(
-    SENode* node, const ir::Loop* loop) {
+    SENode* node, const opt::Loop* loop) {
   for (auto itr = node->graph_begin(); itr != node->graph_end(); ++itr) {
     SERecurrentNode* rec = itr->AsSERecurrentNode();
     if (rec && rec->GetLoop() == loop) {
@@ -652,7 +652,7 @@
 namespace {
 class IsGreaterThanZero {
  public:
-  explicit IsGreaterThanZero(ir::IRContext* context) : context_(context) {}
+  explicit IsGreaterThanZero(opt::IRContext* context) : context_(context) {}
 
   // Determine if the value of |node| is always strictly greater than zero if
   // |or_equal_zero| is false or greater or equal to zero if |or_equal_zero| is
@@ -844,7 +844,7 @@
 
   // Returns the signedness of an unknown |node| based on its type.
   Signedness Visit(const SEValueUnknown* node) {
-    ir::Instruction* insn =
+    opt::Instruction* insn =
         context_->get_def_use_mgr()->GetDef(node->ResultId());
     analysis::Type* type = context_->get_type_mgr()->GetType(insn->type_id());
     assert(type && "Can't retrieve a type for the instruction");
@@ -904,7 +904,8 @@
       const SENode* node,
       std::function<Signedness(Signedness, Signedness)> reduce) {
     Signedness result = Visit(*node->begin());
-    for (const SENode* operand : ir::make_range(++node->begin(), node->end())) {
+    for (const SENode* operand :
+         opt::make_range(++node->begin(), node->end())) {
       if (result == Signedness::kPositiveOrNegative) {
         return Signedness::kPositiveOrNegative;
       }
@@ -913,7 +914,7 @@
     return result;
   }
 
-  ir::IRContext* context_;
+  opt::IRContext* context_;
 };
 }  // namespace
 
diff --git a/source/opt/scalar_analysis.h b/source/opt/scalar_analysis.h
index 3541433..901c387 100644
--- a/source/opt/scalar_analysis.h
+++ b/source/opt/scalar_analysis.h
@@ -27,12 +27,10 @@
 #include "opt/scalar_analysis_nodes.h"
 
 namespace spvtools {
-namespace ir {
+namespace opt {
+
 class IRContext;
 class Loop;
-}  // namespace ir
-
-namespace opt {
 
 // Manager for the Scalar Evolution analysis. Creates and maintains a DAG of
 // scalar operations generated from analysing the use def graph from incoming
@@ -42,7 +40,7 @@
 // usable form with SimplifyExpression.
 class ScalarEvolutionAnalysis {
  public:
-  explicit ScalarEvolutionAnalysis(ir::IRContext* context);
+  explicit ScalarEvolutionAnalysis(opt::IRContext* context);
 
   // Create a unary negative node on |operand|.
   SENode* CreateNegation(SENode* operand);
@@ -63,18 +61,18 @@
   SENode* CreateConstant(int64_t integer);
 
   // Create a value unknown node, such as a load.
-  SENode* CreateValueUnknownNode(const ir::Instruction* inst);
+  SENode* CreateValueUnknownNode(const opt::Instruction* inst);
 
   // Create a CantComputeNode. Used to exit out of analysis.
   SENode* CreateCantComputeNode();
 
   // Create a new recurrent node with |offset| and |coefficient|, with respect
   // to |loop|.
-  SENode* CreateRecurrentExpression(const ir::Loop* loop, SENode* offset,
+  SENode* CreateRecurrentExpression(const opt::Loop* loop, SENode* offset,
                                     SENode* coefficient);
 
   // Construct the DAG by traversing use def chain of |inst|.
-  SENode* AnalyzeInstruction(const ir::Instruction* inst);
+  SENode* AnalyzeInstruction(const opt::Instruction* inst);
 
   // Simplify the |node| by grouping like terms or if contains a recurrent
   // expression, rewrite the graph so the whole DAG (from |node| down) is in
@@ -93,7 +91,7 @@
   SENode* GetCachedOrAdd(std::unique_ptr<SENode> prospective_node);
 
   // Checks that the graph starting from |node| is invariant to the |loop|.
-  bool IsLoopInvariant(const ir::Loop* loop, const SENode* node) const;
+  bool IsLoopInvariant(const opt::Loop* loop, const SENode* node) const;
 
   // Sets |is_gt_zero| to true if |node| represent a value always strictly
   // greater than 0. The result of |is_gt_zero| is valid only if the function
@@ -108,15 +106,15 @@
   // |node| and return the coefficient of that recurrent term. Constant zero
   // will be returned if no recurrent could be found. |node| should be in
   // simplest form.
-  SENode* GetCoefficientFromRecurrentTerm(SENode* node, const ir::Loop* loop);
+  SENode* GetCoefficientFromRecurrentTerm(SENode* node, const opt::Loop* loop);
 
   // Return a rebuilt graph starting from |node| with the recurrent expression
   // belonging to |loop| being zeroed out. Returned node will be simplified.
-  SENode* BuildGraphWithoutRecurrentTerm(SENode* node, const ir::Loop* loop);
+  SENode* BuildGraphWithoutRecurrentTerm(SENode* node, const opt::Loop* loop);
 
   // Return the recurrent term belonging to |loop| if it appears in the graph
   // starting at |node| or null if it doesn't.
-  SERecurrentNode* GetRecurrentTerm(SENode* node, const ir::Loop* loop);
+  SERecurrentNode* GetRecurrentTerm(SENode* node, const opt::Loop* loop);
 
   SENode* UpdateChildNode(SENode* parent, SENode* child, SENode* new_child);
 
@@ -124,29 +122,29 @@
   // SERecurrentNode objects. This enables analysing dependencies that will be
   // created during loop fusion.
   void AddLoopsToPretendAreTheSame(
-      const std::pair<const ir::Loop*, const ir::Loop*>& loop_pair) {
+      const std::pair<const opt::Loop*, const opt::Loop*>& loop_pair) {
     pretend_equal_[std::get<1>(loop_pair)] = std::get<0>(loop_pair);
   }
 
  private:
-  SENode* AnalyzeConstant(const ir::Instruction* inst);
+  SENode* AnalyzeConstant(const opt::Instruction* inst);
 
   // Handles both addition and subtraction. If the |instruction| is OpISub
   // then the resulting node will be op1+(-op2) otherwise if it is OpIAdd then
   // the result will be op1+op2. |instruction| must be OpIAdd or OpISub.
-  SENode* AnalyzeAddOp(const ir::Instruction* instruction);
+  SENode* AnalyzeAddOp(const opt::Instruction* instruction);
 
-  SENode* AnalyzeMultiplyOp(const ir::Instruction* multiply);
+  SENode* AnalyzeMultiplyOp(const opt::Instruction* multiply);
 
-  SENode* AnalyzePhiInstruction(const ir::Instruction* phi);
+  SENode* AnalyzePhiInstruction(const opt::Instruction* phi);
 
-  ir::IRContext* context_;
+  opt::IRContext* context_;
 
   // A map of instructions to SENodes. This is used to track recurrent
   // expressions as they are added when analyzing instructions. Recurrent
   // expressions come from phi nodes which by nature can include recursion so we
   // check if nodes have already been built when analyzing instructions.
-  std::map<const ir::Instruction*, SENode*> recurrent_node_map_;
+  std::map<const opt::Instruction*, SENode*> recurrent_node_map_;
 
   // On creation we create and cache the CantCompute node so we not need to
   // perform a needless create step.
@@ -169,7 +167,7 @@
 
   // Loops that should be considered the same for performing analysis for loop
   // fusion.
-  std::map<const ir::Loop*, const ir::Loop*> pretend_equal_;
+  std::map<const opt::Loop*, const opt::Loop*> pretend_equal_;
 };
 
 // Wrapping class to manipulate SENode pointer using + - * / operators.
diff --git a/source/opt/scalar_analysis_nodes.h b/source/opt/scalar_analysis_nodes.h
index f9fdb6b..ee19c66 100644
--- a/source/opt/scalar_analysis_nodes.h
+++ b/source/opt/scalar_analysis_nodes.h
@@ -22,12 +22,9 @@
 #include "opt/tree_iterator.h"
 
 namespace spvtools {
-namespace ir {
-class Loop;
-}  // namespace ir
-
 namespace opt {
 
+class Loop;
 class ScalarEvolutionAnalysis;
 class SEConstantNode;
 class SERecurrentNode;
@@ -241,7 +238,7 @@
 class SERecurrentNode : public SENode {
  public:
   SERecurrentNode(opt::ScalarEvolutionAnalysis* parent_analysis,
-                  const ir::Loop* loop)
+                  const opt::Loop* loop)
       : SENode(parent_analysis), loop_(loop) {}
 
   SENodeType GetType() const final { return RecurrentAddExpr; }
@@ -263,7 +260,7 @@
   inline SENode* GetOffset() { return offset_; }
 
   // Return the loop which this recurrent expression is recurring within.
-  const ir::Loop* GetLoop() const { return loop_; }
+  const opt::Loop* GetLoop() const { return loop_; }
 
   SERecurrentNode* AsSERecurrentNode() override { return this; }
   const SERecurrentNode* AsSERecurrentNode() const override { return this; }
@@ -271,7 +268,7 @@
  private:
   SENode* coefficient_;
   SENode* offset_;
-  const ir::Loop* loop_;
+  const opt::Loop* loop_;
 };
 
 // A node representing an addition operation between child nodes.
diff --git a/source/opt/scalar_analysis_simplification.cpp b/source/opt/scalar_analysis_simplification.cpp
index 018896a..c1dbcc9 100644
--- a/source/opt/scalar_analysis_simplification.cpp
+++ b/source/opt/scalar_analysis_simplification.cpp
@@ -375,7 +375,7 @@
 
   // A mapping of loops to the list of recurrent expressions which are with
   // respect to those loops.
-  std::map<const ir::Loop*, std::vector<std::pair<SERecurrentNode*, bool>>>
+  std::map<const opt::Loop*, std::vector<std::pair<SERecurrentNode*, bool>>>
       loops_to_recurrent{};
 
   bool has_multiple_same_loop_recurrent_terms = false;
@@ -389,7 +389,7 @@
     }
 
     if (child->GetType() == SENode::RecurrentAddExpr) {
-      const ir::Loop* loop = child->AsSERecurrentNode()->GetLoop();
+      const opt::Loop* loop = child->AsSERecurrentNode()->GetLoop();
 
       SERecurrentNode* rec = child->AsSERecurrentNode();
       if (loops_to_recurrent.find(loop) == loops_to_recurrent.end()) {
@@ -408,7 +408,7 @@
   for (auto pair : loops_to_recurrent) {
     std::vector<std::pair<SERecurrentNode*, bool>>& recurrent_expressions =
         pair.second;
-    const ir::Loop* loop = pair.first;
+    const opt::Loop* loop = pair.first;
 
     std::unique_ptr<SENode> new_coefficient{new SEAddNode(&analysis_)};
     std::unique_ptr<SENode> new_offset{new SEAddNode(&analysis_)};
diff --git a/source/opt/scalar_replacement_pass.cpp b/source/opt/scalar_replacement_pass.cpp
index f894c7b..e73fc56 100644
--- a/source/opt/scalar_replacement_pass.cpp
+++ b/source/opt/scalar_replacement_pass.cpp
@@ -26,7 +26,7 @@
 namespace spvtools {
 namespace opt {
 
-Pass::Status ScalarReplacementPass::Process(ir::IRContext* c) {
+Pass::Status ScalarReplacementPass::Process(opt::IRContext* c) {
   InitializeProcessing(c);
 
   Status status = Status::SuccessWithoutChange;
@@ -41,15 +41,15 @@
   return status;
 }
 
-Pass::Status ScalarReplacementPass::ProcessFunction(ir::Function* function) {
-  std::queue<ir::Instruction*> worklist;
-  ir::BasicBlock& entry = *function->begin();
+Pass::Status ScalarReplacementPass::ProcessFunction(opt::Function* function) {
+  std::queue<opt::Instruction*> worklist;
+  opt::BasicBlock& entry = *function->begin();
   for (auto iter = entry.begin(); iter != entry.end(); ++iter) {
     // Function storage class OpVariables must appear as the first instructions
     // of the entry block.
     if (iter->opcode() != SpvOpVariable) break;
 
-    ir::Instruction* varInst = &*iter;
+    opt::Instruction* varInst = &*iter;
     if (CanReplaceVariable(varInst)) {
       worklist.push(varInst);
     }
@@ -57,7 +57,7 @@
 
   Status status = Status::SuccessWithoutChange;
   while (!worklist.empty()) {
-    ir::Instruction* varInst = worklist.front();
+    opt::Instruction* varInst = worklist.front();
     worklist.pop();
 
     if (!ReplaceVariable(varInst, &worklist))
@@ -70,15 +70,15 @@
 }
 
 bool ScalarReplacementPass::ReplaceVariable(
-    ir::Instruction* inst, std::queue<ir::Instruction*>* worklist) {
-  std::vector<ir::Instruction*> replacements;
+    opt::Instruction* inst, std::queue<opt::Instruction*>* worklist) {
+  std::vector<opt::Instruction*> replacements;
   CreateReplacementVariables(inst, &replacements);
 
-  std::vector<ir::Instruction*> dead;
+  std::vector<opt::Instruction*> dead;
   dead.push_back(inst);
   if (!get_def_use_mgr()->WhileEachUser(
-          inst, [this, &replacements, &dead](ir::Instruction* user) {
-            if (!ir::IsAnnotationInst(user->opcode())) {
+          inst, [this, &replacements, &dead](opt::Instruction* user) {
+            if (!opt::IsAnnotationInst(user->opcode())) {
               switch (user->opcode()) {
                 case SpvOpLoad:
                   ReplaceWholeLoad(user, replacements);
@@ -107,7 +107,7 @@
 
   // Clean up some dead code.
   while (!dead.empty()) {
-    ir::Instruction* toKill = dead.back();
+    opt::Instruction* toKill = dead.back();
     dead.pop_back();
     context()->KillInst(toKill);
   }
@@ -127,13 +127,14 @@
 }
 
 void ScalarReplacementPass::ReplaceWholeLoad(
-    ir::Instruction* load, const std::vector<ir::Instruction*>& replacements) {
+    opt::Instruction* load,
+    const std::vector<opt::Instruction*>& replacements) {
   // Replaces the load of the entire composite with a load from each replacement
   // variable followed by a composite construction.
-  ir::BasicBlock* block = context()->get_instr_block(load);
-  std::vector<ir::Instruction*> loads;
+  opt::BasicBlock* block = context()->get_instr_block(load);
+  std::vector<opt::Instruction*> loads;
   loads.reserve(replacements.size());
-  ir::BasicBlock::iterator where(load);
+  opt::BasicBlock::iterator where(load);
   for (auto var : replacements) {
     // Create a load of each replacement variable.
     if (var->opcode() != SpvOpVariable) {
@@ -141,16 +142,16 @@
       continue;
     }
 
-    ir::Instruction* type = GetStorageType(var);
+    opt::Instruction* type = GetStorageType(var);
     uint32_t loadId = TakeNextId();
-    std::unique_ptr<ir::Instruction> newLoad(
-        new ir::Instruction(context(), SpvOpLoad, type->result_id(), loadId,
-                            std::initializer_list<ir::Operand>{
-                                {SPV_OPERAND_TYPE_ID, {var->result_id()}}}));
+    std::unique_ptr<opt::Instruction> newLoad(
+        new opt::Instruction(context(), SpvOpLoad, type->result_id(), loadId,
+                             std::initializer_list<opt::Operand>{
+                                 {SPV_OPERAND_TYPE_ID, {var->result_id()}}}));
     // Copy memory access attributes which start at index 1. Index 0 is the
     // pointer to load.
     for (uint32_t i = 1; i < load->NumInOperands(); ++i) {
-      ir::Operand copy(load->GetInOperand(i));
+      opt::Operand copy(load->GetInOperand(i));
       newLoad->AddOperand(std::move(copy));
     }
     where = where.InsertBefore(std::move(newLoad));
@@ -162,11 +163,11 @@
   // Construct a new composite.
   uint32_t compositeId = TakeNextId();
   where = load;
-  std::unique_ptr<ir::Instruction> compositeConstruct(new ir::Instruction(
+  std::unique_ptr<opt::Instruction> compositeConstruct(new opt::Instruction(
       context(), SpvOpCompositeConstruct, load->type_id(), compositeId, {}));
   for (auto l : loads) {
-    ir::Operand op(SPV_OPERAND_TYPE_ID,
-                   std::initializer_list<uint32_t>{l->result_id()});
+    opt::Operand op(SPV_OPERAND_TYPE_ID,
+                    std::initializer_list<uint32_t>{l->result_id()});
     compositeConstruct->AddOperand(std::move(op));
   }
   where = where.InsertBefore(std::move(compositeConstruct));
@@ -176,12 +177,13 @@
 }
 
 void ScalarReplacementPass::ReplaceWholeStore(
-    ir::Instruction* store, const std::vector<ir::Instruction*>& replacements) {
+    opt::Instruction* store,
+    const std::vector<opt::Instruction*>& replacements) {
   // Replaces a store to the whole composite with a series of extract and stores
   // to each element.
   uint32_t storeInput = store->GetSingleWordInOperand(1u);
-  ir::BasicBlock* block = context()->get_instr_block(store);
-  ir::BasicBlock::iterator where(store);
+  opt::BasicBlock* block = context()->get_instr_block(store);
+  opt::BasicBlock::iterator where(store);
   uint32_t elementIndex = 0;
   for (auto var : replacements) {
     // Create the extract.
@@ -190,11 +192,11 @@
       continue;
     }
 
-    ir::Instruction* type = GetStorageType(var);
+    opt::Instruction* type = GetStorageType(var);
     uint32_t extractId = TakeNextId();
-    std::unique_ptr<ir::Instruction> extract(new ir::Instruction(
+    std::unique_ptr<opt::Instruction> extract(new opt::Instruction(
         context(), SpvOpCompositeExtract, type->result_id(), extractId,
-        std::initializer_list<ir::Operand>{
+        std::initializer_list<opt::Operand>{
             {SPV_OPERAND_TYPE_ID, {storeInput}},
             {SPV_OPERAND_TYPE_LITERAL_INTEGER, {elementIndex++}}}));
     auto iter = where.InsertBefore(std::move(extract));
@@ -202,15 +204,15 @@
     context()->set_instr_block(&*iter, block);
 
     // Create the store.
-    std::unique_ptr<ir::Instruction> newStore(
-        new ir::Instruction(context(), SpvOpStore, 0, 0,
-                            std::initializer_list<ir::Operand>{
-                                {SPV_OPERAND_TYPE_ID, {var->result_id()}},
-                                {SPV_OPERAND_TYPE_ID, {extractId}}}));
+    std::unique_ptr<opt::Instruction> newStore(
+        new opt::Instruction(context(), SpvOpStore, 0, 0,
+                             std::initializer_list<opt::Operand>{
+                                 {SPV_OPERAND_TYPE_ID, {var->result_id()}},
+                                 {SPV_OPERAND_TYPE_ID, {extractId}}}));
     // Copy memory access attributes which start at index 2. Index 0 is the
     // pointer and index 1 is the data.
     for (uint32_t i = 2; i < store->NumInOperands(); ++i) {
-      ir::Operand copy(store->GetInOperand(i));
+      opt::Operand copy(store->GetInOperand(i));
       newStore->AddOperand(std::move(copy));
     }
     iter = where.InsertBefore(std::move(newStore));
@@ -220,28 +222,29 @@
 }
 
 bool ScalarReplacementPass::ReplaceAccessChain(
-    ir::Instruction* chain, const std::vector<ir::Instruction*>& replacements) {
+    opt::Instruction* chain,
+    const std::vector<opt::Instruction*>& replacements) {
   // Replaces the access chain with either another access chain (with one fewer
   // indexes) or a direct use of the replacement variable.
   uint32_t indexId = chain->GetSingleWordInOperand(1u);
-  const ir::Instruction* index = get_def_use_mgr()->GetDef(indexId);
+  const opt::Instruction* index = get_def_use_mgr()->GetDef(indexId);
   size_t indexValue = GetConstantInteger(index);
   if (indexValue > replacements.size()) {
     // Out of bounds access, this is illegal IR.
     return false;
   } else {
-    const ir::Instruction* var = replacements[indexValue];
+    const opt::Instruction* var = replacements[indexValue];
     if (chain->NumInOperands() > 2) {
       // Replace input access chain with another access chain.
-      ir::BasicBlock::iterator chainIter(chain);
+      opt::BasicBlock::iterator chainIter(chain);
       uint32_t replacementId = TakeNextId();
-      std::unique_ptr<ir::Instruction> replacementChain(new ir::Instruction(
+      std::unique_ptr<opt::Instruction> replacementChain(new opt::Instruction(
           context(), chain->opcode(), chain->type_id(), replacementId,
-          std::initializer_list<ir::Operand>{
+          std::initializer_list<opt::Operand>{
               {SPV_OPERAND_TYPE_ID, {var->result_id()}}}));
       // Add the remaining indexes.
       for (uint32_t i = 2; i < chain->NumInOperands(); ++i) {
-        ir::Operand copy(chain->GetInOperand(i));
+        opt::Operand copy(chain->GetInOperand(i));
         replacementChain->AddOperand(std::move(copy));
       }
       auto iter = chainIter.InsertBefore(std::move(replacementChain));
@@ -258,8 +261,8 @@
 }
 
 void ScalarReplacementPass::CreateReplacementVariables(
-    ir::Instruction* inst, std::vector<ir::Instruction*>* replacements) {
-  ir::Instruction* type = GetStorageType(inst);
+    opt::Instruction* inst, std::vector<opt::Instruction*>* replacements) {
+  opt::Instruction* type = GetStorageType(inst);
 
   std::unique_ptr<std::unordered_set<uint64_t>> components_used =
       GetUsedComponents(inst);
@@ -305,8 +308,8 @@
 }
 
 void ScalarReplacementPass::TransferAnnotations(
-    const ir::Instruction* source,
-    std::vector<ir::Instruction*>* replacements) {
+    const opt::Instruction* source,
+    std::vector<opt::Instruction*>* replacements) {
   // Only transfer invariant and restrict decorations on the variable. There are
   // no type or member decorations that are necessary to transfer.
   for (auto inst :
@@ -316,13 +319,13 @@
     if (decoration == SpvDecorationInvariant ||
         decoration == SpvDecorationRestrict) {
       for (auto var : *replacements) {
-        std::unique_ptr<ir::Instruction> annotation(new ir::Instruction(
+        std::unique_ptr<opt::Instruction> annotation(new opt::Instruction(
             context(), SpvOpDecorate, 0, 0,
-            std::initializer_list<ir::Operand>{
+            std::initializer_list<opt::Operand>{
                 {SPV_OPERAND_TYPE_ID, {var->result_id()}},
                 {SPV_OPERAND_TYPE_DECORATION, {decoration}}}));
         for (uint32_t i = 2; i < inst->NumInOperands(); ++i) {
-          ir::Operand copy(inst->GetInOperand(i));
+          opt::Operand copy(inst->GetInOperand(i));
           annotation->AddOperand(std::move(copy));
         }
         context()->AddAnnotationInst(std::move(annotation));
@@ -333,18 +336,18 @@
 }
 
 void ScalarReplacementPass::CreateVariable(
-    uint32_t typeId, ir::Instruction* varInst, uint32_t index,
-    std::vector<ir::Instruction*>* replacements) {
+    uint32_t typeId, opt::Instruction* varInst, uint32_t index,
+    std::vector<opt::Instruction*>* replacements) {
   uint32_t ptrId = GetOrCreatePointerType(typeId);
   uint32_t id = TakeNextId();
-  std::unique_ptr<ir::Instruction> variable(new ir::Instruction(
+  std::unique_ptr<opt::Instruction> variable(new opt::Instruction(
       context(), SpvOpVariable, ptrId, id,
-      std::initializer_list<ir::Operand>{
+      std::initializer_list<opt::Operand>{
           {SPV_OPERAND_TYPE_STORAGE_CLASS, {SpvStorageClassFunction}}}));
 
-  ir::BasicBlock* block = context()->get_instr_block(varInst);
+  opt::BasicBlock* block = context()->get_instr_block(varInst);
   block->begin().InsertBefore(std::move(variable));
-  ir::Instruction* inst = &*block->begin();
+  opt::Instruction* inst = &*block->begin();
 
   // If varInst was initialized, make sure to initialize its replacement.
   GetOrCreateInitialValue(varInst, index, inst);
@@ -391,12 +394,12 @@
   }
 
   ptrId = TakeNextId();
-  context()->AddType(MakeUnique<ir::Instruction>(
+  context()->AddType(MakeUnique<opt::Instruction>(
       context(), SpvOpTypePointer, 0, ptrId,
-      std::initializer_list<ir::Operand>{
+      std::initializer_list<opt::Operand>{
           {SPV_OPERAND_TYPE_STORAGE_CLASS, {SpvStorageClassFunction}},
           {SPV_OPERAND_TYPE_ID, {id}}}));
-  ir::Instruction* ptr = &*--context()->types_values_end();
+  opt::Instruction* ptr = &*--context()->types_values_end();
   get_def_use_mgr()->AnalyzeInstDefUse(ptr);
   pointee_to_pointer_[id] = ptrId;
   // Register with the type manager if necessary.
@@ -405,15 +408,15 @@
   return ptrId;
 }
 
-void ScalarReplacementPass::GetOrCreateInitialValue(ir::Instruction* source,
+void ScalarReplacementPass::GetOrCreateInitialValue(opt::Instruction* source,
                                                     uint32_t index,
-                                                    ir::Instruction* newVar) {
+                                                    opt::Instruction* newVar) {
   assert(source->opcode() == SpvOpVariable);
   if (source->NumInOperands() < 2) return;
 
   uint32_t initId = source->GetSingleWordInOperand(1u);
   uint32_t storageId = GetStorageType(newVar)->result_id();
-  ir::Instruction* init = get_def_use_mgr()->GetDef(initId);
+  opt::Instruction* init = get_def_use_mgr()->GetDef(initId);
   uint32_t newInitId = 0;
   // TODO(dnovillo): Refactor this with constant propagation.
   if (init->opcode() == SpvOpConstantNull) {
@@ -422,29 +425,29 @@
     if (iter == type_to_null_.end()) {
       newInitId = TakeNextId();
       type_to_null_[storageId] = newInitId;
-      context()->AddGlobalValue(MakeUnique<ir::Instruction>(
+      context()->AddGlobalValue(MakeUnique<opt::Instruction>(
           context(), SpvOpConstantNull, storageId, newInitId,
-          std::initializer_list<ir::Operand>{}));
-      ir::Instruction* newNull = &*--context()->types_values_end();
+          std::initializer_list<opt::Operand>{}));
+      opt::Instruction* newNull = &*--context()->types_values_end();
       get_def_use_mgr()->AnalyzeInstDefUse(newNull);
     } else {
       newInitId = iter->second;
     }
-  } else if (ir::IsSpecConstantInst(init->opcode())) {
+  } else if (opt::IsSpecConstantInst(init->opcode())) {
     // Create a new constant extract.
     newInitId = TakeNextId();
-    context()->AddGlobalValue(MakeUnique<ir::Instruction>(
+    context()->AddGlobalValue(MakeUnique<opt::Instruction>(
         context(), SpvOpSpecConstantOp, storageId, newInitId,
-        std::initializer_list<ir::Operand>{
+        std::initializer_list<opt::Operand>{
             {SPV_OPERAND_TYPE_SPEC_CONSTANT_OP_NUMBER, {SpvOpCompositeExtract}},
             {SPV_OPERAND_TYPE_ID, {init->result_id()}},
             {SPV_OPERAND_TYPE_LITERAL_INTEGER, {index}}}));
-    ir::Instruction* newSpecConst = &*--context()->types_values_end();
+    opt::Instruction* newSpecConst = &*--context()->types_values_end();
     get_def_use_mgr()->AnalyzeInstDefUse(newSpecConst);
   } else if (init->opcode() == SpvOpConstantComposite) {
     // Get the appropriate index constant.
     newInitId = init->GetSingleWordInOperand(index);
-    ir::Instruction* element = get_def_use_mgr()->GetDef(newInitId);
+    opt::Instruction* element = get_def_use_mgr()->GetDef(newInitId);
     if (element->opcode() == SpvOpUndef) {
       // Undef is not a valid initializer for a variable.
       newInitId = 0;
@@ -458,7 +461,7 @@
   }
 }
 
-size_t ScalarReplacementPass::GetIntegerLiteral(const ir::Operand& op) const {
+size_t ScalarReplacementPass::GetIntegerLiteral(const opt::Operand& op) const {
   assert(op.words.size() <= 2);
   size_t len = 0;
   for (uint32_t i = 0; i != op.words.size(); ++i) {
@@ -468,7 +471,7 @@
 }
 
 size_t ScalarReplacementPass::GetConstantInteger(
-    const ir::Instruction* constant) const {
+    const opt::Instruction* constant) const {
   assert(get_def_use_mgr()->GetDef(constant->type_id())->opcode() ==
          SpvOpTypeInt);
   assert(constant->opcode() == SpvOpConstant ||
@@ -477,23 +480,23 @@
     return 0;
   }
 
-  const ir::Operand& op = constant->GetInOperand(0u);
+  const opt::Operand& op = constant->GetInOperand(0u);
   return GetIntegerLiteral(op);
 }
 
 size_t ScalarReplacementPass::GetArrayLength(
-    const ir::Instruction* arrayType) const {
+    const opt::Instruction* arrayType) const {
   assert(arrayType->opcode() == SpvOpTypeArray);
-  const ir::Instruction* length =
+  const opt::Instruction* length =
       get_def_use_mgr()->GetDef(arrayType->GetSingleWordInOperand(1u));
   return GetConstantInteger(length);
 }
 
 size_t ScalarReplacementPass::GetNumElements(
-    const ir::Instruction* type) const {
+    const opt::Instruction* type) const {
   assert(type->opcode() == SpvOpTypeVector ||
          type->opcode() == SpvOpTypeMatrix);
-  const ir::Operand& op = type->GetInOperand(1u);
+  const opt::Operand& op = type->GetInOperand(1u);
   assert(op.words.size() <= 2);
   size_t len = 0;
   for (uint32_t i = 0; i != op.words.size(); ++i) {
@@ -502,8 +505,8 @@
   return len;
 }
 
-ir::Instruction* ScalarReplacementPass::GetStorageType(
-    const ir::Instruction* inst) const {
+opt::Instruction* ScalarReplacementPass::GetStorageType(
+    const opt::Instruction* inst) const {
   assert(inst->opcode() == SpvOpVariable);
 
   uint32_t ptrTypeId = inst->type_id();
@@ -513,7 +516,7 @@
 }
 
 bool ScalarReplacementPass::CanReplaceVariable(
-    const ir::Instruction* varInst) const {
+    const opt::Instruction* varInst) const {
   assert(varInst->opcode() == SpvOpVariable);
 
   // Can only replace function scope variables.
@@ -523,11 +526,11 @@
   if (!CheckTypeAnnotations(get_def_use_mgr()->GetDef(varInst->type_id())))
     return false;
 
-  const ir::Instruction* typeInst = GetStorageType(varInst);
+  const opt::Instruction* typeInst = GetStorageType(varInst);
   return CheckType(typeInst) && CheckAnnotations(varInst) && CheckUses(varInst);
 }
 
-bool ScalarReplacementPass::CheckType(const ir::Instruction* typeInst) const {
+bool ScalarReplacementPass::CheckType(const opt::Instruction* typeInst) const {
   if (!CheckTypeAnnotations(typeInst)) return false;
 
   switch (typeInst->opcode()) {
@@ -556,7 +559,7 @@
 }
 
 bool ScalarReplacementPass::CheckTypeAnnotations(
-    const ir::Instruction* typeInst) const {
+    const opt::Instruction* typeInst) const {
   for (auto inst :
        get_decoration_mgr()->GetDecorationsFor(typeInst->result_id(), false)) {
     uint32_t decoration;
@@ -589,7 +592,7 @@
 }
 
 bool ScalarReplacementPass::CheckAnnotations(
-    const ir::Instruction* varInst) const {
+    const opt::Instruction* varInst) const {
   for (auto inst :
        get_decoration_mgr()->GetDecorationsFor(varInst->result_id(), false)) {
     assert(inst->opcode() == SpvOpDecorate);
@@ -609,7 +612,7 @@
   return true;
 }
 
-bool ScalarReplacementPass::CheckUses(const ir::Instruction* inst) const {
+bool ScalarReplacementPass::CheckUses(const opt::Instruction* inst) const {
   VariableStats stats = {0, 0};
   bool ok = CheckUses(inst, &stats);
 
@@ -620,20 +623,20 @@
   return ok;
 }
 
-bool ScalarReplacementPass::CheckUses(const ir::Instruction* inst,
+bool ScalarReplacementPass::CheckUses(const opt::Instruction* inst,
                                       VariableStats* stats) const {
   bool ok = true;
   get_def_use_mgr()->ForEachUse(
-      inst, [this, stats, &ok](const ir::Instruction* user, uint32_t index) {
+      inst, [this, stats, &ok](const opt::Instruction* user, uint32_t index) {
         // Annotations are check as a group separately.
-        if (!ir::IsAnnotationInst(user->opcode())) {
+        if (!opt::IsAnnotationInst(user->opcode())) {
           switch (user->opcode()) {
             case SpvOpAccessChain:
             case SpvOpInBoundsAccessChain:
               if (index == 2u) {
                 uint32_t id = user->GetSingleWordOperand(3u);
-                const ir::Instruction* opInst = get_def_use_mgr()->GetDef(id);
-                if (!ir::IsCompileTimeConstantInst(opInst->opcode())) {
+                const opt::Instruction* opInst = get_def_use_mgr()->GetDef(id);
+                if (!opt::IsCompileTimeConstantInst(opInst->opcode())) {
                   ok = false;
                 } else {
                   if (!CheckUsesRelaxed(user)) ok = false;
@@ -665,10 +668,10 @@
 }
 
 bool ScalarReplacementPass::CheckUsesRelaxed(
-    const ir::Instruction* inst) const {
+    const opt::Instruction* inst) const {
   bool ok = true;
   get_def_use_mgr()->ForEachUse(
-      inst, [this, &ok](const ir::Instruction* user, uint32_t index) {
+      inst, [this, &ok](const opt::Instruction* user, uint32_t index) {
         switch (user->opcode()) {
           case SpvOpAccessChain:
           case SpvOpInBoundsAccessChain:
@@ -693,7 +696,7 @@
   return ok;
 }
 
-bool ScalarReplacementPass::CheckLoad(const ir::Instruction* inst,
+bool ScalarReplacementPass::CheckLoad(const opt::Instruction* inst,
                                       uint32_t index) const {
   if (index != 2u) return false;
   if (inst->NumInOperands() >= 2 &&
@@ -702,7 +705,7 @@
   return true;
 }
 
-bool ScalarReplacementPass::CheckStore(const ir::Instruction* inst,
+bool ScalarReplacementPass::CheckStore(const opt::Instruction* inst,
                                        uint32_t index) const {
   if (index != 0u) return false;
   if (inst->NumInOperands() >= 3 &&
@@ -718,19 +721,19 @@
 }
 
 std::unique_ptr<std::unordered_set<uint64_t>>
-ScalarReplacementPass::GetUsedComponents(ir::Instruction* inst) {
+ScalarReplacementPass::GetUsedComponents(opt::Instruction* inst) {
   std::unique_ptr<std::unordered_set<uint64_t>> result(
       new std::unordered_set<uint64_t>());
 
   analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr();
 
   def_use_mgr->WhileEachUser(inst, [&result, def_use_mgr,
-                                    this](ir::Instruction* use) {
+                                    this](opt::Instruction* use) {
     switch (use->opcode()) {
       case SpvOpLoad: {
         // Look for extract from the load.
         std::vector<uint32_t> t;
-        if (def_use_mgr->WhileEachUser(use, [&t](ir::Instruction* use2) {
+        if (def_use_mgr->WhileEachUser(use, [&t](opt::Instruction* use2) {
               if (use2->opcode() != SpvOpCompositeExtract) {
                 return false;
               }
@@ -794,13 +797,13 @@
   return result;
 }
 
-ir::Instruction* ScalarReplacementPass::CreateNullConstant(uint32_t type_id) {
+opt::Instruction* ScalarReplacementPass::CreateNullConstant(uint32_t type_id) {
   analysis::TypeManager* type_mgr = context()->get_type_mgr();
   analysis::ConstantManager* const_mgr = context()->get_constant_mgr();
 
   const analysis::Type* type = type_mgr->GetType(type_id);
   const analysis::Constant* null_const = const_mgr->GetConstant(type, {});
-  ir::Instruction* null_inst =
+  opt::Instruction* null_inst =
       const_mgr->GetDefiningInstruction(null_const, type_id);
   context()->UpdateDefUse(null_inst);
   return null_inst;
diff --git a/source/opt/scalar_replacement_pass.h b/source/opt/scalar_replacement_pass.h
index 6a02955..cf801ca 100644
--- a/source/opt/scalar_replacement_pass.h
+++ b/source/opt/scalar_replacement_pass.h
@@ -43,14 +43,14 @@
 
   // Attempts to scalarize all appropriate function scope variables. Returns
   // SuccessWithChange if any change is made.
-  Status Process(ir::IRContext* c) override;
+  Status Process(opt::IRContext* c) override;
 
-  ir::IRContext::Analysis GetPreservedAnalyses() override {
-    return ir::IRContext::kAnalysisDefUse |
-           ir::IRContext::kAnalysisInstrToBlockMapping |
-           ir::IRContext::kAnalysisDecorations |
-           ir::IRContext::kAnalysisCombinators | ir::IRContext::kAnalysisCFG |
-           ir::IRContext::kAnalysisNameMap;
+  opt::IRContext::Analysis GetPreservedAnalyses() override {
+    return opt::IRContext::kAnalysisDefUse |
+           opt::IRContext::kAnalysisInstrToBlockMapping |
+           opt::IRContext::kAnalysisDecorations |
+           opt::IRContext::kAnalysisCombinators | opt::IRContext::kAnalysisCFG |
+           opt::IRContext::kAnalysisNameMap;
   }
 
  private:
@@ -64,27 +64,27 @@
 
   // Attempts to scalarize all appropriate function scope variables in
   // |function|. Returns SuccessWithChange if any changes are mode.
-  Status ProcessFunction(ir::Function* function);
+  Status ProcessFunction(opt::Function* function);
 
   // Returns true if |varInst| can be scalarized.
   //
   // Examines the use chain of |varInst| to verify all uses are valid for
   // scalarization.
-  bool CanReplaceVariable(const ir::Instruction* varInst) const;
+  bool CanReplaceVariable(const opt::Instruction* varInst) const;
 
   // Returns true if |typeInst| is an acceptable type to scalarize.
   //
   // Allows all aggregate types except runtime arrays. Additionally, checks the
   // that the number of elements that would be scalarized is within bounds.
-  bool CheckType(const ir::Instruction* typeInst) const;
+  bool CheckType(const opt::Instruction* typeInst) const;
 
   // Returns true if all the decorations for |varInst| are acceptable for
   // scalarization.
-  bool CheckAnnotations(const ir::Instruction* varInst) const;
+  bool CheckAnnotations(const opt::Instruction* varInst) const;
 
   // Returns true if all the decorations for |typeInst| are acceptable for
   // scalarization.
-  bool CheckTypeAnnotations(const ir::Instruction* typeInst) const;
+  bool CheckTypeAnnotations(const opt::Instruction* typeInst) const;
 
   // Returns true if the uses of |inst| are acceptable for scalarization.
   //
@@ -93,20 +93,20 @@
   // SpvOpStore. Access chains must have the first index be a compile-time
   // constant. Subsequent uses of access chains (including other access chains)
   // are checked in a more relaxed manner.
-  bool CheckUses(const ir::Instruction* inst) const;
+  bool CheckUses(const opt::Instruction* inst) const;
 
   // Helper function for the above |CheckUses|.
   //
   // This version tracks some stats about the current OpVariable. These stats
   // are used to drive heuristics about when to scalarize.
-  bool CheckUses(const ir::Instruction* inst, VariableStats* stats) const;
+  bool CheckUses(const opt::Instruction* inst, VariableStats* stats) const;
 
   // Relaxed helper function for |CheckUses|.
-  bool CheckUsesRelaxed(const ir::Instruction* inst) const;
+  bool CheckUsesRelaxed(const opt::Instruction* inst) const;
 
   // Transfers appropriate decorations from |source| to |replacements|.
-  void TransferAnnotations(const ir::Instruction* source,
-                           std::vector<ir::Instruction*>* replacements);
+  void TransferAnnotations(const opt::Instruction* source,
+                           std::vector<opt::Instruction*>* replacements);
 
   // Scalarizes |inst| and updates its uses.
   //
@@ -116,31 +116,32 @@
   // get added to |worklist| for further processing. If any replacement
   // variable ends up with no uses it is erased. Returns false if any
   // subsequent access chain is out of bounds.
-  bool ReplaceVariable(ir::Instruction* inst,
-                       std::queue<ir::Instruction*>* worklist);
+  bool ReplaceVariable(opt::Instruction* inst,
+                       std::queue<opt::Instruction*>* worklist);
 
   // Returns the underlying storage type for |inst|.
   //
   // |inst| must be an OpVariable. Returns the type that is pointed to by
   // |inst|.
-  ir::Instruction* GetStorageType(const ir::Instruction* inst) const;
+  opt::Instruction* GetStorageType(const opt::Instruction* inst) const;
 
   // Returns true if the load can be scalarized.
   //
   // |inst| must be an OpLoad. Returns true if |index| is the pointer operand of
   // |inst| and the load is not from volatile memory.
-  bool CheckLoad(const ir::Instruction* inst, uint32_t index) const;
+  bool CheckLoad(const opt::Instruction* inst, uint32_t index) const;
 
   // Returns true if the store can be scalarized.
   //
   // |inst| must be an OpStore. Returns true if |index| is the pointer operand
   // of |inst| and the store is not to volatile memory.
-  bool CheckStore(const ir::Instruction* inst, uint32_t index) const;
+  bool CheckStore(const opt::Instruction* inst, uint32_t index) const;
 
   // Creates a variable of type |typeId| from the |index|'th element of
   // |varInst|. The new variable is added to |replacements|.
-  void CreateVariable(uint32_t typeId, ir::Instruction* varInst, uint32_t index,
-                      std::vector<ir::Instruction*>* replacements);
+  void CreateVariable(uint32_t typeId, opt::Instruction* varInst,
+                      uint32_t index,
+                      std::vector<opt::Instruction*>* replacements);
 
   // Populates |replacements| with a new OpVariable for each element of |inst|.
   //
@@ -149,24 +150,24 @@
   // will contain a variable for each element of the composite with matching
   // indexes (i.e. the 0'th element of |inst| is the 0'th entry of
   // |replacements|).
-  void CreateReplacementVariables(ir::Instruction* inst,
-                                  std::vector<ir::Instruction*>* replacements);
+  void CreateReplacementVariables(opt::Instruction* inst,
+                                  std::vector<opt::Instruction*>* replacements);
 
   // Returns the value of an OpConstant of integer type.
   //
   // |constant| must use two or fewer words to generate the value.
-  size_t GetConstantInteger(const ir::Instruction* constant) const;
+  size_t GetConstantInteger(const opt::Instruction* constant) const;
 
   // Returns the integer literal for |op|.
-  size_t GetIntegerLiteral(const ir::Operand& op) const;
+  size_t GetIntegerLiteral(const opt::Operand& op) const;
 
   // Returns the array length for |arrayInst|.
-  size_t GetArrayLength(const ir::Instruction* arrayInst) const;
+  size_t GetArrayLength(const opt::Instruction* arrayInst) const;
 
   // Returns the number of elements in |type|.
   //
   // |type| must be a vector or matrix type.
-  size_t GetNumElements(const ir::Instruction* type) const;
+  size_t GetNumElements(const opt::Instruction* type) const;
 
   // Returns an id for a pointer to |id|.
   uint32_t GetOrCreatePointerType(uint32_t id);
@@ -176,8 +177,8 @@
   // If there is an initial value for |source| for element |index|, it is
   // appended as an operand on |newVar|. If the initial value is OpUndef, no
   // initial value is added to |newVar|.
-  void GetOrCreateInitialValue(ir::Instruction* source, uint32_t index,
-                               ir::Instruction* newVar);
+  void GetOrCreateInitialValue(opt::Instruction* source, uint32_t index,
+                               opt::Instruction* newVar);
 
   // Replaces the load to the entire composite.
   //
@@ -185,32 +186,32 @@
   // composite by combining all of the loads.
   //
   // |load| must be a load.
-  void ReplaceWholeLoad(ir::Instruction* load,
-                        const std::vector<ir::Instruction*>& replacements);
+  void ReplaceWholeLoad(opt::Instruction* load,
+                        const std::vector<opt::Instruction*>& replacements);
 
   // Replaces the store to the entire composite.
   //
   // Generates a composite extract and store for each element in the scalarized
   // variable from the original store data input.
-  void ReplaceWholeStore(ir::Instruction* store,
-                         const std::vector<ir::Instruction*>& replacements);
+  void ReplaceWholeStore(opt::Instruction* store,
+                         const std::vector<opt::Instruction*>& replacements);
 
   // Replaces an access chain to the composite variable with either a direct use
   // of the appropriate replacement variable or another access chain with the
   // replacement variable as the base and one fewer indexes. Returns false if
   // the chain has an out of bounds access.
-  bool ReplaceAccessChain(ir::Instruction* chain,
-                          const std::vector<ir::Instruction*>& replacements);
+  bool ReplaceAccessChain(opt::Instruction* chain,
+                          const std::vector<opt::Instruction*>& replacements);
 
   // Returns a set containing the which components of the result of |inst| are
   // potentially used.  If the return value is |nullptr|, then every components
   // is possibly used.
   std::unique_ptr<std::unordered_set<uint64_t>> GetUsedComponents(
-      ir::Instruction* inst);
+      opt::Instruction* inst);
 
   // Returns an instruction defining a null constant with type |type_id|.  If
   // one already exists, it is returned.  Otherwise a new one is created.
-  ir::Instruction* CreateNullConstant(uint32_t type_id);
+  opt::Instruction* CreateNullConstant(uint32_t type_id);
 
   // Maps storage type to a pointer type enclosing that type.
   std::unordered_map<uint32_t, uint32_t> pointee_to_pointer_;
diff --git a/source/opt/set_spec_constant_default_value_pass.cpp b/source/opt/set_spec_constant_default_value_pass.cpp
index 0adad5c..ab5b564 100644
--- a/source/opt/set_spec_constant_default_value_pass.cpp
+++ b/source/opt/set_spec_constant_default_value_pass.cpp
@@ -112,7 +112,7 @@
 
 // Returns true if the given instruction's result id could have a SpecId
 // decoration.
-bool CanHaveSpecIdDecoration(const ir::Instruction& inst) {
+bool CanHaveSpecIdDecoration(const opt::Instruction& inst) {
   switch (inst.opcode()) {
     case SpvOp::SpvOpSpecConstant:
     case SpvOp::SpvOpSpecConstantFalse:
@@ -127,8 +127,8 @@
 // decoration, finds the spec constant defining instruction which is the real
 // target of the SpecId decoration. Returns the spec constant defining
 // instruction if such an instruction is found, otherwise returns a nullptr.
-ir::Instruction* GetSpecIdTargetFromDecorationGroup(
-    const ir::Instruction& decoration_group_defining_inst,
+opt::Instruction* GetSpecIdTargetFromDecorationGroup(
+    const opt::Instruction& decoration_group_defining_inst,
     analysis::DefUseManager* def_use_mgr) {
   // Find the OpGroupDecorate instruction which consumes the given decoration
   // group. Note that the given decoration group has SpecId decoration, which
@@ -136,16 +136,16 @@
   // consumed by different OpGroupDecorate instructions. Therefore we only need
   // the first OpGroupDecoration instruction that uses the given decoration
   // group.
-  ir::Instruction* group_decorate_inst = nullptr;
-  if (def_use_mgr->WhileEachUser(&decoration_group_defining_inst,
-                                 [&group_decorate_inst](ir::Instruction* user) {
-                                   if (user->opcode() ==
-                                       SpvOp::SpvOpGroupDecorate) {
-                                     group_decorate_inst = user;
-                                     return false;
-                                   }
-                                   return true;
-                                 }))
+  opt::Instruction* group_decorate_inst = nullptr;
+  if (def_use_mgr->WhileEachUser(
+          &decoration_group_defining_inst,
+          [&group_decorate_inst](opt::Instruction* user) {
+            if (user->opcode() == SpvOp::SpvOpGroupDecorate) {
+              group_decorate_inst = user;
+              return false;
+            }
+            return true;
+          }))
     return nullptr;
 
   // Scan through the target ids of the OpGroupDecorate instruction. There
@@ -155,12 +155,12 @@
   // instruction. If the OpGroupDecorate instruction has different target ids
   // or a target id is not defined by an eligible spec cosntant instruction,
   // returns a nullptr.
-  ir::Instruction* target_inst = nullptr;
+  opt::Instruction* target_inst = nullptr;
   for (uint32_t i = 1; i < group_decorate_inst->NumInOperands(); i++) {
     // All the operands of a OpGroupDecorate instruction should be of type
     // SPV_OPERAND_TYPE_ID.
     uint32_t candidate_id = group_decorate_inst->GetSingleWordInOperand(i);
-    ir::Instruction* candidate_inst = def_use_mgr->GetDef(candidate_id);
+    opt::Instruction* candidate_inst = def_use_mgr->GetDef(candidate_id);
 
     if (!candidate_inst) {
       continue;
@@ -191,7 +191,7 @@
 }  // namespace
 
 Pass::Status SetSpecConstantDefaultValuePass::Process(
-    ir::IRContext* irContext) {
+    opt::IRContext* irContext) {
   InitializeProcessing(irContext);
 
   // The operand index of decoration target in an OpDecorate instruction.
@@ -216,7 +216,7 @@
   // is found for a spec id, the string will be parsed according to the target
   // spec constant type. The parsed value will be used to replace the original
   // default value of the target spec constant.
-  for (ir::Instruction& inst : irContext->annotations()) {
+  for (opt::Instruction& inst : irContext->annotations()) {
     // Only process 'OpDecorate SpecId' instructions
     if (inst.opcode() != SpvOp::SpvOpDecorate) continue;
     if (inst.NumOperands() != kOpDecorateSpecIdNumOperands) continue;
@@ -231,8 +231,8 @@
 
     // Find the spec constant defining instruction. Note that the
     // target_id might be a decoration group id.
-    ir::Instruction* spec_inst = nullptr;
-    if (ir::Instruction* target_inst = get_def_use_mgr()->GetDef(target_id)) {
+    opt::Instruction* spec_inst = nullptr;
+    if (opt::Instruction* target_inst = get_def_use_mgr()->GetDef(target_id)) {
       if (target_inst->opcode() == SpvOp::SpvOpDecorationGroup) {
         spec_inst =
             GetSpecIdTargetFromDecorationGroup(*target_inst, get_def_use_mgr());
diff --git a/source/opt/set_spec_constant_default_value_pass.h b/source/opt/set_spec_constant_default_value_pass.h
index 95667bb..823258d 100644
--- a/source/opt/set_spec_constant_default_value_pass.h
+++ b/source/opt/set_spec_constant_default_value_pass.h
@@ -32,7 +32,7 @@
   using SpecIdToValueStrMap = std::unordered_map<uint32_t, std::string>;
   using SpecIdToValueBitPatternMap =
       std::unordered_map<uint32_t, std::vector<uint32_t>>;
-  using SpecIdToInstMap = std::unordered_map<uint32_t, ir::Instruction*>;
+  using SpecIdToInstMap = std::unordered_map<uint32_t, opt::Instruction*>;
 
   // Constructs a pass instance with a map from spec ids to default values
   // in the form of string.
@@ -56,7 +56,7 @@
         spec_id_to_value_bit_pattern_(std::move(default_values)) {}
 
   const char* name() const override { return "set-spec-const-default-value"; }
-  Status Process(ir::IRContext*) override;
+  Status Process(opt::IRContext*) override;
 
   // Parses the given null-terminated C string to get a mapping from Spec Id to
   // default value strings. Returns a unique pointer of the mapping from spec
diff --git a/source/opt/simplification_pass.cpp b/source/opt/simplification_pass.cpp
index 984dd1a..d3814f5 100644
--- a/source/opt/simplification_pass.cpp
+++ b/source/opt/simplification_pass.cpp
@@ -23,17 +23,17 @@
 namespace spvtools {
 namespace opt {
 
-Pass::Status SimplificationPass::Process(ir::IRContext* c) {
+Pass::Status SimplificationPass::Process(opt::IRContext* c) {
   InitializeProcessing(c);
   bool modified = false;
 
-  for (ir::Function& function : *get_module()) {
+  for (opt::Function& function : *get_module()) {
     modified |= SimplifyFunction(&function);
   }
   return (modified ? Status::SuccessWithChange : Status::SuccessWithoutChange);
 }
 
-bool SimplificationPass::SimplifyFunction(ir::Function* function) {
+bool SimplificationPass::SimplifyFunction(opt::Function* function) {
   bool modified = false;
   // Phase 1: Traverse all instructions in dominance order.
   // The second phase will only be on the instructions whose inputs have changed
@@ -41,17 +41,17 @@
   // only instructions whose inputs do not necessarily dominate the use, we keep
   // track of the OpPhi instructions already seen, and add them to the work list
   // for phase 2 when needed.
-  std::vector<ir::Instruction*> work_list;
-  std::unordered_set<ir::Instruction*> process_phis;
-  std::unordered_set<ir::Instruction*> inst_to_kill;
-  std::unordered_set<ir::Instruction*> in_work_list;
+  std::vector<opt::Instruction*> work_list;
+  std::unordered_set<opt::Instruction*> process_phis;
+  std::unordered_set<opt::Instruction*> inst_to_kill;
+  std::unordered_set<opt::Instruction*> in_work_list;
   const opt::InstructionFolder& folder = context()->get_instruction_folder();
 
   cfg()->ForEachBlockInReversePostOrder(
       function->entry().get(),
       [&modified, &process_phis, &work_list, &in_work_list, &inst_to_kill,
-       folder, this](ir::BasicBlock* bb) {
-        for (ir::Instruction* inst = &*bb->begin(); inst;
+       folder, this](opt::BasicBlock* bb) {
+        for (opt::Instruction* inst = &*bb->begin(); inst;
              inst = inst->NextNode()) {
           if (inst->opcode() == SpvOpPhi) {
             process_phis.insert(inst);
@@ -63,7 +63,7 @@
             context()->AnalyzeUses(inst);
             get_def_use_mgr()->ForEachUser(inst, [&work_list, &process_phis,
                                                   &in_work_list](
-                                                     ir::Instruction* use) {
+                                                     opt::Instruction* use) {
               if (process_phis.count(use) && in_work_list.insert(use).second) {
                 work_list.push_back(use);
               }
@@ -85,13 +85,13 @@
   //          done.  This time we add all users to the work list because phase 1
   //          has already finished.
   for (size_t i = 0; i < work_list.size(); ++i) {
-    ir::Instruction* inst = work_list[i];
+    opt::Instruction* inst = work_list[i];
     in_work_list.erase(inst);
     if (inst->opcode() == SpvOpCopyObject || folder.FoldInstruction(inst)) {
       modified = true;
       context()->AnalyzeUses(inst);
       get_def_use_mgr()->ForEachUser(
-          inst, [&work_list, &in_work_list](ir::Instruction* use) {
+          inst, [&work_list, &in_work_list](opt::Instruction* use) {
             if (!use->IsDecoration() && use->opcode() != SpvOpName &&
                 in_work_list.insert(use).second) {
               work_list.push_back(use);
@@ -111,7 +111,7 @@
   }
 
   // Phase 3: Kill instructions we know are no longer needed.
-  for (ir::Instruction* inst : inst_to_kill) {
+  for (opt::Instruction* inst : inst_to_kill) {
     context()->KillInst(inst);
   }
 
diff --git a/source/opt/simplification_pass.h b/source/opt/simplification_pass.h
index 206d9dc..4dc2661 100644
--- a/source/opt/simplification_pass.h
+++ b/source/opt/simplification_pass.h
@@ -26,21 +26,21 @@
 class SimplificationPass : public Pass {
  public:
   const char* name() const override { return "simplify-instructions"; }
-  Status Process(ir::IRContext*) override;
-  virtual ir::IRContext::Analysis GetPreservedAnalyses() override {
-    return ir::IRContext::kAnalysisDefUse |
-           ir::IRContext::kAnalysisInstrToBlockMapping |
-           ir::IRContext::kAnalysisDecorations |
-           ir::IRContext::kAnalysisCombinators | ir::IRContext::kAnalysisCFG |
-           ir::IRContext::kAnalysisDominatorAnalysis |
-           ir::IRContext::kAnalysisNameMap;
+  Status Process(opt::IRContext*) override;
+  virtual opt::IRContext::Analysis GetPreservedAnalyses() override {
+    return opt::IRContext::kAnalysisDefUse |
+           opt::IRContext::kAnalysisInstrToBlockMapping |
+           opt::IRContext::kAnalysisDecorations |
+           opt::IRContext::kAnalysisCombinators | opt::IRContext::kAnalysisCFG |
+           opt::IRContext::kAnalysisDominatorAnalysis |
+           opt::IRContext::kAnalysisNameMap;
   }
 
  private:
   // Returns true if the module was changed.  The simplifier is called on every
   // instruction in |function| until nothing else in the function can be
   // simplified.
-  bool SimplifyFunction(ir::Function* function);
+  bool SimplifyFunction(opt::Function* function);
 };
 
 }  // namespace opt
diff --git a/source/opt/ssa_rewrite_pass.cpp b/source/opt/ssa_rewrite_pass.cpp
index 1e8be88..8fdc504 100644
--- a/source/opt/ssa_rewrite_pass.cpp
+++ b/source/opt/ssa_rewrite_pass.cpp
@@ -66,7 +66,7 @@
 const uint32_t kVariableInitIdInIdx = 1;
 }  // namespace
 
-std::string SSARewriter::PhiCandidate::PrettyPrint(const ir::CFG* cfg) const {
+std::string SSARewriter::PhiCandidate::PrettyPrint(const opt::CFG* cfg) const {
   std::ostringstream str;
   str << "%" << result_id_ << " = Phi[%" << var_id_ << ", BB %" << bb_->id()
       << "](";
@@ -86,8 +86,8 @@
   return str.str();
 }
 
-SSARewriter::PhiCandidate& SSARewriter::CreatePhiCandidate(uint32_t var_id,
-                                                           ir::BasicBlock* bb) {
+SSARewriter::PhiCandidate& SSARewriter::CreatePhiCandidate(
+    uint32_t var_id, opt::BasicBlock* bb) {
   uint32_t phi_result_id = pass_->context()->TakeNextId();
   auto result = phi_candidates_.emplace(
       phi_result_id, PhiCandidate(var_id, phi_result_id, bb));
@@ -161,7 +161,7 @@
 
   bool found_0_arg = false;
   for (uint32_t pred : pass_->cfg()->preds(phi_candidate->bb()->id())) {
-    ir::BasicBlock* pred_bb = pass_->cfg()->block(pred);
+    opt::BasicBlock* pred_bb = pass_->cfg()->block(pred);
 
     // If |pred_bb| is not sealed, use %0 to indicate that
     // |phi_candidate| needs to be completed after the whole CFG has
@@ -233,7 +233,7 @@
   return repl_id;
 }
 
-uint32_t SSARewriter::GetReachingDef(uint32_t var_id, ir::BasicBlock* bb) {
+uint32_t SSARewriter::GetReachingDef(uint32_t var_id, opt::BasicBlock* bb) {
   // If |var_id| has a definition in |bb|, return it.
   const auto& bb_it = defs_at_block_.find(bb);
   if (bb_it != defs_at_block_.end()) {
@@ -271,14 +271,14 @@
   return val_id;
 }
 
-void SSARewriter::SealBlock(ir::BasicBlock* bb) {
+void SSARewriter::SealBlock(opt::BasicBlock* bb) {
   auto result = sealed_blocks_.insert(bb);
   (void)result;
   assert(result.second == true &&
          "Tried to seal the same basic block more than once.");
 }
 
-void SSARewriter::ProcessStore(ir::Instruction* inst, ir::BasicBlock* bb) {
+void SSARewriter::ProcessStore(opt::Instruction* inst, opt::BasicBlock* bb) {
   auto opcode = inst->opcode();
   assert((opcode == SpvOpStore || opcode == SpvOpVariable) &&
          "Expecting a store or a variable definition instruction.");
@@ -303,7 +303,7 @@
   }
 }
 
-void SSARewriter::ProcessLoad(ir::Instruction* inst, ir::BasicBlock* bb) {
+void SSARewriter::ProcessLoad(opt::Instruction* inst, opt::BasicBlock* bb) {
   uint32_t var_id = 0;
   (void)pass_->GetPtr(inst, &var_id);
   if (pass_->IsTargetVar(var_id)) {
@@ -346,7 +346,7 @@
   std::cerr << "\n";
 }
 
-void SSARewriter::GenerateSSAReplacements(ir::BasicBlock* bb) {
+void SSARewriter::GenerateSSAReplacements(opt::BasicBlock* bb) {
 #if SSA_REWRITE_DEBUGGING_LEVEL > 1
   std::cerr << "Generating SSA replacements for block: " << bb->id() << "\n";
   std::cerr << bb->PrettyPrint(SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES)
@@ -416,7 +416,7 @@
 #endif
 
   // Add Phi instructions from completed Phi candidates.
-  std::vector<ir::Instruction*> generated_phis;
+  std::vector<opt::Instruction*> generated_phis;
   for (const PhiCandidate* phi_candidate : phis_to_generate_) {
 #if SSA_REWRITE_DEBUGGING_LEVEL > 2
     std::cerr << "Phi candidate: " << phi_candidate->PrettyPrint(pass_->cfg())
@@ -430,7 +430,7 @@
     // Build the vector of operands for the new OpPhi instruction.
     uint32_t type_id = pass_->GetPointeeTypeId(
         pass_->get_def_use_mgr()->GetDef(phi_candidate->var_id()));
-    std::vector<ir::Operand> phi_operands;
+    std::vector<opt::Operand> phi_operands;
     uint32_t arg_ix = 0;
     for (uint32_t pred_label : pass_->cfg()->preds(phi_candidate->bb()->id())) {
       uint32_t op_val_id = GetPhiArgument(phi_candidate, arg_ix++);
@@ -442,9 +442,9 @@
 
     // Generate a new OpPhi instruction and insert it in its basic
     // block.
-    std::unique_ptr<ir::Instruction> phi_inst(
-        new ir::Instruction(pass_->context(), SpvOpPhi, type_id,
-                            phi_candidate->result_id(), phi_operands));
+    std::unique_ptr<opt::Instruction> phi_inst(
+        new opt::Instruction(pass_->context(), SpvOpPhi, type_id,
+                             phi_candidate->result_id(), phi_operands));
     generated_phis.push_back(phi_inst.get());
     pass_->get_def_use_mgr()->AnalyzeInstDef(&*phi_inst);
     pass_->context()->set_instr_block(&*phi_inst, phi_candidate->bb());
@@ -456,7 +456,7 @@
   // Scan uses for all inserted Phi instructions. Do this separately from the
   // registration of the Phi instruction itself to avoid trying to analyze uses
   // of Phi instructions that have not been registered yet.
-  for (ir::Instruction* phi_inst : generated_phis) {
+  for (opt::Instruction* phi_inst : generated_phis) {
     pass_->get_def_use_mgr()->AnalyzeInstUse(&*phi_inst);
   }
 
@@ -469,7 +469,7 @@
   for (auto& repl : load_replacement_) {
     uint32_t load_id = repl.first;
     uint32_t val_id = GetReplacement(repl);
-    ir::Instruction* load_inst =
+    opt::Instruction* load_inst =
         pass_->context()->get_def_use_mgr()->GetDef(load_id);
 
 #if SSA_REWRITE_DEBUGGING_LEVEL > 2
@@ -498,7 +498,7 @@
 
   uint32_t ix = 0;
   for (uint32_t pred : pass_->cfg()->preds(phi_candidate->bb()->id())) {
-    ir::BasicBlock* pred_bb = pass_->cfg()->block(pred);
+    opt::BasicBlock* pred_bb = pass_->cfg()->block(pred);
     uint32_t& arg_id = phi_candidate->phi_args()[ix++];
     if (arg_id == 0) {
       // If |pred_bb| is still not sealed, it means it's unreachable. In this
@@ -536,7 +536,7 @@
   }
 }
 
-bool SSARewriter::RewriteFunctionIntoSSA(ir::Function* fp) {
+bool SSARewriter::RewriteFunctionIntoSSA(opt::Function* fp) {
 #if SSA_REWRITE_DEBUGGING_LEVEL > 0
   std::cerr << "Function before SSA rewrite:\n"
             << fp->PrettyPrint(0) << "\n\n\n";
@@ -549,7 +549,7 @@
   // generate incomplete and trivial Phis.
   pass_->cfg()->ForEachBlockInReversePostOrder(
       fp->entry().get(),
-      [this](ir::BasicBlock* bb) { GenerateSSAReplacements(bb); });
+      [this](opt::BasicBlock* bb) { GenerateSSAReplacements(bb); });
 
   // Remove trivial Phis and add arguments to incomplete Phis.
   FinalizePhiCandidates();
@@ -565,9 +565,9 @@
   return modified;
 }
 
-void SSARewritePass::Initialize(ir::IRContext* c) { InitializeProcessing(c); }
+void SSARewritePass::Initialize(opt::IRContext* c) { InitializeProcessing(c); }
 
-Pass::Status SSARewritePass::Process(ir::IRContext* c) {
+Pass::Status SSARewritePass::Process(opt::IRContext* c) {
   Initialize(c);
 
   bool modified = false;
diff --git a/source/opt/ssa_rewrite_pass.h b/source/opt/ssa_rewrite_pass.h
index e589436..5e6bcaa 100644
--- a/source/opt/ssa_rewrite_pass.h
+++ b/source/opt/ssa_rewrite_pass.h
@@ -43,12 +43,12 @@
   //
   // It returns true if function |fp| was modified.  Otherwise, it returns
   // false.
-  bool RewriteFunctionIntoSSA(ir::Function* fp);
+  bool RewriteFunctionIntoSSA(opt::Function* fp);
 
  private:
   class PhiCandidate {
    public:
-    explicit PhiCandidate(uint32_t var, uint32_t result, ir::BasicBlock* block)
+    explicit PhiCandidate(uint32_t var, uint32_t result, opt::BasicBlock* block)
         : var_id_(var),
           result_id_(result),
           bb_(block),
@@ -59,7 +59,7 @@
 
     uint32_t var_id() const { return var_id_; }
     uint32_t result_id() const { return result_id_; }
-    ir::BasicBlock* bb() const { return bb_; }
+    opt::BasicBlock* bb() const { return bb_; }
     std::vector<uint32_t>& phi_args() { return phi_args_; }
     const std::vector<uint32_t>& phi_args() const { return phi_args_; }
     uint32_t copy_of() const { return copy_of_; }
@@ -81,7 +81,7 @@
 
     // Pretty prints this Phi candidate into a string and returns it. |cfg| is
     // needed to lookup basic block predecessors.
-    std::string PrettyPrint(const ir::CFG* cfg) const;
+    std::string PrettyPrint(const opt::CFG* cfg) const;
 
     // Registers |operand_id| as a user of this Phi candidate.
     void AddUser(uint32_t operand_id) { users_.push_back(operand_id); }
@@ -95,7 +95,7 @@
     uint32_t result_id_;
 
     // Basic block to hold this Phi.
-    ir::BasicBlock* bb_;
+    opt::BasicBlock* bb_;
 
     // Vector of operands for every predecessor block of |bb|.  This vector is
     // organized so that the Ith slot contains the argument coming from the Ith
@@ -117,21 +117,21 @@
   };
 
   // Type used to keep track of store operations in each basic block.
-  typedef std::unordered_map<ir::BasicBlock*,
+  typedef std::unordered_map<opt::BasicBlock*,
                              std::unordered_map<uint32_t, uint32_t>>
       BlockDefsMap;
 
   // Generates all the SSA rewriting decisions for basic block |bb|.  This
   // populates the Phi candidate table (|phi_candidate_|) and the load
   // replacement table (|load_replacement_).
-  void GenerateSSAReplacements(ir::BasicBlock* bb);
+  void GenerateSSAReplacements(opt::BasicBlock* bb);
 
   // Seals block |bb|.  Sealing a basic block means |bb| and all its
   // predecessors of |bb| have been scanned for loads/stores.
-  void SealBlock(ir::BasicBlock* bb);
+  void SealBlock(opt::BasicBlock* bb);
 
   // Returns true if |bb| has been sealed.
-  bool IsBlockSealed(ir::BasicBlock* bb) {
+  bool IsBlockSealed(opt::BasicBlock* bb) {
     return sealed_blocks_.count(bb) != 0;
   }
 
@@ -183,7 +183,7 @@
 
   // Registers a definition for variable |var_id| in basic block |bb| with
   // value |val_id|.
-  void WriteVariable(uint32_t var_id, ir::BasicBlock* bb, uint32_t val_id) {
+  void WriteVariable(uint32_t var_id, opt::BasicBlock* bb, uint32_t val_id) {
     defs_at_block_[bb][var_id] = val_id;
   }
 
@@ -191,13 +191,13 @@
   // the variable ID being stored into, determines whether the variable is an
   // SSA-target variable, and, if it is, it stores its value in the
   // |defs_at_block_| map.
-  void ProcessStore(ir::Instruction* inst, ir::BasicBlock* bb);
+  void ProcessStore(opt::Instruction* inst, opt::BasicBlock* bb);
 
   // Processes the load operation |inst| in basic block |bb|. This extracts
   // the variable ID being stored into, determines whether the variable is an
   // SSA-target variable, and, if it is, it reads its reaching definition by
   // calling |GetReachingDef|.
-  void ProcessLoad(ir::Instruction* inst, ir::BasicBlock* bb);
+  void ProcessLoad(opt::Instruction* inst, opt::BasicBlock* bb);
 
   // Reads the current definition for variable |var_id| in basic block |bb|.
   // If |var_id| is not defined in block |bb| it walks up the predecessors of
@@ -205,7 +205,7 @@
   //
   // It returns the value for |var_id| from the RHS of the current reaching
   // definition for |var_id|.
-  uint32_t GetReachingDef(uint32_t var_id, ir::BasicBlock* bb);
+  uint32_t GetReachingDef(uint32_t var_id, opt::BasicBlock* bb);
 
   // Adds arguments to |phi_candidate| by getting the reaching definition of
   // |phi_candidate|'s variable on each of the predecessors of its basic
@@ -223,7 +223,7 @@
   // during rewriting.
   //
   // Once the candidate Phi is created, it returns its ID.
-  PhiCandidate& CreatePhiCandidate(uint32_t var_id, ir::BasicBlock* bb);
+  PhiCandidate& CreatePhiCandidate(uint32_t var_id, opt::BasicBlock* bb);
 
   // Attempts to remove a trivial Phi candidate |phi_cand|. Trivial Phis are
   // those that only reference themselves and one other value |val| any number
@@ -277,7 +277,7 @@
   std::unordered_map<uint32_t, uint32_t> load_replacement_;
 
   // Set of blocks that have been sealed already.
-  std::unordered_set<ir::BasicBlock*> sealed_blocks_;
+  std::unordered_set<opt::BasicBlock*> sealed_blocks_;
 
   // Memory pass requesting the SSA rewriter.
   MemPass* pass_;
@@ -291,11 +291,11 @@
  public:
   SSARewritePass() = default;
   const char* name() const override { return "ssa-rewrite"; }
-  Status Process(ir::IRContext* c) override;
+  Status Process(opt::IRContext* c) override;
 
  private:
   // Initializes the pass.
-  void Initialize(ir::IRContext* c);
+  void Initialize(opt::IRContext* c);
 };
 
 }  // namespace opt
diff --git a/source/opt/strength_reduction_pass.cpp b/source/opt/strength_reduction_pass.cpp
index fd8ccf9..75b98ea 100644
--- a/source/opt/strength_reduction_pass.cpp
+++ b/source/opt/strength_reduction_pass.cpp
@@ -53,7 +53,7 @@
 namespace spvtools {
 namespace opt {
 
-Pass::Status StrengthReductionPass::Process(ir::IRContext* c) {
+Pass::Status StrengthReductionPass::Process(opt::IRContext* c) {
   InitializeProcessing(c);
 
   // Initialize the member variables on a per module basis.
@@ -68,7 +68,7 @@
 }
 
 bool StrengthReductionPass::ReplaceMultiplyByPowerOf2(
-    ir::BasicBlock::iterator* inst) {
+    opt::BasicBlock::iterator* inst) {
   assert((*inst)->opcode() == SpvOp::SpvOpIMul &&
          "Only works for multiplication of integers.");
   bool modified = false;
@@ -82,7 +82,7 @@
   // Check the operands for a constant that is a power of 2.
   for (int i = 0; i < 2; i++) {
     uint32_t opId = (*inst)->GetSingleWordInOperand(i);
-    ir::Instruction* opInst = get_def_use_mgr()->GetDef(opId);
+    opt::Instruction* opInst = get_def_use_mgr()->GetDef(opId);
     if (opInst->opcode() == SpvOp::SpvOpConstant) {
       // We found a constant operand.
       uint32_t constVal = opInst->GetSingleWordOperand(2);
@@ -94,14 +94,14 @@
 
         // Create the new instruction.
         uint32_t newResultId = TakeNextId();
-        std::vector<ir::Operand> newOperands;
+        std::vector<opt::Operand> newOperands;
         newOperands.push_back((*inst)->GetInOperand(1 - i));
-        ir::Operand shiftOperand(spv_operand_type_t::SPV_OPERAND_TYPE_ID,
-                                 {shiftConstResultId});
+        opt::Operand shiftOperand(spv_operand_type_t::SPV_OPERAND_TYPE_ID,
+                                  {shiftConstResultId});
         newOperands.push_back(shiftOperand);
-        std::unique_ptr<ir::Instruction> newInstruction(
-            new ir::Instruction(context(), SpvOp::SpvOpShiftLeftLogical,
-                                (*inst)->type_id(), newResultId, newOperands));
+        std::unique_ptr<opt::Instruction> newInstruction(
+            new opt::Instruction(context(), SpvOp::SpvOpShiftLeftLogical,
+                                 (*inst)->type_id(), newResultId, newOperands));
 
         // Insert the new instruction and update the data structures.
         (*inst) = (*inst).InsertBefore(std::move(newInstruction));
@@ -110,7 +110,7 @@
         context()->ReplaceAllUsesWith((*inst)->result_id(), newResultId);
 
         // Remove the old instruction.
-        ir::Instruction* inst_to_delete = &*(*inst);
+        opt::Instruction* inst_to_delete = &*(*inst);
         --(*inst);
         context()->KillInst(inst_to_delete);
 
@@ -156,11 +156,11 @@
 
     // Construct the constant.
     uint32_t resultId = TakeNextId();
-    ir::Operand constant(spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER,
-                         {val});
-    std::unique_ptr<ir::Instruction> newConstant(
-        new ir::Instruction(context(), SpvOp::SpvOpConstant, uint32_type_id_,
-                            resultId, {constant}));
+    opt::Operand constant(spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER,
+                          {val});
+    std::unique_ptr<opt::Instruction> newConstant(
+        new opt::Instruction(context(), SpvOp::SpvOpConstant, uint32_type_id_,
+                             resultId, {constant}));
     get_module()->AddGlobalValue(std::move(newConstant));
 
     // Notify the DefUseManager about this constant.
diff --git a/source/opt/strength_reduction_pass.h b/source/opt/strength_reduction_pass.h
index 6c233e1..d5f0c88 100644
--- a/source/opt/strength_reduction_pass.h
+++ b/source/opt/strength_reduction_pass.h
@@ -27,12 +27,12 @@
 class StrengthReductionPass : public Pass {
  public:
   const char* name() const override { return "strength-reduction"; }
-  Status Process(ir::IRContext*) override;
+  Status Process(opt::IRContext*) override;
 
  private:
   // Replaces multiple by power of 2 with an equivalent bit shift.
   // Returns true if something changed.
-  bool ReplaceMultiplyByPowerOf2(ir::BasicBlock::iterator*);
+  bool ReplaceMultiplyByPowerOf2(opt::BasicBlock::iterator*);
 
   // Scan the types and constants in the module looking for the the integer
   // types that we are
diff --git a/source/opt/strip_debug_info_pass.cpp b/source/opt/strip_debug_info_pass.cpp
index ae35b10..93e71ef 100644
--- a/source/opt/strip_debug_info_pass.cpp
+++ b/source/opt/strip_debug_info_pass.cpp
@@ -18,13 +18,13 @@
 namespace spvtools {
 namespace opt {
 
-Pass::Status StripDebugInfoPass::Process(ir::IRContext* irContext) {
+Pass::Status StripDebugInfoPass::Process(opt::IRContext* irContext) {
   bool modified = !irContext->debugs1().empty() ||
                   !irContext->debugs2().empty() ||
                   !irContext->debugs3().empty();
   irContext->debug_clear();
 
-  irContext->module()->ForEachInst([&modified](ir::Instruction* inst) {
+  irContext->module()->ForEachInst([&modified](opt::Instruction* inst) {
     modified |= !inst->dbg_line_insts().empty();
     inst->dbg_line_insts().clear();
   });
diff --git a/source/opt/strip_debug_info_pass.h b/source/opt/strip_debug_info_pass.h
index 52cbd68..beb7889 100644
--- a/source/opt/strip_debug_info_pass.h
+++ b/source/opt/strip_debug_info_pass.h
@@ -26,7 +26,7 @@
 class StripDebugInfoPass : public Pass {
  public:
   const char* name() const override { return "strip-debug"; }
-  Status Process(ir::IRContext* irContext) override;
+  Status Process(opt::IRContext* irContext) override;
 };
 
 }  // namespace opt
diff --git a/source/opt/strip_reflect_info_pass.cpp b/source/opt/strip_reflect_info_pass.cpp
index 3c6d794..993c040 100644
--- a/source/opt/strip_reflect_info_pass.cpp
+++ b/source/opt/strip_reflect_info_pass.cpp
@@ -22,9 +22,9 @@
 namespace spvtools {
 namespace opt {
 
-using ir::Instruction;
+using opt::Instruction;
 
-Pass::Status StripReflectInfoPass::Process(ir::IRContext* irContext) {
+Pass::Status StripReflectInfoPass::Process(opt::IRContext* irContext) {
   bool modified = false;
 
   std::vector<Instruction*> to_remove;
diff --git a/source/opt/strip_reflect_info_pass.h b/source/opt/strip_reflect_info_pass.h
index b6e9f33..7edfe26 100644
--- a/source/opt/strip_reflect_info_pass.h
+++ b/source/opt/strip_reflect_info_pass.h
@@ -26,15 +26,15 @@
 class StripReflectInfoPass : public Pass {
  public:
   const char* name() const override { return "strip-reflect"; }
-  Status Process(ir::IRContext* irContext) override;
+  Status Process(opt::IRContext* irContext) override;
 
   // Return the mask of preserved Analyses.
-  ir::IRContext::Analysis GetPreservedAnalyses() override {
-    return ir::IRContext::kAnalysisInstrToBlockMapping |
-           ir::IRContext::kAnalysisCombinators | ir::IRContext::kAnalysisCFG |
-           ir::IRContext::kAnalysisDominatorAnalysis |
-           ir::IRContext::kAnalysisLoopAnalysis |
-           ir::IRContext::kAnalysisNameMap;
+  opt::IRContext::Analysis GetPreservedAnalyses() override {
+    return opt::IRContext::kAnalysisInstrToBlockMapping |
+           opt::IRContext::kAnalysisCombinators | opt::IRContext::kAnalysisCFG |
+           opt::IRContext::kAnalysisDominatorAnalysis |
+           opt::IRContext::kAnalysisLoopAnalysis |
+           opt::IRContext::kAnalysisNameMap;
   }
 };
 
diff --git a/source/opt/type_manager.cpp b/source/opt/type_manager.cpp
index 1e2e0cb..fa60f46 100644
--- a/source/opt/type_manager.cpp
+++ b/source/opt/type_manager.cpp
@@ -32,7 +32,7 @@
 namespace opt {
 namespace analysis {
 
-TypeManager::TypeManager(const MessageConsumer& consumer, ir::IRContext* c)
+TypeManager::TypeManager(const MessageConsumer& consumer, opt::IRContext* c)
     : consumer_(consumer), context_(c) {
   AnalyzeTypes(*c->module());
 }
@@ -61,7 +61,7 @@
   return 0;
 }
 
-void TypeManager::AnalyzeTypes(const ir::Module& module) {
+void TypeManager::AnalyzeTypes(const opt::Module& module) {
   // First pass through the types.  Any types that reference a forward pointer
   // (directly or indirectly) are incomplete, and are added to incomplete types.
   for (const auto* inst : module.GetTypes()) {
@@ -130,7 +130,7 @@
   // Add the remaining incomplete types to the type pool.
   for (auto& type : incomplete_types_) {
     if (type.type() && !type.type()->AsForwardPointer()) {
-      std::vector<ir::Instruction*> decorations =
+      std::vector<opt::Instruction*> decorations =
           context()->get_decoration_mgr()->GetDecorationsFor(type.id(), true);
       for (auto dec : decorations) {
         AttachDecoration(*dec, type.type());
@@ -200,14 +200,15 @@
   uint32_t id = GetId(type);
   if (id != 0) return id;
 
-  std::unique_ptr<ir::Instruction> typeInst;
+  std::unique_ptr<opt::Instruction> typeInst;
   id = context()->TakeNextId();
   RegisterType(id, *type);
   switch (type->kind()) {
-#define DefineParameterlessCase(kind)                                          \
-  case Type::k##kind:                                                          \
-    typeInst.reset(new ir::Instruction(context(), SpvOpType##kind, 0, id,      \
-                                       std::initializer_list<ir::Operand>{})); \
+#define DefineParameterlessCase(kind)                                 \
+  case Type::k##kind:                                                 \
+    typeInst.reset(                                                   \
+        new opt::Instruction(context(), SpvOpType##kind, 0, id,       \
+                             std::initializer_list<opt::Operand>{})); \
     break;
     DefineParameterlessCase(Void);
     DefineParameterlessCase(Bool);
@@ -220,45 +221,45 @@
     DefineParameterlessCase(NamedBarrier);
 #undef DefineParameterlessCase
     case Type::kInteger:
-      typeInst.reset(new ir::Instruction(
+      typeInst.reset(new opt::Instruction(
           context(), SpvOpTypeInt, 0, id,
-          std::initializer_list<ir::Operand>{
+          std::initializer_list<opt::Operand>{
               {SPV_OPERAND_TYPE_LITERAL_INTEGER, {type->AsInteger()->width()}},
               {SPV_OPERAND_TYPE_LITERAL_INTEGER,
                {(type->AsInteger()->IsSigned() ? 1u : 0u)}}}));
       break;
     case Type::kFloat:
-      typeInst.reset(new ir::Instruction(
+      typeInst.reset(new opt::Instruction(
           context(), SpvOpTypeFloat, 0, id,
-          std::initializer_list<ir::Operand>{
+          std::initializer_list<opt::Operand>{
               {SPV_OPERAND_TYPE_LITERAL_INTEGER, {type->AsFloat()->width()}}}));
       break;
     case Type::kVector: {
       uint32_t subtype = GetTypeInstruction(type->AsVector()->element_type());
       typeInst.reset(
-          new ir::Instruction(context(), SpvOpTypeVector, 0, id,
-                              std::initializer_list<ir::Operand>{
-                                  {SPV_OPERAND_TYPE_ID, {subtype}},
-                                  {SPV_OPERAND_TYPE_LITERAL_INTEGER,
-                                   {type->AsVector()->element_count()}}}));
+          new opt::Instruction(context(), SpvOpTypeVector, 0, id,
+                               std::initializer_list<opt::Operand>{
+                                   {SPV_OPERAND_TYPE_ID, {subtype}},
+                                   {SPV_OPERAND_TYPE_LITERAL_INTEGER,
+                                    {type->AsVector()->element_count()}}}));
       break;
     }
     case Type::kMatrix: {
       uint32_t subtype = GetTypeInstruction(type->AsMatrix()->element_type());
       typeInst.reset(
-          new ir::Instruction(context(), SpvOpTypeMatrix, 0, id,
-                              std::initializer_list<ir::Operand>{
-                                  {SPV_OPERAND_TYPE_ID, {subtype}},
-                                  {SPV_OPERAND_TYPE_LITERAL_INTEGER,
-                                   {type->AsMatrix()->element_count()}}}));
+          new opt::Instruction(context(), SpvOpTypeMatrix, 0, id,
+                               std::initializer_list<opt::Operand>{
+                                   {SPV_OPERAND_TYPE_ID, {subtype}},
+                                   {SPV_OPERAND_TYPE_LITERAL_INTEGER,
+                                    {type->AsMatrix()->element_count()}}}));
       break;
     }
     case Type::kImage: {
       const Image* image = type->AsImage();
       uint32_t subtype = GetTypeInstruction(image->sampled_type());
-      typeInst.reset(new ir::Instruction(
+      typeInst.reset(new opt::Instruction(
           context(), SpvOpTypeImage, 0, id,
-          std::initializer_list<ir::Operand>{
+          std::initializer_list<opt::Operand>{
               {SPV_OPERAND_TYPE_ID, {subtype}},
               {SPV_OPERAND_TYPE_DIMENSIONALITY,
                {static_cast<uint32_t>(image->dim())}},
@@ -278,16 +279,16 @@
       uint32_t subtype =
           GetTypeInstruction(type->AsSampledImage()->image_type());
       typeInst.reset(
-          new ir::Instruction(context(), SpvOpTypeSampledImage, 0, id,
-                              std::initializer_list<ir::Operand>{
-                                  {SPV_OPERAND_TYPE_ID, {subtype}}}));
+          new opt::Instruction(context(), SpvOpTypeSampledImage, 0, id,
+                               std::initializer_list<opt::Operand>{
+                                   {SPV_OPERAND_TYPE_ID, {subtype}}}));
       break;
     }
     case Type::kArray: {
       uint32_t subtype = GetTypeInstruction(type->AsArray()->element_type());
-      typeInst.reset(new ir::Instruction(
+      typeInst.reset(new opt::Instruction(
           context(), SpvOpTypeArray, 0, id,
-          std::initializer_list<ir::Operand>{
+          std::initializer_list<opt::Operand>{
               {SPV_OPERAND_TYPE_ID, {subtype}},
               {SPV_OPERAND_TYPE_ID, {type->AsArray()->LengthId()}}}));
       break;
@@ -296,20 +297,20 @@
       uint32_t subtype =
           GetTypeInstruction(type->AsRuntimeArray()->element_type());
       typeInst.reset(
-          new ir::Instruction(context(), SpvOpTypeRuntimeArray, 0, id,
-                              std::initializer_list<ir::Operand>{
-                                  {SPV_OPERAND_TYPE_ID, {subtype}}}));
+          new opt::Instruction(context(), SpvOpTypeRuntimeArray, 0, id,
+                               std::initializer_list<opt::Operand>{
+                                   {SPV_OPERAND_TYPE_ID, {subtype}}}));
       break;
     }
     case Type::kStruct: {
-      std::vector<ir::Operand> ops;
+      std::vector<opt::Operand> ops;
       const Struct* structTy = type->AsStruct();
       for (auto ty : structTy->element_types()) {
         ops.push_back(
-            ir::Operand(SPV_OPERAND_TYPE_ID, {GetTypeInstruction(ty)}));
+            opt::Operand(SPV_OPERAND_TYPE_ID, {GetTypeInstruction(ty)}));
       }
       typeInst.reset(
-          new ir::Instruction(context(), SpvOpTypeStruct, 0, id, ops));
+          new opt::Instruction(context(), SpvOpTypeStruct, 0, id, ops));
       break;
     }
     case Type::kOpaque: {
@@ -320,46 +321,46 @@
       char* dst = reinterpret_cast<char*>(words.data());
       strncpy(dst, opaque->name().c_str(), size);
       typeInst.reset(
-          new ir::Instruction(context(), SpvOpTypeOpaque, 0, id,
-                              std::initializer_list<ir::Operand>{
-                                  {SPV_OPERAND_TYPE_LITERAL_STRING, words}}));
+          new opt::Instruction(context(), SpvOpTypeOpaque, 0, id,
+                               std::initializer_list<opt::Operand>{
+                                   {SPV_OPERAND_TYPE_LITERAL_STRING, words}}));
       break;
     }
     case Type::kPointer: {
       const Pointer* pointer = type->AsPointer();
       uint32_t subtype = GetTypeInstruction(pointer->pointee_type());
-      typeInst.reset(new ir::Instruction(
+      typeInst.reset(new opt::Instruction(
           context(), SpvOpTypePointer, 0, id,
-          std::initializer_list<ir::Operand>{
+          std::initializer_list<opt::Operand>{
               {SPV_OPERAND_TYPE_STORAGE_CLASS,
                {static_cast<uint32_t>(pointer->storage_class())}},
               {SPV_OPERAND_TYPE_ID, {subtype}}}));
       break;
     }
     case Type::kFunction: {
-      std::vector<ir::Operand> ops;
+      std::vector<opt::Operand> ops;
       const Function* function = type->AsFunction();
-      ops.push_back(ir::Operand(SPV_OPERAND_TYPE_ID,
-                                {GetTypeInstruction(function->return_type())}));
+      ops.push_back(opt::Operand(
+          SPV_OPERAND_TYPE_ID, {GetTypeInstruction(function->return_type())}));
       for (auto ty : function->param_types()) {
         ops.push_back(
-            ir::Operand(SPV_OPERAND_TYPE_ID, {GetTypeInstruction(ty)}));
+            opt::Operand(SPV_OPERAND_TYPE_ID, {GetTypeInstruction(ty)}));
       }
       typeInst.reset(
-          new ir::Instruction(context(), SpvOpTypeFunction, 0, id, ops));
+          new opt::Instruction(context(), SpvOpTypeFunction, 0, id, ops));
       break;
     }
     case Type::kPipe:
-      typeInst.reset(new ir::Instruction(
+      typeInst.reset(new opt::Instruction(
           context(), SpvOpTypePipe, 0, id,
-          std::initializer_list<ir::Operand>{
+          std::initializer_list<opt::Operand>{
               {SPV_OPERAND_TYPE_ACCESS_QUALIFIER,
                {static_cast<uint32_t>(type->AsPipe()->access_qualifier())}}}));
       break;
     case Type::kForwardPointer:
-      typeInst.reset(new ir::Instruction(
+      typeInst.reset(new opt::Instruction(
           context(), SpvOpTypeForwardPointer, 0, 0,
-          std::initializer_list<ir::Operand>{
+          std::initializer_list<opt::Operand>{
               {SPV_OPERAND_TYPE_ID, {type->AsForwardPointer()->target_id()}},
               {SPV_OPERAND_TYPE_STORAGE_CLASS,
                {static_cast<uint32_t>(
@@ -385,10 +386,10 @@
   }
 
   // Ambiguous type, do a linear search.
-  ir::Module::inst_iterator type_itr =
+  opt::Module::inst_iterator type_itr =
       context()->module()->types_values_begin();
   for (; type_itr != context()->module()->types_values_end(); ++type_itr) {
-    const ir::Instruction* type_inst = &*type_itr;
+    const opt::Instruction* type_inst = &*type_itr;
     if (type_inst->opcode() == SpvOpTypePointer &&
         type_inst->GetSingleWordOperand(kSpvTypePointerTypeIdInIdx) ==
             type_id &&
@@ -399,7 +400,7 @@
 
   // Must create the pointer type.
   uint32_t resultId = context()->TakeNextId();
-  std::unique_ptr<ir::Instruction> type_inst(new ir::Instruction(
+  std::unique_ptr<opt::Instruction> type_inst(new opt::Instruction(
       context(), SpvOpTypePointer, 0, resultId,
       {{spv_operand_type_t::SPV_OPERAND_TYPE_STORAGE_CLASS,
         {uint32_t(storage_class)}},
@@ -426,20 +427,20 @@
 void TypeManager::CreateDecoration(uint32_t target,
                                    const std::vector<uint32_t>& decoration,
                                    uint32_t element) {
-  std::vector<ir::Operand> ops;
-  ops.push_back(ir::Operand(SPV_OPERAND_TYPE_ID, {target}));
+  std::vector<opt::Operand> ops;
+  ops.push_back(opt::Operand(SPV_OPERAND_TYPE_ID, {target}));
   if (element != 0) {
-    ops.push_back(ir::Operand(SPV_OPERAND_TYPE_LITERAL_INTEGER, {element}));
+    ops.push_back(opt::Operand(SPV_OPERAND_TYPE_LITERAL_INTEGER, {element}));
   }
-  ops.push_back(ir::Operand(SPV_OPERAND_TYPE_DECORATION, {decoration[0]}));
+  ops.push_back(opt::Operand(SPV_OPERAND_TYPE_DECORATION, {decoration[0]}));
   for (size_t i = 1; i < decoration.size(); ++i) {
     ops.push_back(
-        ir::Operand(SPV_OPERAND_TYPE_LITERAL_INTEGER, {decoration[i]}));
+        opt::Operand(SPV_OPERAND_TYPE_LITERAL_INTEGER, {decoration[i]}));
   }
-  context()->AddAnnotationInst(MakeUnique<ir::Instruction>(
+  context()->AddAnnotationInst(MakeUnique<opt::Instruction>(
       context(), (element == 0 ? SpvOpDecorate : SpvOpMemberDecorate), 0, 0,
       ops));
-  ir::Instruction* inst = &*--context()->annotation_end();
+  opt::Instruction* inst = &*--context()->annotation_end();
   context()->get_def_use_mgr()->AnalyzeInstUse(inst);
 }
 
@@ -590,8 +591,8 @@
   return GetType(id);
 }
 
-Type* TypeManager::RecordIfTypeDefinition(const ir::Instruction& inst) {
-  if (!ir::IsTypeInst(inst.opcode())) return nullptr;
+Type* TypeManager::RecordIfTypeDefinition(const opt::Instruction& inst) {
+  if (!opt::IsTypeInst(inst.opcode())) return nullptr;
 
   Type* type = nullptr;
   switch (inst.opcode()) {
@@ -751,7 +752,7 @@
   SPIRV_ASSERT(consumer_, id != 0, "instruction without result id found");
   SPIRV_ASSERT(consumer_, type != nullptr,
                "type should not be nullptr at this point");
-  std::vector<ir::Instruction*> decorations =
+  std::vector<opt::Instruction*> decorations =
       context()->get_decoration_mgr()->GetDecorationsFor(id, true);
   for (auto dec : decorations) {
     AttachDecoration(*dec, type);
@@ -763,9 +764,9 @@
   return type;
 }
 
-void TypeManager::AttachDecoration(const ir::Instruction& inst, Type* type) {
+void TypeManager::AttachDecoration(const opt::Instruction& inst, Type* type) {
   const SpvOp opcode = inst.opcode();
-  if (!ir::IsAnnotationInst(opcode)) return;
+  if (!opt::IsAnnotationInst(opcode)) return;
 
   switch (opcode) {
     case SpvOpDecorate: {
diff --git a/source/opt/type_manager.h b/source/opt/type_manager.h
index ade26aa..358ef93 100644
--- a/source/opt/type_manager.h
+++ b/source/opt/type_manager.h
@@ -25,11 +25,10 @@
 #include "types.h"
 
 namespace spvtools {
-namespace ir {
-class IRContext;
-}  // namespace ir
-
 namespace opt {
+
+class IRContext;
+
 namespace analysis {
 
 // Hashing functor.
@@ -76,7 +75,7 @@
   // will be communicated to the outside via the given message |consumer|.
   // This instance only keeps a reference to the |consumer|, so the |consumer|
   // should outlive this instance.
-  TypeManager(const MessageConsumer& consumer, ir::IRContext* c);
+  TypeManager(const MessageConsumer& consumer, opt::IRContext* c);
 
   TypeManager(const TypeManager&) = delete;
   TypeManager(TypeManager&&) = delete;
@@ -162,9 +161,9 @@
   using IdToUnresolvedType = std::vector<UnresolvedType>;
 
   // Analyzes the types and decorations on types in the given |module|.
-  void AnalyzeTypes(const ir::Module& module);
+  void AnalyzeTypes(const opt::Module& module);
 
-  ir::IRContext* context() { return context_; }
+  opt::IRContext* context() { return context_; }
 
   // Attaches the decorations on |type| to |id|.
   void AttachDecorations(uint32_t id, const Type* type);
@@ -179,11 +178,11 @@
 
   // Creates and returns a type from the given SPIR-V |inst|. Returns nullptr if
   // the given instruction is not for defining a type.
-  Type* RecordIfTypeDefinition(const ir::Instruction& inst);
+  Type* RecordIfTypeDefinition(const opt::Instruction& inst);
   // Attaches the decoration encoded in |inst| to |type|. Does nothing if the
   // given instruction is not a decoration instruction. Assumes the target is
   // |type| (e.g. should be called in loop of |type|'s decorations).
-  void AttachDecoration(const ir::Instruction& inst, Type* type);
+  void AttachDecoration(const opt::Instruction& inst, Type* type);
 
   // Returns an equivalent pointer to |type| built in terms of pointers owned by
   // |type_pool_|. For example, if |type| is a vec3 of bool, it will be rebuilt
@@ -199,7 +198,7 @@
   void ReplaceType(Type* new_type, Type* original_type);
 
   const MessageConsumer& consumer_;  // Message consumer.
-  ir::IRContext* context_;
+  opt::IRContext* context_;
   IdToTypeMap id_to_type_;  // Mapping from ids to their type representations.
   TypeToIdMap type_to_id_;  // Mapping from types to their defining ids.
   TypePool type_pool_;      // Memory owner of type pointers.
diff --git a/source/opt/unify_const_pass.cpp b/source/opt/unify_const_pass.cpp
index 2667573..8337f2e 100644
--- a/source/opt/unify_const_pass.cpp
+++ b/source/opt/unify_const_pass.cpp
@@ -39,7 +39,7 @@
   // is found, creates a trie node with those keys, stores the instruction's
   // result id and returns that result id. If an existing result id is found,
   // returns the existing result id.
-  uint32_t LookupEquivalentResultFor(const ir::Instruction& inst) {
+  uint32_t LookupEquivalentResultFor(const opt::Instruction& inst) {
     auto keys = GetLookUpKeys(inst);
     auto* node = root_.get();
     for (uint32_t key : keys) {
@@ -85,7 +85,7 @@
 
   // Returns a vector of the opcode followed by the words in the raw SPIR-V
   // instruction encoding but without the result id.
-  std::vector<uint32_t> GetLookUpKeys(const ir::Instruction& inst) {
+  std::vector<uint32_t> GetLookUpKeys(const opt::Instruction& inst) {
     std::vector<uint32_t> keys;
     // Need to use the opcode, otherwise there might be a conflict with the
     // following case when <op>'s binary value equals xx's id:
@@ -103,12 +103,14 @@
 };
 }  // anonymous namespace
 
-Pass::Status UnifyConstantPass::Process(ir::IRContext* c) {
+Pass::Status UnifyConstantPass::Process(opt::IRContext* c) {
   InitializeProcessing(c);
   bool modified = false;
   ResultIdTrie defined_constants;
 
-  for( ir::Instruction* next_instruction, *inst = &*(context()->types_values_begin()); inst; inst = next_instruction) {
+  for (opt::Instruction *next_instruction,
+       *inst = &*(context()->types_values_begin());
+       inst; inst = next_instruction) {
     next_instruction = inst->NextNode();
 
     // Do not handle the instruction when there are decorations upon the result
diff --git a/source/opt/unify_const_pass.h b/source/opt/unify_const_pass.h
index 6483817..2f82c4f 100644
--- a/source/opt/unify_const_pass.h
+++ b/source/opt/unify_const_pass.h
@@ -26,7 +26,7 @@
 class UnifyConstantPass : public Pass {
  public:
   const char* name() const override { return "unify-const"; }
-  Status Process(ir::IRContext*) override;
+  Status Process(opt::IRContext*) override;
 };
 
 }  // namespace opt
diff --git a/source/opt/value_number_table.cpp b/source/opt/value_number_table.cpp
index 5c121a5..c78f23e 100644
--- a/source/opt/value_number_table.cpp
+++ b/source/opt/value_number_table.cpp
@@ -22,7 +22,7 @@
 namespace spvtools {
 namespace opt {
 
-uint32_t ValueNumberTable::GetValueNumber(ir::Instruction* inst) const {
+uint32_t ValueNumberTable::GetValueNumber(opt::Instruction* inst) const {
   assert(inst->result_id() != 0 &&
          "inst must have a result id to get a value number.");
 
@@ -38,7 +38,7 @@
   return GetValueNumber(context()->get_def_use_mgr()->GetDef(id));
 }
 
-uint32_t ValueNumberTable::AssignValueNumber(ir::Instruction* inst) {
+uint32_t ValueNumberTable::AssignValueNumber(opt::Instruction* inst) {
   // If it already has a value return that.
   uint32_t value = GetValueNumber(inst);
   if (value != 0) {
@@ -107,19 +107,19 @@
 
   // Replace all of the operands by their value number.  The sign bit will be
   // set to distinguish between an id and a value number.
-  ir::Instruction value_ins(context(), inst->opcode(), inst->type_id(),
-                            inst->result_id(), {});
+  opt::Instruction value_ins(context(), inst->opcode(), inst->type_id(),
+                             inst->result_id(), {});
   for (uint32_t o = 0; o < inst->NumInOperands(); ++o) {
-    const ir::Operand& op = inst->GetInOperand(o);
+    const opt::Operand& op = inst->GetInOperand(o);
     if (spvIsIdType(op.type)) {
       uint32_t id_value = op.words[0];
       auto use_id_to_val = id_to_value_.find(id_value);
       if (use_id_to_val != id_to_value_.end()) {
         id_value = (1 << 31) | use_id_to_val->second;
       }
-      value_ins.AddOperand(ir::Operand(op.type, {id_value}));
+      value_ins.AddOperand(opt::Operand(op.type, {id_value}));
     } else {
-      value_ins.AddOperand(ir::Operand(op.type, op.words));
+      value_ins.AddOperand(opt::Operand(op.type, op.words));
     }
   }
 
@@ -167,11 +167,11 @@
     }
   }
 
-  for (ir::Function& func : *context()->module()) {
+  for (opt::Function& func : *context()->module()) {
     // For best results we want to traverse the code in reverse post order.
     // This happens naturally because of the forward referencing rules.
-    for (ir::BasicBlock& block : func) {
-      for (ir::Instruction& inst : block) {
+    for (opt::BasicBlock& block : func) {
+      for (opt::Instruction& inst : block) {
         if (inst.result_id() != 0) {
           AssignValueNumber(&inst);
         }
@@ -180,8 +180,8 @@
   }
 }
 
-bool ComputeSameValue::operator()(const ir::Instruction& lhs,
-                                  const ir::Instruction& rhs) const {
+bool ComputeSameValue::operator()(const opt::Instruction& lhs,
+                                  const opt::Instruction& rhs) const {
   if (lhs.result_id() == 0 || rhs.result_id() == 0) {
     return false;
   }
@@ -208,7 +208,7 @@
       lhs.result_id(), rhs.result_id());
 }
 
-std::size_t ValueTableHash::operator()(const ir::Instruction& inst) const {
+std::size_t ValueTableHash::operator()(const opt::Instruction& inst) const {
   // We hash the opcode and in-operands, not the result, because we want
   // instructions that are the same except for the result to hash to the
   // same value.
diff --git a/source/opt/value_number_table.h b/source/opt/value_number_table.h
index b6f05a7..73ce596 100644
--- a/source/opt/value_number_table.h
+++ b/source/opt/value_number_table.h
@@ -20,23 +20,22 @@
 #include "instruction.h"
 
 namespace spvtools {
-namespace ir {
-class IRContext;
-}
-
 namespace opt {
 
+class IRContext;
+
 // Returns true if the two instructions compute the same value.  Used by the
 // value number table to compare two instructions.
 class ComputeSameValue {
  public:
-  bool operator()(const ir::Instruction& lhs, const ir::Instruction& rhs) const;
+  bool operator()(const opt::Instruction& lhs,
+                  const opt::Instruction& rhs) const;
 };
 
 // The hash function used in the value number table.
 class ValueTableHash {
  public:
-  std::size_t operator()(const ir::Instruction& inst) const;
+  std::size_t operator()(const opt::Instruction& inst) const;
 };
 
 // This class implements the value number analysis.  It is using a hash-based
@@ -52,20 +51,20 @@
 // the scope.
 class ValueNumberTable {
  public:
-  ValueNumberTable(ir::IRContext* ctx) : context_(ctx), next_value_number_(1) {
+  ValueNumberTable(opt::IRContext* ctx) : context_(ctx), next_value_number_(1) {
     BuildDominatorTreeValueNumberTable();
   }
 
   // Returns the value number of the value computed by |inst|.  |inst| must have
   // a result id that will hold the computed value.  If no value number has been
   // assigned to the result id, then the return value is 0.
-  uint32_t GetValueNumber(ir::Instruction* inst) const;
+  uint32_t GetValueNumber(opt::Instruction* inst) const;
 
   // Returns the value number of the value contain in |id|.  Returns 0 if it
   // has not been assigned a value number.
   uint32_t GetValueNumber(uint32_t id) const;
 
-  ir::IRContext* context() const { return context_; }
+  opt::IRContext* context() const { return context_; }
 
  private:
   // Assigns a value number to every result id in the module.
@@ -77,13 +76,13 @@
   // Assigns a new value number to the result of |inst| if it does not already
   // have one.  Return the value number for |inst|.  |inst| must have a result
   // id.
-  uint32_t AssignValueNumber(ir::Instruction* inst);
+  uint32_t AssignValueNumber(opt::Instruction* inst);
 
-  std::unordered_map<ir::Instruction, uint32_t, ValueTableHash,
+  std::unordered_map<opt::Instruction, uint32_t, ValueTableHash,
                      ComputeSameValue>
       instruction_to_value_;
   std::unordered_map<uint32_t, uint32_t> id_to_value_;
-  ir::IRContext* context_;
+  opt::IRContext* context_;
   uint32_t next_value_number_;
 };
 
diff --git a/source/opt/vector_dce.cpp b/source/opt/vector_dce.cpp
index 61eb9cf..9e46af7 100644
--- a/source/opt/vector_dce.cpp
+++ b/source/opt/vector_dce.cpp
@@ -23,23 +23,23 @@
 namespace spvtools {
 namespace opt {
 
-Pass::Status VectorDCE::Process(ir::IRContext* ctx) {
+Pass::Status VectorDCE::Process(opt::IRContext* ctx) {
   InitializeProcessing(ctx);
 
   bool modified = false;
-  for (ir::Function& function : *get_module()) {
+  for (opt::Function& function : *get_module()) {
     modified |= VectorDCEFunction(&function);
   }
   return (modified ? Status::SuccessWithChange : Status::SuccessWithoutChange);
 }
 
-bool VectorDCE::VectorDCEFunction(ir::Function* function) {
+bool VectorDCE::VectorDCEFunction(opt::Function* function) {
   LiveComponentMap live_components;
   FindLiveComponents(function, &live_components);
   return RewriteInstructions(function, live_components);
 }
 
-void VectorDCE::FindLiveComponents(ir::Function* function,
+void VectorDCE::FindLiveComponents(opt::Function* function,
                                    LiveComponentMap* live_components) {
   std::vector<WorkListItem> work_list;
 
@@ -50,7 +50,7 @@
   // the nesting.  We cannot simply us a bit vector to keep track of which
   // components are live because of arbitrary nesting of structs.
   function->ForEachInst(
-      [&work_list, this, live_components](ir::Instruction* current_inst) {
+      [&work_list, this, live_components](opt::Instruction* current_inst) {
         if (!HasVectorOrScalarResult(current_inst) ||
             !context()->IsCombinatorInstruction(current_inst)) {
           MarkUsesAsLive(current_inst, all_components_live_, live_components,
@@ -61,7 +61,7 @@
   // Process the work list propagating liveness.
   for (uint32_t i = 0; i < work_list.size(); i++) {
     WorkListItem current_item = work_list[i];
-    ir::Instruction* current_inst = current_item.instruction;
+    opt::Instruction* current_inst = current_item.instruction;
 
     switch (current_inst->opcode()) {
       case SpvOpCompositeExtract:
@@ -90,13 +90,13 @@
   }
 }
 
-void VectorDCE::MarkExtractUseAsLive(const ir::Instruction* current_inst,
+void VectorDCE::MarkExtractUseAsLive(const opt::Instruction* current_inst,
                                      LiveComponentMap* live_components,
                                      std::vector<WorkListItem>* work_list) {
   analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr();
   uint32_t operand_id =
       current_inst->GetSingleWordInOperand(kExtractCompositeIdInIdx);
-  ir::Instruction* operand_inst = def_use_mgr->GetDef(operand_id);
+  opt::Instruction* operand_inst = def_use_mgr->GetDef(operand_id);
 
   if (HasVectorOrScalarResult(operand_inst)) {
     WorkListItem new_item;
@@ -118,7 +118,7 @@
   // Add the elements of the composite object that are used.
   uint32_t operand_id =
       current_item.instruction->GetSingleWordInOperand(kInsertCompositeIdInIdx);
-  ir::Instruction* operand_inst = def_use_mgr->GetDef(operand_id);
+  opt::Instruction* operand_inst = def_use_mgr->GetDef(operand_id);
 
   WorkListItem new_item;
   new_item.instruction = operand_inst;
@@ -131,7 +131,7 @@
   if (current_item.components.Get(insert_position)) {
     uint32_t obj_operand_id =
         current_item.instruction->GetSingleWordInOperand(kInsertObjectIdInIdx);
-    ir::Instruction* obj_operand_inst = def_use_mgr->GetDef(obj_operand_id);
+    opt::Instruction* obj_operand_inst = def_use_mgr->GetDef(obj_operand_id);
     WorkListItem new_item_for_obj;
     new_item_for_obj.instruction = obj_operand_inst;
     new_item_for_obj.components.Set(0);
@@ -181,11 +181,11 @@
   analysis::TypeManager* type_mgr = context()->get_type_mgr();
 
   uint32_t current_component = 0;
-  ir::Instruction* current_inst = work_item.instruction;
+  opt::Instruction* current_inst = work_item.instruction;
   uint32_t num_in_operands = current_inst->NumInOperands();
   for (uint32_t i = 0; i < num_in_operands; ++i) {
     uint32_t id = current_inst->GetSingleWordInOperand(i);
-    ir::Instruction* op_inst = def_use_mgr->GetDef(id);
+    opt::Instruction* op_inst = def_use_mgr->GetDef(id);
 
     if (HasScalarResult(op_inst)) {
       WorkListItem new_work_item;
@@ -214,14 +214,14 @@
 }
 
 void VectorDCE::MarkUsesAsLive(
-    ir::Instruction* current_inst, const utils::BitVector& live_elements,
+    opt::Instruction* current_inst, const utils::BitVector& live_elements,
     LiveComponentMap* live_components,
     std::vector<VectorDCE::WorkListItem>* work_list) {
   analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr();
 
   current_inst->ForEachInId([&work_list, &live_elements, this, live_components,
                              def_use_mgr](uint32_t* operand_id) {
-    ir::Instruction* operand_inst = def_use_mgr->GetDef(*operand_id);
+    opt::Instruction* operand_inst = def_use_mgr->GetDef(*operand_id);
 
     if (HasVectorResult(operand_inst)) {
       WorkListItem new_item;
@@ -237,11 +237,11 @@
   });
 }
 
-bool VectorDCE::HasVectorOrScalarResult(const ir::Instruction* inst) const {
+bool VectorDCE::HasVectorOrScalarResult(const opt::Instruction* inst) const {
   return HasScalarResult(inst) || HasVectorResult(inst);
 }
 
-bool VectorDCE::HasVectorResult(const ir::Instruction* inst) const {
+bool VectorDCE::HasVectorResult(const opt::Instruction* inst) const {
   analysis::TypeManager* type_mgr = context()->get_type_mgr();
   if (inst->type_id() == 0) {
     return false;
@@ -256,7 +256,7 @@
   }
 }
 
-bool VectorDCE::HasScalarResult(const ir::Instruction* inst) const {
+bool VectorDCE::HasScalarResult(const opt::Instruction* inst) const {
   analysis::TypeManager* type_mgr = context()->get_type_mgr();
   if (inst->type_id() == 0) {
     return false;
@@ -274,11 +274,11 @@
 }
 
 bool VectorDCE::RewriteInstructions(
-    ir::Function* function,
+    opt::Function* function,
     const VectorDCE::LiveComponentMap& live_components) {
   bool modified = false;
   function->ForEachInst(
-      [&modified, this, live_components](ir::Instruction* current_inst) {
+      [&modified, this, live_components](opt::Instruction* current_inst) {
         if (!context()->IsCombinatorInstruction(current_inst)) {
           return;
         }
@@ -321,7 +321,7 @@
 }
 
 bool VectorDCE::RewriteInsertInstruction(
-    ir::Instruction* current_inst, const utils::BitVector& live_components) {
+    opt::Instruction* current_inst, const utils::BitVector& live_components) {
   // If the value being inserted is not live, then we can skip the insert.
   bool modified = false;
   uint32_t insert_index = current_inst->GetSingleWordInOperand(2);
@@ -350,7 +350,7 @@
 void VectorDCE::AddItemToWorkListIfNeeded(
     WorkListItem work_item, VectorDCE::LiveComponentMap* live_components,
     std::vector<WorkListItem>* work_list) {
-  ir::Instruction* current_inst = work_item.instruction;
+  opt::Instruction* current_inst = work_item.instruction;
   auto it = live_components->find(current_inst->result_id());
   if (it == live_components->end()) {
     live_components->emplace(
diff --git a/source/opt/vector_dce.h b/source/opt/vector_dce.h
index 0e6aca6..feaf54a 100644
--- a/source/opt/vector_dce.h
+++ b/source/opt/vector_dce.h
@@ -32,13 +32,13 @@
   struct WorkListItem {
     WorkListItem() : instruction(nullptr), components(kMaxVectorSize) {}
 
-    ir::Instruction* instruction;
+    opt::Instruction* instruction;
     utils::BitVector components;
   };
 
  public:
   const char* name() const override { return "vector-dce"; }
-  Status Process(ir::IRContext*) override;
+  Status Process(opt::IRContext*) override;
 
   VectorDCE() : all_components_live_(kMaxVectorSize) {
     for (uint32_t i = 0; i < kMaxVectorSize; i++) {
@@ -46,29 +46,29 @@
     }
   }
 
-  ir::IRContext::Analysis GetPreservedAnalyses() override {
-    return ir::IRContext::kAnalysisDefUse | ir::IRContext::kAnalysisCFG |
-           ir::IRContext::kAnalysisInstrToBlockMapping |
-           ir::IRContext::kAnalysisLoopAnalysis |
-           ir::IRContext::kAnalysisDecorations |
-           ir::IRContext::kAnalysisDominatorAnalysis |
-           ir::IRContext::kAnalysisNameMap;
+  opt::IRContext::Analysis GetPreservedAnalyses() override {
+    return opt::IRContext::kAnalysisDefUse | opt::IRContext::kAnalysisCFG |
+           opt::IRContext::kAnalysisInstrToBlockMapping |
+           opt::IRContext::kAnalysisLoopAnalysis |
+           opt::IRContext::kAnalysisDecorations |
+           opt::IRContext::kAnalysisDominatorAnalysis |
+           opt::IRContext::kAnalysisNameMap;
   }
 
  private:
   // Runs the vector dce pass on |function|.  Returns true if |function| was
   // modified.
-  bool VectorDCEFunction(ir::Function* function);
+  bool VectorDCEFunction(opt::Function* function);
 
   // Identifies the live components of the vectors that are results of
   // instructions in |function|.  The results are stored in |live_components|.
-  void FindLiveComponents(ir::Function* function,
+  void FindLiveComponents(opt::Function* function,
                           LiveComponentMap* live_components);
 
   // Rewrites instructions in |function| that are dead or partially dead.  If an
   // instruction does not have an entry in |live_components|, then it is not
   // changed.  Returns true if |function| was modified.
-  bool RewriteInstructions(ir::Function* function,
+  bool RewriteInstructions(opt::Function* function,
                            const LiveComponentMap& live_components);
 
   // Rewrites the OpCompositeInsert instruction |current_inst| to avoid
@@ -80,17 +80,17 @@
   //
   // If the composite input to |current_inst| is not live, then it is replaced
   // by and OpUndef in |current_inst|.
-  bool RewriteInsertInstruction(ir::Instruction* current_inst,
+  bool RewriteInsertInstruction(opt::Instruction* current_inst,
                                 const utils::BitVector& live_components);
 
   // Returns true if the result of |inst| is a vector or a scalar.
-  bool HasVectorOrScalarResult(const ir::Instruction* inst) const;
+  bool HasVectorOrScalarResult(const opt::Instruction* inst) const;
 
   // Returns true if the result of |inst| is a scalar.
-  bool HasVectorResult(const ir::Instruction* inst) const;
+  bool HasVectorResult(const opt::Instruction* inst) const;
 
   // Returns true if the result of |inst| is a vector.
-  bool HasScalarResult(const ir::Instruction* inst) const;
+  bool HasScalarResult(const opt::Instruction* inst) const;
 
   // Adds |work_item| to |work_list| if it is not already live according to
   // |live_components|.  |live_components| is updated to indicate that
@@ -102,7 +102,7 @@
   // Marks the components |live_elements| of the uses in |current_inst| as live
   // according to |live_components|. If they were not live before, then they are
   // added to |work_list|.
-  void MarkUsesAsLive(ir::Instruction* current_inst,
+  void MarkUsesAsLive(opt::Instruction* current_inst,
                       const utils::BitVector& live_elements,
                       LiveComponentMap* live_components,
                       std::vector<WorkListItem>* work_list);
@@ -126,7 +126,7 @@
   // Marks the uses in the OpCompositeExtract instruction |current_inst| as
   // live. If anything becomes live they are added to |work_list| and
   // |live_components| is updated accordingly.
-  void MarkExtractUseAsLive(const ir::Instruction* current_inst,
+  void MarkExtractUseAsLive(const opt::Instruction* current_inst,
                             LiveComponentMap* live_components,
                             std::vector<WorkListItem>* work_list);
 
diff --git a/source/opt/workaround1209.cpp b/source/opt/workaround1209.cpp
index ae05848..6521473 100644
--- a/source/opt/workaround1209.cpp
+++ b/source/opt/workaround1209.cpp
@@ -20,7 +20,7 @@
 namespace spvtools {
 namespace opt {
 
-Pass::Status Workaround1209::Process(ir::IRContext* c) {
+Pass::Status Workaround1209::Process(opt::IRContext* c) {
   InitializeProcessing(c);
   bool modified = false;
   modified = RemoveOpUnreachableInLoops();
@@ -30,14 +30,14 @@
 bool Workaround1209::RemoveOpUnreachableInLoops() {
   bool modified = false;
   for (auto& func : *get_module()) {
-    std::list<ir::BasicBlock*> structured_order;
+    std::list<opt::BasicBlock*> structured_order;
     cfg()->ComputeStructuredOrder(&func, &*func.begin(), &structured_order);
 
     // Keep track of the loop merges.  The top of the stack will always be the
     // loop merge for the loop that immediately contains the basic block being
     // processed.
     std::stack<uint32_t> loop_merges;
-    for (ir::BasicBlock* bb : structured_order) {
+    for (opt::BasicBlock* bb : structured_order) {
       if (!loop_merges.empty() && bb->id() == loop_merges.top()) {
         loop_merges.pop();
       }
@@ -47,10 +47,10 @@
           // We found an OpUnreachable inside a loop.
           // Replace it with an unconditional branch to the loop merge.
           context()->KillInst(&*bb->tail());
-          std::unique_ptr<ir::Instruction> new_branch(
-              new ir::Instruction(context(), SpvOpBranch, 0, 0,
-                                  {{spv_operand_type_t::SPV_OPERAND_TYPE_ID,
-                                    {loop_merges.top()}}}));
+          std::unique_ptr<opt::Instruction> new_branch(
+              new opt::Instruction(context(), SpvOpBranch, 0, 0,
+                                   {{spv_operand_type_t::SPV_OPERAND_TYPE_ID,
+                                     {loop_merges.top()}}}));
           context()->AnalyzeDefUse(&*new_branch);
           bb->AddInstruction(std::move(new_branch));
           modified = true;
diff --git a/source/opt/workaround1209.h b/source/opt/workaround1209.h
index 2265ac3..76c0369 100644
--- a/source/opt/workaround1209.h
+++ b/source/opt/workaround1209.h
@@ -24,7 +24,7 @@
 class Workaround1209 : public Pass {
  public:
   const char* name() const override { return "workaround-1209"; }
-  Status Process(ir::IRContext*) override;
+  Status Process(opt::IRContext*) override;
 
  private:
   // There is at least one driver where an OpUnreachable found in a loop is not
diff --git a/test/opt/compact_ids_test.cpp b/test/opt/compact_ids_test.cpp
index ece670c..7eaab12 100644
--- a/test/opt/compact_ids_test.cpp
+++ b/test/opt/compact_ids_test.cpp
@@ -224,7 +224,7 @@
 )");
 
   spvtools::SpirvTools tools(SPV_ENV_UNIVERSAL_1_1);
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, input,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   ASSERT_NE(context, nullptr);
diff --git a/test/opt/constant_manager_test.cpp b/test/opt/constant_manager_test.cpp
index 7370531..799ebe8 100644
--- a/test/opt/constant_manager_test.cpp
+++ b/test/opt/constant_manager_test.cpp
@@ -32,20 +32,20 @@
 %2 = OpTypeStruct %int
   )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   ASSERT_NE(context, nullptr);
 
   Type* struct_type_1 = context->get_type_mgr()->GetType(1);
   StructConstant struct_const_1(struct_type_1->AsStruct());
-  ir::Instruction* const_inst_1 =
+  opt::Instruction* const_inst_1 =
       context->get_constant_mgr()->GetDefiningInstruction(&struct_const_1, 1);
   EXPECT_EQ(const_inst_1->type_id(), 1);
 
   Type* struct_type_2 = context->get_type_mgr()->GetType(2);
   StructConstant struct_const_2(struct_type_2->AsStruct());
-  ir::Instruction* const_inst_2 =
+  opt::Instruction* const_inst_2 =
       context->get_constant_mgr()->GetDefiningInstruction(&struct_const_2, 2);
   EXPECT_EQ(const_inst_2->type_id(), 2);
 }
diff --git a/test/opt/copy_prop_array_test.cpp b/test/opt/copy_prop_array_test.cpp
index 83eac78..97f0e84 100644
--- a/test/opt/copy_prop_array_test.cpp
+++ b/test/opt/copy_prop_array_test.cpp
@@ -22,8 +22,8 @@
 namespace {
 
 using namespace spvtools;
-using ir::Instruction;
-using ir::IRContext;
+using opt::IRContext;
+using opt::Instruction;
 using opt::PassManager;
 
 using CopyPropArrayPassTest = PassTest<::testing::Test>;
diff --git a/test/opt/decoration_manager_test.cpp b/test/opt/decoration_manager_test.cpp
index b503316..6e5dbc6 100644
--- a/test/opt/decoration_manager_test.cpp
+++ b/test/opt/decoration_manager_test.cpp
@@ -25,8 +25,8 @@
 namespace {
 
 using spvtest::MakeVector;
-using spvtools::ir::Instruction;
-using spvtools::ir::IRContext;
+using spvtools::opt::IRContext;
+using spvtools::opt::Instruction;
 using spvtools::opt::analysis::DecorationManager;
 
 class DecorationManagerTest : public ::testing::Test {
@@ -114,7 +114,7 @@
 
 TEST_F(DecorationManagerTest,
        ComparingDecorationsWithDiffOpcodesDecorateDecorateId) {
-  spvtools::ir::IRContext ir_context(SPV_ENV_UNIVERSAL_1_2, GetConsumer());
+  spvtools::opt::IRContext ir_context(SPV_ENV_UNIVERSAL_1_2, GetConsumer());
   // This parameter can be interprated both as { SpvDecorationConstant }
   // and also as a list of IDs:  { 22 }
   const std::vector<uint32_t> param{SpvDecorationConstant};
@@ -133,7 +133,7 @@
 
 TEST_F(DecorationManagerTest,
        ComparingDecorationsWithDiffOpcodesDecorateDecorateString) {
-  spvtools::ir::IRContext ir_context(SPV_ENV_UNIVERSAL_1_2, GetConsumer());
+  spvtools::opt::IRContext ir_context(SPV_ENV_UNIVERSAL_1_2, GetConsumer());
   // This parameter can be interprated both as { SpvDecorationConstant }
   // and also as a null-terminated string with a single character with value 22.
   const std::vector<uint32_t> param{SpvDecorationConstant};
@@ -151,7 +151,7 @@
 }
 
 TEST_F(DecorationManagerTest, ComparingDecorationsWithDiffDecorateParam) {
-  spvtools::ir::IRContext ir_context(SPV_ENV_UNIVERSAL_1_2, GetConsumer());
+  spvtools::opt::IRContext ir_context(SPV_ENV_UNIVERSAL_1_2, GetConsumer());
   // OpDecorate %1 Constant
   Instruction inst1(&ir_context, SpvOpDecorate, 0u, 0u,
                     {{SPV_OPERAND_TYPE_ID, {1u}},
@@ -166,7 +166,7 @@
 }
 
 TEST_F(DecorationManagerTest, ComparingDecorationsWithDiffDecorateIdParam) {
-  spvtools::ir::IRContext ir_context(SPV_ENV_UNIVERSAL_1_2, GetConsumer());
+  spvtools::opt::IRContext ir_context(SPV_ENV_UNIVERSAL_1_2, GetConsumer());
   // OpDecorate %1 Constant
   Instruction inst1(
       &ir_context, SpvOpDecorateId, 0u, 0u,
@@ -181,7 +181,7 @@
 }
 
 TEST_F(DecorationManagerTest, ComparingDecorationsWithDiffDecorateStringParam) {
-  spvtools::ir::IRContext ir_context(SPV_ENV_UNIVERSAL_1_2, GetConsumer());
+  spvtools::opt::IRContext ir_context(SPV_ENV_UNIVERSAL_1_2, GetConsumer());
   // OpDecorate %1 Constant
   Instruction inst1(&ir_context, SpvOpDecorateStringGOOGLE, 0u, 0u,
                     {{SPV_OPERAND_TYPE_ID, {1u}},
@@ -196,7 +196,7 @@
 }
 
 TEST_F(DecorationManagerTest, ComparingSameDecorationsOnDiffTargetAllowed) {
-  spvtools::ir::IRContext ir_context(SPV_ENV_UNIVERSAL_1_2, GetConsumer());
+  spvtools::opt::IRContext ir_context(SPV_ENV_UNIVERSAL_1_2, GetConsumer());
   // OpDecorate %1 Constant
   Instruction inst1(&ir_context, SpvOpDecorate, 0u, 0u,
                     {{SPV_OPERAND_TYPE_ID, {1u}},
@@ -211,7 +211,7 @@
 }
 
 TEST_F(DecorationManagerTest, ComparingSameDecorationIdsOnDiffTargetAllowed) {
-  spvtools::ir::IRContext ir_context(SPV_ENV_UNIVERSAL_1_2, GetConsumer());
+  spvtools::opt::IRContext ir_context(SPV_ENV_UNIVERSAL_1_2, GetConsumer());
   Instruction inst1(
       &ir_context, SpvOpDecorateId, 0u, 0u,
       {{SPV_OPERAND_TYPE_ID, {1u}}, {SPV_OPERAND_TYPE_DECORATION, {44}}});
@@ -225,7 +225,7 @@
 
 TEST_F(DecorationManagerTest,
        ComparingSameDecorationStringsOnDiffTargetAllowed) {
-  spvtools::ir::IRContext ir_context(SPV_ENV_UNIVERSAL_1_2, GetConsumer());
+  spvtools::opt::IRContext ir_context(SPV_ENV_UNIVERSAL_1_2, GetConsumer());
   Instruction inst1(&ir_context, SpvOpDecorateStringGOOGLE, 0u, 0u,
                     {{SPV_OPERAND_TYPE_ID, {1u}},
                      {SPV_OPERAND_TYPE_LITERAL_STRING, MakeVector("hello")}});
@@ -238,7 +238,7 @@
 }
 
 TEST_F(DecorationManagerTest, ComparingSameDecorationsOnDiffTargetDisallowed) {
-  spvtools::ir::IRContext ir_context(SPV_ENV_UNIVERSAL_1_2, GetConsumer());
+  spvtools::opt::IRContext ir_context(SPV_ENV_UNIVERSAL_1_2, GetConsumer());
   // OpDecorate %1 Constant
   Instruction inst1(&ir_context, SpvOpDecorate, 0u, 0u,
                     {{SPV_OPERAND_TYPE_ID, {1u}},
@@ -253,7 +253,7 @@
 }
 
 TEST_F(DecorationManagerTest, ComparingMemberDecorationsOnSameTypeDiffMember) {
-  spvtools::ir::IRContext ir_context(SPV_ENV_UNIVERSAL_1_2, GetConsumer());
+  spvtools::opt::IRContext ir_context(SPV_ENV_UNIVERSAL_1_2, GetConsumer());
   // OpMemberDecorate %1 0 Constant
   Instruction inst1(&ir_context, SpvOpMemberDecorate, 0u, 0u,
                     {{SPV_OPERAND_TYPE_ID, {1u}},
@@ -271,7 +271,7 @@
 
 TEST_F(DecorationManagerTest,
        ComparingSameMemberDecorationsOnDiffTargetAllowed) {
-  spvtools::ir::IRContext ir_context(SPV_ENV_UNIVERSAL_1_2, GetConsumer());
+  spvtools::opt::IRContext ir_context(SPV_ENV_UNIVERSAL_1_2, GetConsumer());
   // OpMemberDecorate %1 0 Constant
   Instruction inst1(&ir_context, SpvOpMemberDecorate, 0u, 0u,
                     {{SPV_OPERAND_TYPE_ID, {1u}},
@@ -289,7 +289,7 @@
 
 TEST_F(DecorationManagerTest,
        ComparingSameMemberDecorationsOnDiffTargetDisallowed) {
-  spvtools::ir::IRContext ir_context(SPV_ENV_UNIVERSAL_1_2, GetConsumer());
+  spvtools::opt::IRContext ir_context(SPV_ENV_UNIVERSAL_1_2, GetConsumer());
   // OpMemberDecorate %1 0 Constant
   Instruction inst1(&ir_context, SpvOpMemberDecorate, 0u, 0u,
                     {{SPV_OPERAND_TYPE_ID, {1u}},
@@ -482,7 +482,7 @@
   DecorationManager* decoManager = GetDecorationManager(spirv);
   EXPECT_THAT(GetErrorMessage(), "");
   decoManager->RemoveDecorationsFrom(
-      1u, [](const spvtools::ir::Instruction& inst) {
+      1u, [](const spvtools::opt::Instruction& inst) {
         return inst.opcode() == SpvOpDecorate &&
                inst.GetSingleWordInOperand(0u) == 3u;
       });
@@ -534,7 +534,7 @@
   DecorationManager* decoManager = GetDecorationManager(spirv);
   EXPECT_THAT(GetErrorMessage(), "");
   decoManager->RemoveDecorationsFrom(
-      1u, [](const spvtools::ir::Instruction& inst) {
+      1u, [](const spvtools::opt::Instruction& inst) {
         return inst.opcode() == SpvOpDecorate &&
                inst.GetSingleWordInOperand(0u) == 3u &&
                inst.GetSingleWordInOperand(1u) == SpvDecorationBuiltIn;
diff --git a/test/opt/def_use_test.cpp b/test/opt/def_use_test.cpp
index cdc829b..5cd62a7 100644
--- a/test/opt/def_use_test.cpp
+++ b/test/opt/def_use_test.cpp
@@ -36,10 +36,10 @@
 using spvtools::opt::analysis::DefUseManager;
 
 // Returns the number of uses of |id|.
-uint32_t NumUses(const std::unique_ptr<ir::IRContext>& context, uint32_t id) {
+uint32_t NumUses(const std::unique_ptr<opt::IRContext>& context, uint32_t id) {
   uint32_t count = 0;
   context->get_def_use_mgr()->ForEachUse(
-      id, [&count](ir::Instruction*, uint32_t) { ++count; });
+      id, [&count](opt::Instruction*, uint32_t) { ++count; });
   return count;
 }
 
@@ -47,18 +47,18 @@
 //
 // If |id| is used multiple times in a single instruction, that instruction's
 // opcode will appear a corresponding number of times.
-std::vector<SpvOp> GetUseOpcodes(const std::unique_ptr<ir::IRContext>& context,
+std::vector<SpvOp> GetUseOpcodes(const std::unique_ptr<opt::IRContext>& context,
                                  uint32_t id) {
   std::vector<SpvOp> opcodes;
   context->get_def_use_mgr()->ForEachUse(
-      id, [&opcodes](ir::Instruction* user, uint32_t) {
+      id, [&opcodes](opt::Instruction* user, uint32_t) {
         opcodes.push_back(user->opcode());
       });
   return opcodes;
 }
 
 // Disassembles the given |inst| and returns the disassembly.
-std::string DisassembleInst(ir::Instruction* inst) {
+std::string DisassembleInst(opt::Instruction* inst) {
   SpirvTools tools(SPV_ENV_UNIVERSAL_1_1);
 
   std::vector<uint32_t> binary;
@@ -103,7 +103,7 @@
   }
 }
 
-using UserMap = std::unordered_map<uint32_t, std::vector<ir::Instruction*>>;
+using UserMap = std::unordered_map<uint32_t, std::vector<opt::Instruction*>>;
 
 // Creates a mapping of all definitions to their users (except OpConstant).
 //
@@ -112,7 +112,7 @@
   UserMap userMap;
   for (uint32_t id = 0; id != idBound; ++id) {
     if (mgr->GetDef(id)) {
-      mgr->ForEachUser(id, [id, &userMap](ir::Instruction* user) {
+      mgr->ForEachUser(id, [id, &userMap](opt::Instruction* user) {
         if (user->opcode() != SpvOpConstant) {
           userMap[id].push_back(user);
         }
@@ -190,7 +190,7 @@
 
   // Build module.
   const std::vector<const char*> text = {tc.text};
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, JoinAllInsts(text),
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   ASSERT_NE(nullptr, context);
@@ -587,7 +587,7 @@
 using ReplaceUseTest = ::testing::TestWithParam<ReplaceUseCase>;
 
 // Disassembles the given |module| and returns the disassembly.
-std::string DisassembleModule(ir::Module* module) {
+std::string DisassembleModule(opt::Module* module) {
   SpirvTools tools(SPV_ENV_UNIVERSAL_1_1);
 
   std::vector<uint32_t> binary;
@@ -606,13 +606,13 @@
 
   // Build module.
   const std::vector<const char*> text = {tc.before};
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, JoinAllInsts(text),
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   ASSERT_NE(nullptr, context);
 
   // Force a re-build of def-use manager.
-  context->InvalidateAnalyses(ir::IRContext::Analysis::kAnalysisDefUse);
+  context->InvalidateAnalyses(opt::IRContext::Analysis::kAnalysisDefUse);
   (void)context->get_def_use_mgr();
 
   // Do the substitution.
@@ -961,7 +961,7 @@
 
   // Build module.
   const std::vector<const char*> text = {tc.before};
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, JoinAllInsts(text),
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   ASSERT_NE(nullptr, context);
@@ -1238,13 +1238,13 @@
       "      OpReturnValue %6 "
       "      OpFunctionEnd";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, original_text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   ASSERT_NE(nullptr, context);
 
   // Force a re-build of def-use manager.
-  context->InvalidateAnalyses(ir::IRContext::Analysis::kAnalysisDefUse);
+  context->InvalidateAnalyses(opt::IRContext::Analysis::kAnalysisDefUse);
   (void)context->get_def_use_mgr();
 
   // Do a bunch replacements.
@@ -1327,7 +1327,7 @@
   auto tc = GetParam();
 
   // Build module.
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, tc.module_text);
   ASSERT_NE(nullptr, context);
 
@@ -1370,16 +1370,16 @@
 using AnalyzeInstDefUse = ::testing::Test;
 
 TEST(AnalyzeInstDefUse, UseWithNoResultId) {
-  ir::IRContext context(SPV_ENV_UNIVERSAL_1_2, nullptr);
+  opt::IRContext context(SPV_ENV_UNIVERSAL_1_2, nullptr);
 
   // Analyze the instructions.
   opt::analysis::DefUseManager manager(context.module());
 
-  ir::Instruction label(&context, SpvOpLabel, 0, 2, {});
+  opt::Instruction label(&context, SpvOpLabel, 0, 2, {});
   manager.AnalyzeInstDefUse(&label);
 
-  ir::Instruction branch(&context, SpvOpBranch, 0, 0,
-                         {{SPV_OPERAND_TYPE_ID, {2}}});
+  opt::Instruction branch(&context, SpvOpBranch, 0, 0,
+                          {{SPV_OPERAND_TYPE_ID, {2}}});
   manager.AnalyzeInstDefUse(&branch);
   context.module()->SetIdBound(3);
 
@@ -1400,14 +1400,14 @@
   const std::string input = "%1 = OpTypeBool";
 
   // Build module.
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, input);
   ASSERT_NE(nullptr, context);
 
   // Analyze the instructions.
   opt::analysis::DefUseManager manager(context->module());
 
-  ir::Instruction newInst(context.get(), SpvOpConstantTrue, 1, 2, {});
+  opt::Instruction newInst(context.get(), SpvOpConstantTrue, 1, 2, {});
   manager.AnalyzeInstDefUse(&newInst);
 
   InstDefUse expected = {
@@ -1439,17 +1439,17 @@
   auto tc = GetParam();
 
   // Build module.
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, tc.before,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   ASSERT_NE(nullptr, context);
 
   // Force a re-build of the def-use manager.
-  context->InvalidateAnalyses(ir::IRContext::Analysis::kAnalysisDefUse);
+  context->InvalidateAnalyses(opt::IRContext::Analysis::kAnalysisDefUse);
   (void)context->get_def_use_mgr();
 
   // KillInst
-  context->module()->ForEachInst([&tc, &context](ir::Instruction* inst) {
+  context->module()->ForEachInst([&tc, &context](opt::Instruction* inst) {
     if (tc.indices_for_inst_to_kill.count(inst->result_id())) {
       context->KillInst(inst);
     }
@@ -1566,7 +1566,7 @@
   const GetAnnotationsTestCase& tc = GetParam();
 
   // Build module.
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, tc.code);
   ASSERT_NE(nullptr, context);
 
@@ -1693,14 +1693,14 @@
       // clang-format on
   };
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, JoinAllInsts(text),
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   ASSERT_NE(nullptr, context);
 
   DefUseManager* def_use_mgr = context->get_def_use_mgr();
-  ir::Instruction* def = def_use_mgr->GetDef(9);
-  ir::Instruction* use = def_use_mgr->GetDef(10);
+  opt::Instruction* def = def_use_mgr->GetDef(9);
+  opt::Instruction* use = def_use_mgr->GetDef(10);
   def->SetOpcode(SpvOpCopyObject);
   def->SetInOperands({{SPV_OPERAND_TYPE_ID, {25}}});
   context->UpdateDefUse(def);
diff --git a/test/opt/dominator_tree/common_dominators.cpp b/test/opt/dominator_tree/common_dominators.cpp
index c91499b..f557b93 100644
--- a/test/opt/dominator_tree/common_dominators.cpp
+++ b/test/opt/dominator_tree/common_dominators.cpp
@@ -59,12 +59,13 @@
 OpFunctionEnd
 )";
 
-ir::BasicBlock* GetBlock(uint32_t id, std::unique_ptr<ir::IRContext>& context) {
+opt::BasicBlock* GetBlock(uint32_t id,
+                          std::unique_ptr<opt::IRContext>& context) {
   return context->get_instr_block(context->get_def_use_mgr()->GetDef(id));
 }
 
 TEST(CommonDominatorsTest, SameBlock) {
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   EXPECT_NE(nullptr, context);
@@ -78,7 +79,7 @@
 }
 
 TEST(CommonDominatorsTest, ParentAndChild) {
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   EXPECT_NE(nullptr, context);
@@ -98,7 +99,7 @@
 }
 
 TEST(CommonDominatorsTest, BranchSplit) {
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   EXPECT_NE(nullptr, context);
@@ -115,7 +116,7 @@
 }
 
 TEST(CommonDominatorsTest, LoopContinueAndMerge) {
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   EXPECT_NE(nullptr, context);
@@ -129,7 +130,7 @@
 }
 
 TEST(CommonDominatorsTest, NoCommonDominator) {
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   EXPECT_NE(nullptr, context);
diff --git a/test/opt/dominator_tree/generated.cpp b/test/opt/dominator_tree/generated.cpp
index 181aac0..f571a43 100644
--- a/test/opt/dominator_tree/generated.cpp
+++ b/test/opt/dominator_tree/generated.cpp
@@ -43,7 +43,7 @@
 //   if x == x then
 //      x does not strictly dominate itself
 void check_dominance(const opt::DominatorAnalysisBase& dom_tree,
-                     const ir::Function* fn, uint32_t x, uint32_t y) {
+                     const opt::Function* fn, uint32_t x, uint32_t y) {
   SCOPED_TRACE("Check dominance properties for Basic Block " +
                std::to_string(x) + " and " + std::to_string(y));
   EXPECT_TRUE(dom_tree.Dominates(spvtest::GetBasicBlock(fn, x),
@@ -60,7 +60,7 @@
 
 // Check that x does not dominates y and vise versa
 void check_no_dominance(const opt::DominatorAnalysisBase& dom_tree,
-                        const ir::Function* fn, uint32_t x, uint32_t y) {
+                        const opt::Function* fn, uint32_t x, uint32_t y) {
   SCOPED_TRACE("Check no domination for Basic Block " + std::to_string(x) +
                " and " + std::to_string(y));
   EXPECT_FALSE(dom_tree.Dominates(spvtest::GetBasicBlock(fn, x),
@@ -108,14 +108,14 @@
                OpFunctionEnd
 )";
   // clang-format on
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_0, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  const ir::Function* fn = spvtest::GetFunction(module, 1);
-  const ir::BasicBlock* entry = spvtest::GetBasicBlock(fn, 10);
+  const opt::Function* fn = spvtest::GetFunction(module, 1);
+  const opt::BasicBlock* entry = spvtest::GetBasicBlock(fn, 10);
   EXPECT_EQ(entry, fn->entry().get())
       << "The entry node is not the expected one";
 
@@ -123,7 +123,7 @@
   {
     opt::DominatorAnalysis dom_tree;
     dom_tree.InitializeTree(fn);
-    const ir::CFG& cfg = *context->cfg();
+    const opt::CFG& cfg = *context->cfg();
 
     // Inspect the actual tree
     opt::DominatorTree& tree = dom_tree.GetDomTree();
@@ -155,8 +155,8 @@
     // check with some invalid inputs
     EXPECT_FALSE(dom_tree.Dominates(nullptr, entry));
     EXPECT_FALSE(dom_tree.Dominates(entry, nullptr));
-    EXPECT_FALSE(dom_tree.Dominates(static_cast<ir::BasicBlock*>(nullptr),
-                                    static_cast<ir::BasicBlock*>(nullptr)));
+    EXPECT_FALSE(dom_tree.Dominates(static_cast<opt::BasicBlock*>(nullptr),
+                                    static_cast<opt::BasicBlock*>(nullptr)));
     EXPECT_FALSE(dom_tree.Dominates(10, 1));
     EXPECT_FALSE(dom_tree.Dominates(1, 10));
     EXPECT_FALSE(dom_tree.Dominates(1, 1));
@@ -188,7 +188,7 @@
   {
     opt::PostDominatorAnalysis dom_tree;
     dom_tree.InitializeTree(fn);
-    const ir::CFG& cfg = *context->cfg();
+    const opt::CFG& cfg = *context->cfg();
 
     // Inspect the actual tree
     opt::DominatorTree& tree = dom_tree.GetDomTree();
@@ -217,8 +217,8 @@
     // check with some invalid inputs
     EXPECT_FALSE(dom_tree.Dominates(nullptr, entry));
     EXPECT_FALSE(dom_tree.Dominates(entry, nullptr));
-    EXPECT_FALSE(dom_tree.Dominates(static_cast<ir::BasicBlock*>(nullptr),
-                                    static_cast<ir::BasicBlock*>(nullptr)));
+    EXPECT_FALSE(dom_tree.Dominates(static_cast<opt::BasicBlock*>(nullptr),
+                                    static_cast<opt::BasicBlock*>(nullptr)));
     EXPECT_FALSE(dom_tree.Dominates(10, 1));
     EXPECT_FALSE(dom_tree.Dominates(1, 10));
     EXPECT_FALSE(dom_tree.Dominates(1, 1));
@@ -274,15 +274,15 @@
                OpFunctionEnd
 )";
   // clang-format on
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_0, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  const ir::Function* fn = spvtest::GetFunction(module, 1);
+  const opt::Function* fn = spvtest::GetFunction(module, 1);
 
-  const ir::BasicBlock* entry = spvtest::GetBasicBlock(fn, 8);
+  const opt::BasicBlock* entry = spvtest::GetBasicBlock(fn, 8);
   EXPECT_EQ(entry, fn->entry().get())
       << "The entry node is not the expected one";
 
@@ -290,7 +290,7 @@
   {
     opt::DominatorAnalysis dom_tree;
     dom_tree.InitializeTree(fn);
-    const ir::CFG& cfg = *context->cfg();
+    const opt::CFG& cfg = *context->cfg();
 
     // Inspect the actual tree
     opt::DominatorTree& tree = dom_tree.GetDomTree();
@@ -332,7 +332,7 @@
   {
     opt::PostDominatorAnalysis dom_tree;
     dom_tree.InitializeTree(fn);
-    const ir::CFG& cfg = *context->cfg();
+    const opt::CFG& cfg = *context->cfg();
 
     // Inspect the actual tree
     opt::DominatorTree& tree = dom_tree.GetDomTree();
@@ -395,15 +395,15 @@
                OpFunctionEnd
 )";
   // clang-format on
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_0, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  const ir::Function* fn = spvtest::GetFunction(module, 1);
+  const opt::Function* fn = spvtest::GetFunction(module, 1);
 
-  const ir::BasicBlock* entry = spvtest::GetBasicBlock(fn, 10);
+  const opt::BasicBlock* entry = spvtest::GetBasicBlock(fn, 10);
   EXPECT_EQ(entry, fn->entry().get())
       << "The entry node is not the expected one";
 
@@ -411,7 +411,7 @@
   {
     opt::DominatorAnalysis dom_tree;
     dom_tree.InitializeTree(fn);
-    const ir::CFG& cfg = *context->cfg();
+    const opt::CFG& cfg = *context->cfg();
 
     // Inspect the actual tree
     opt::DominatorTree& tree = dom_tree.GetDomTree();
@@ -466,7 +466,7 @@
       opt::DominatorTree::post_iterator node_end =
           dom_tree.GetDomTree().post_end();
       for (uint32_t id :
-           ir::make_range(node_order.rbegin(), node_order.rend())) {
+           opt::make_range(node_order.rbegin(), node_order.rend())) {
         EXPECT_NE(node_it, node_end);
         EXPECT_EQ(node_it->id(), id);
         node_it++;
@@ -480,7 +480,7 @@
       opt::DominatorTree::const_post_iterator node_end =
           dom_tree.GetDomTree().post_cend();
       for (uint32_t id :
-           ir::make_range(node_order.rbegin(), node_order.rend())) {
+           opt::make_range(node_order.rbegin(), node_order.rend())) {
         EXPECT_NE(node_it, node_end);
         EXPECT_EQ(node_it->id(), id);
         node_it++;
@@ -493,7 +493,7 @@
   {
     opt::PostDominatorAnalysis dom_tree;
     dom_tree.InitializeTree(fn);
-    const ir::CFG& cfg = *context->cfg();
+    const opt::CFG& cfg = *context->cfg();
 
     // Inspect the actual tree
     opt::DominatorTree& tree = dom_tree.GetDomTree();
@@ -548,7 +548,7 @@
       opt::DominatorTree::post_iterator node_end =
           dom_tree.GetDomTree().post_end();
       for (uint32_t id :
-           ir::make_range(node_order.rbegin(), node_order.rend())) {
+           opt::make_range(node_order.rbegin(), node_order.rend())) {
         EXPECT_NE(node_it, node_end);
         EXPECT_EQ(node_it->id(), id);
         node_it++;
@@ -562,7 +562,7 @@
       opt::DominatorTree::const_post_iterator node_end =
           dom_tree.GetDomTree().post_cend();
       for (uint32_t id :
-           ir::make_range(node_order.rbegin(), node_order.rend())) {
+           opt::make_range(node_order.rbegin(), node_order.rend())) {
         EXPECT_NE(node_it, node_end);
         EXPECT_EQ(node_it->id(), id);
         node_it++;
@@ -602,15 +602,15 @@
                OpFunctionEnd
 )";
   // clang-format on
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_0, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  const ir::Function* fn = spvtest::GetFunction(module, 1);
+  const opt::Function* fn = spvtest::GetFunction(module, 1);
 
-  const ir::BasicBlock* entry = spvtest::GetBasicBlock(fn, 10);
+  const opt::BasicBlock* entry = spvtest::GetBasicBlock(fn, 10);
   EXPECT_EQ(entry, fn->entry().get())
       << "The entry node is not the expected one";
 
@@ -618,7 +618,7 @@
   {
     opt::DominatorAnalysis dom_tree;
     dom_tree.InitializeTree(fn);
-    const ir::CFG& cfg = *context->cfg();
+    const opt::CFG& cfg = *context->cfg();
 
     // Inspect the actual tree
     opt::DominatorTree& tree = dom_tree.GetDomTree();
@@ -669,7 +669,7 @@
   {
     opt::PostDominatorAnalysis dom_tree;
     dom_tree.InitializeTree(fn);
-    const ir::CFG& cfg = *context->cfg();
+    const opt::CFG& cfg = *context->cfg();
 
     // (strict) dominance checks.
     for (uint32_t id : {10, 11, 12, 13, 14, 15})
@@ -733,22 +733,22 @@
                OpFunctionEnd
 )";
   // clang-format on
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_0, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  const ir::Function* fn = spvtest::GetFunction(module, 1);
+  const opt::Function* fn = spvtest::GetFunction(module, 1);
 
-  const ir::BasicBlock* entry = spvtest::GetBasicBlock(fn, 10);
+  const opt::BasicBlock* entry = spvtest::GetBasicBlock(fn, 10);
   EXPECT_EQ(entry, fn->entry().get())
       << "The entry node is not the expected one";
   // Check normal dominator tree
   {
     opt::DominatorAnalysis dom_tree;
     dom_tree.InitializeTree(fn);
-    const ir::CFG& cfg = *context->cfg();
+    const opt::CFG& cfg = *context->cfg();
 
     // Inspect the actual tree
     opt::DominatorTree& tree = dom_tree.GetDomTree();
@@ -783,7 +783,7 @@
   {
     opt::PostDominatorAnalysis dom_tree;
     dom_tree.InitializeTree(fn);
-    const ir::CFG& cfg = *context->cfg();
+    const opt::CFG& cfg = *context->cfg();
 
     // Inspect the actual tree
     opt::DominatorTree& tree = dom_tree.GetDomTree();
@@ -837,15 +837,15 @@
                OpFunctionEnd
 )";
   // clang-format on
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_0, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  const ir::Function* fn = spvtest::GetFunction(module, 1);
+  const opt::Function* fn = spvtest::GetFunction(module, 1);
 
-  const ir::BasicBlock* entry = spvtest::GetBasicBlock(fn, 8);
+  const opt::BasicBlock* entry = spvtest::GetBasicBlock(fn, 8);
   EXPECT_EQ(entry, fn->entry().get())
       << "The entry node is not the expected one";
 
@@ -853,7 +853,7 @@
   {
     opt::DominatorAnalysis dom_tree;
     dom_tree.InitializeTree(fn);
-    const ir::CFG& cfg = *context->cfg();
+    const opt::CFG& cfg = *context->cfg();
     // Inspect the actual tree
     opt::DominatorTree& tree = dom_tree.GetDomTree();
     EXPECT_EQ(tree.GetRoot()->bb_, cfg.pseudo_entry_block());
@@ -881,7 +881,7 @@
   {
     opt::PostDominatorAnalysis dom_tree;
     dom_tree.InitializeTree(fn);
-    const ir::CFG& cfg = *context->cfg();
+    const opt::CFG& cfg = *context->cfg();
 
     // Inspect the actual tree
     opt::DominatorTree& tree = dom_tree.GetDomTree();
diff --git a/test/opt/dominator_tree/nested_ifs.cpp b/test/opt/dominator_tree/nested_ifs.cpp
index 86b6dac..56da766 100644
--- a/test/opt/dominator_tree/nested_ifs.cpp
+++ b/test/opt/dominator_tree/nested_ifs.cpp
@@ -110,14 +110,14 @@
              OpFunctionEnd
 )";
   // clang-format on
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
 
-  const ir::Function* f = spvtest::GetFunction(module, 4);
+  const opt::Function* f = spvtest::GetFunction(module, 4);
 
   opt::DominatorAnalysis* analysis = context->GetDominatorAnalysis(f);
 
diff --git a/test/opt/dominator_tree/nested_ifs_post.cpp b/test/opt/dominator_tree/nested_ifs_post.cpp
index 6fe2f38..0cc3b8f 100644
--- a/test/opt/dominator_tree/nested_ifs_post.cpp
+++ b/test/opt/dominator_tree/nested_ifs_post.cpp
@@ -110,14 +110,14 @@
              OpFunctionEnd
 )";
   // clang-format on
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
 
-  const ir::Function* f = spvtest::GetFunction(module, 4);
+  const opt::Function* f = spvtest::GetFunction(module, 4);
 
   opt::PostDominatorAnalysis* analysis = context->GetPostDominatorAnalysis(f);
 
diff --git a/test/opt/dominator_tree/nested_loops.cpp b/test/opt/dominator_tree/nested_loops.cpp
index 9b6d4d5..f169398 100644
--- a/test/opt/dominator_tree/nested_loops.cpp
+++ b/test/opt/dominator_tree/nested_loops.cpp
@@ -351,14 +351,14 @@
          OpFunctionEnd
 )";
   // clang-format on
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
 
-  const ir::Function* f = spvtest::GetFunction(module, 4);
+  const opt::Function* f = spvtest::GetFunction(module, 4);
   opt::DominatorAnalysis* analysis = context->GetDominatorAnalysis(f);
 
   EXPECT_TRUE(analysis->Dominates(5, 10));
diff --git a/test/opt/dominator_tree/nested_loops_with_unreachables.cpp b/test/opt/dominator_tree/nested_loops_with_unreachables.cpp
index f1f06e2..55b4a90 100644
--- a/test/opt/dominator_tree/nested_loops_with_unreachables.cpp
+++ b/test/opt/dominator_tree/nested_loops_with_unreachables.cpp
@@ -279,14 +279,14 @@
          OpFunctionEnd
 )";
   // clang-format on
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
 
-  const ir::Function* f = spvtest::GetFunction(module, 4);
+  const opt::Function* f = spvtest::GetFunction(module, 4);
   opt::DominatorAnalysis* analysis = context->GetDominatorAnalysis(f);
 
   EXPECT_TRUE(analysis->Dominates(5, 10));
diff --git a/test/opt/dominator_tree/post.cpp b/test/opt/dominator_tree/post.cpp
index 361e001..4be7be0 100644
--- a/test/opt/dominator_tree/post.cpp
+++ b/test/opt/dominator_tree/post.cpp
@@ -139,15 +139,15 @@
                OpFunctionEnd
 )";
   // clang-format on
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
 
-  const ir::Function* f = spvtest::GetFunction(module, 4);
-  ir::CFG cfg(module);
+  const opt::Function* f = spvtest::GetFunction(module, 4);
+  opt::CFG cfg(module);
   opt::PostDominatorAnalysis* analysis = context->GetPostDominatorAnalysis(f);
 
   EXPECT_TRUE(analysis->Dominates(19, 18));
diff --git a/test/opt/dominator_tree/simple.cpp b/test/opt/dominator_tree/simple.cpp
index 2a5ad64..2198e9c 100644
--- a/test/opt/dominator_tree/simple.cpp
+++ b/test/opt/dominator_tree/simple.cpp
@@ -139,16 +139,16 @@
                OpFunctionEnd
 )";
   // clang-format on
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  const ir::Function* f = spvtest::GetFunction(module, 4);
+  const opt::Function* f = spvtest::GetFunction(module, 4);
 
   opt::DominatorAnalysis* analysis = context->GetDominatorAnalysis(f);
-  const ir::CFG& cfg = *context->cfg();
+  const opt::CFG& cfg = *context->cfg();
 
   opt::DominatorTree& tree = analysis->GetDomTree();
 
diff --git a/test/opt/dominator_tree/switch_case_fallthrough.cpp b/test/opt/dominator_tree/switch_case_fallthrough.cpp
index 00eb630..ca05585 100644
--- a/test/opt/dominator_tree/switch_case_fallthrough.cpp
+++ b/test/opt/dominator_tree/switch_case_fallthrough.cpp
@@ -130,14 +130,14 @@
          OpFunctionEnd
 )";
   // clang-format on
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
 
-  const ir::Function* f = spvtest::GetFunction(module, 4);
+  const opt::Function* f = spvtest::GetFunction(module, 4);
   opt::DominatorAnalysis* analysis = context->GetDominatorAnalysis(f);
 
   EXPECT_TRUE(analysis->Dominates(5, 5));
diff --git a/test/opt/dominator_tree/unreachable_for.cpp b/test/opt/dominator_tree/unreachable_for.cpp
index 6c52adb..f83a83c 100644
--- a/test/opt/dominator_tree/unreachable_for.cpp
+++ b/test/opt/dominator_tree/unreachable_for.cpp
@@ -81,14 +81,14 @@
          OpFunctionEnd
 )";
   // clang-format on
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
 
-  const ir::Function* f = spvtest::GetFunction(module, 4);
+  const opt::Function* f = spvtest::GetFunction(module, 4);
   opt::DominatorAnalysis* analysis = context->GetDominatorAnalysis(f);
   EXPECT_TRUE(analysis->Dominates(5, 5));
   EXPECT_TRUE(analysis->Dominates(5, 10));
diff --git a/test/opt/dominator_tree/unreachable_for_post.cpp b/test/opt/dominator_tree/unreachable_for_post.cpp
index 7bb460d..b13ad74 100644
--- a/test/opt/dominator_tree/unreachable_for_post.cpp
+++ b/test/opt/dominator_tree/unreachable_for_post.cpp
@@ -81,14 +81,14 @@
          OpFunctionEnd
 )";
   // clang-format on
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
 
-  const ir::Function* f = spvtest::GetFunction(module, 4);
+  const opt::Function* f = spvtest::GetFunction(module, 4);
 
   opt::PostDominatorAnalysis* analysis = context->GetPostDominatorAnalysis(f);
 
diff --git a/test/opt/feature_manager_test.cpp b/test/opt/feature_manager_test.cpp
index b87e63d..ebaa1e4 100644
--- a/test/opt/feature_manager_test.cpp
+++ b/test/opt/feature_manager_test.cpp
@@ -29,7 +29,7 @@
 OpMemoryModel Logical GLSL450
   )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
   ASSERT_NE(context, nullptr);
 
@@ -44,7 +44,7 @@
 OpExtension "SPV_KHR_variable_pointers"
   )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
   ASSERT_NE(context, nullptr);
 
@@ -59,7 +59,7 @@
 OpExtension "SPV_KHR_variable_pointers"
   )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
   ASSERT_NE(context, nullptr);
 
@@ -75,7 +75,7 @@
 OpExtension "SPV_KHR_storage_buffer_storage_class"
   )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
   ASSERT_NE(context, nullptr);
 
@@ -92,7 +92,7 @@
 OpMemoryModel Logical GLSL450
   )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
   ASSERT_NE(context, nullptr);
 
@@ -106,7 +106,7 @@
 OpMemoryModel Logical GLSL450
   )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
   ASSERT_NE(context, nullptr);
 
@@ -120,7 +120,7 @@
 OpMemoryModel Logical GLSL450
   )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
   ASSERT_NE(context, nullptr);
 
diff --git a/test/opt/fold_test.cpp b/test/opt/fold_test.cpp
index c00e95a..7ee96bd 100644
--- a/test/opt/fold_test.cpp
+++ b/test/opt/fold_test.cpp
@@ -37,7 +37,7 @@
 using spvtools::opt::analysis::DefUseManager;
 
 #ifdef SPIRV_EFFCEE
-std::string Disassemble(const std::string& original, ir::IRContext* context,
+std::string Disassemble(const std::string& original, opt::IRContext* context,
                         uint32_t disassemble_options = 0) {
   std::vector<uint32_t> optimized_bin;
   context->module()->ToBinary(&optimized_bin, true);
@@ -51,7 +51,7 @@
   return optimized_asm;
 }
 
-void Match(const std::string& original, ir::IRContext* context,
+void Match(const std::string& original, opt::IRContext* context,
            uint32_t disassemble_options = 0) {
   std::string disassembly = Disassemble(original, context, disassemble_options);
   auto match_result = effcee::Match(disassembly, original);
@@ -78,14 +78,14 @@
   const auto& tc = GetParam();
 
   // Build module.
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, tc.test_body,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   ASSERT_NE(nullptr, context);
 
   // Fold the instruction to test.
   opt::analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr();
-  ir::Instruction* inst = def_use_mgr->GetDef(tc.id_to_fold);
+  opt::Instruction* inst = def_use_mgr->GetDef(tc.id_to_fold);
   bool succeeded = context->get_instruction_folder().FoldInstruction(inst);
 
   // Make sure the instruction folded as expected.
@@ -446,14 +446,14 @@
   const auto& tc = GetParam();
 
   // Build module.
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, tc.test_body,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   ASSERT_NE(nullptr, context);
 
   // Fold the instruction to test.
   opt::analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr();
-  ir::Instruction* inst = def_use_mgr->GetDef(tc.id_to_fold);
+  opt::Instruction* inst = def_use_mgr->GetDef(tc.id_to_fold);
   bool succeeded = context->get_instruction_folder().FoldInstruction(inst);
 
   // Make sure the instruction folded as expected.
@@ -510,14 +510,14 @@
   const auto& tc = GetParam();
 
   // Build module.
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, tc.test_body,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   ASSERT_NE(nullptr, context);
 
   // Fold the instruction to test.
   opt::analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr();
-  ir::Instruction* inst = def_use_mgr->GetDef(tc.id_to_fold);
+  opt::Instruction* inst = def_use_mgr->GetDef(tc.id_to_fold);
   bool succeeded = context->get_instruction_folder().FoldInstruction(inst);
 
   // Make sure the instruction folded as expected.
@@ -1121,14 +1121,14 @@
   const auto& tc = GetParam();
 
   // Build module.
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, tc.test_body,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   ASSERT_NE(nullptr, context);
 
   // Fold the instruction to test.
   opt::analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr();
-  ir::Instruction* inst = def_use_mgr->GetDef(tc.id_to_fold);
+  opt::Instruction* inst = def_use_mgr->GetDef(tc.id_to_fold);
   bool succeeded = context->get_instruction_folder().FoldInstruction(inst);
 
   // Make sure the instruction folded as expected.
@@ -1268,14 +1268,14 @@
   const auto& tc = GetParam();
 
   // Build module.
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, tc.test_body,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   ASSERT_NE(nullptr, context);
 
   // Fold the instruction to test.
   opt::analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr();
-  ir::Instruction* inst = def_use_mgr->GetDef(tc.id_to_fold);
+  opt::Instruction* inst = def_use_mgr->GetDef(tc.id_to_fold);
   bool succeeded = context->get_instruction_folder().FoldInstruction(inst);
 
   // Make sure the instruction folded as expected.
@@ -2026,14 +2026,14 @@
   const auto& tc = GetParam();
 
   // Build module.
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, tc.test_body,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   ASSERT_NE(nullptr, context);
 
   // Fold the instruction to test.
   opt::analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr();
-  ir::Instruction* inst = def_use_mgr->GetDef(tc.id_to_fold);
+  opt::Instruction* inst = def_use_mgr->GetDef(tc.id_to_fold);
   inst = context->get_instruction_folder().FoldInstructionToConstant(inst,
                                                                      tc.id_map);
 
@@ -2074,14 +2074,14 @@
   const auto& tc = GetParam();
 
   // Build module.
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, tc.test_body,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   ASSERT_NE(nullptr, context);
 
   // Fold the instruction to test.
   opt::analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr();
-  ir::Instruction* inst = def_use_mgr->GetDef(tc.id_to_fold);
+  opt::Instruction* inst = def_use_mgr->GetDef(tc.id_to_fold);
   inst = context->get_instruction_folder().FoldInstructionToConstant(inst,
                                                                      tc.id_map);
 
@@ -2124,15 +2124,15 @@
   const auto& tc = GetParam();
 
   // Build module.
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, tc.test_body,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   ASSERT_NE(nullptr, context);
 
   // Fold the instruction to test.
   opt::analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr();
-  ir::Instruction* inst = def_use_mgr->GetDef(tc.id_to_fold);
-  std::unique_ptr<ir::Instruction> original_inst(inst->Clone(context.get()));
+  opt::Instruction* inst = def_use_mgr->GetDef(tc.id_to_fold);
+  std::unique_ptr<opt::Instruction> original_inst(inst->Clone(context.get()));
   bool succeeded = context->get_instruction_folder().FoldInstruction(inst);
 
   // Make sure the instruction folded as expected.
@@ -3630,15 +3630,15 @@
   const auto& tc = GetParam();
 
   // Build module.
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, tc.test_body,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   ASSERT_NE(nullptr, context);
 
   // Fold the instruction to test.
   opt::analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr();
-  ir::Instruction* inst = def_use_mgr->GetDef(tc.id_to_fold);
-  std::unique_ptr<ir::Instruction> original_inst(inst->Clone(context.get()));
+  opt::Instruction* inst = def_use_mgr->GetDef(tc.id_to_fold);
+  std::unique_ptr<opt::Instruction> original_inst(inst->Clone(context.get()));
   bool succeeded = context->get_instruction_folder().FoldInstruction(inst);
 
   // Make sure the instruction folded as expected.
@@ -3753,15 +3753,15 @@
   const auto& tc = GetParam();
 
   // Build module.
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, tc.test_body,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   ASSERT_NE(nullptr, context);
 
   // Fold the instruction to test.
   opt::analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr();
-  ir::Instruction* inst = def_use_mgr->GetDef(tc.id_to_fold);
-  std::unique_ptr<ir::Instruction> original_inst(inst->Clone(context.get()));
+  opt::Instruction* inst = def_use_mgr->GetDef(tc.id_to_fold);
+  std::unique_ptr<opt::Instruction> original_inst(inst->Clone(context.get()));
   bool succeeded = context->get_instruction_folder().FoldInstruction(inst);
   EXPECT_EQ(succeeded, tc.expected_result);
   if (succeeded) {
@@ -5610,23 +5610,23 @@
   const auto& tc = GetParam();
 
   // Build module.
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, tc.test_body,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   ASSERT_NE(nullptr, context);
 
   // Fold the instruction to test.
-  ir::Instruction* inst = nullptr;
-  ir::Function* func = &*context->module()->begin();
+  opt::Instruction* inst = nullptr;
+  opt::Function* func = &*context->module()->begin();
   for(auto& bb : *func) {
-    ir::Instruction* terminator = bb.terminator();
+    opt::Instruction* terminator = bb.terminator();
     if (terminator->IsReturnOrAbort()) {
       inst = terminator->PreviousNode();
       break;
     }
   }
   assert(inst && "Invalid test.  Could not find instruction to fold.");
-  std::unique_ptr<ir::Instruction> original_inst(inst->Clone(context.get()));
+  std::unique_ptr<opt::Instruction> original_inst(inst->Clone(context.get()));
   bool succeeded = context->get_instruction_folder().FoldInstruction(inst);
   EXPECT_EQ(succeeded, tc.expected_result);
   if (succeeded) {
diff --git a/test/opt/function_utils.h b/test/opt/function_utils.h
index 1bcc58e..fdc223a 100644
--- a/test/opt/function_utils.h
+++ b/test/opt/function_utils.h
@@ -20,9 +20,9 @@
 
 namespace spvtest {
 
-inline spvtools::ir::Function* GetFunction(spvtools::ir::Module* module,
-                                           uint32_t id) {
-  for (spvtools::ir::Function& f : *module) {
+inline spvtools::opt::Function* GetFunction(spvtools::opt::Module* module,
+                                            uint32_t id) {
+  for (spvtools::opt::Function& f : *module) {
     if (f.result_id() == id) {
       return &f;
     }
@@ -30,9 +30,9 @@
   return nullptr;
 }
 
-inline const spvtools::ir::Function* GetFunction(
-    const spvtools::ir::Module* module, uint32_t id) {
-  for (const spvtools::ir::Function& f : *module) {
+inline const spvtools::opt::Function* GetFunction(
+    const spvtools::opt::Module* module, uint32_t id) {
+  for (const spvtools::opt::Function& f : *module) {
     if (f.result_id() == id) {
       return &f;
     }
@@ -40,9 +40,9 @@
   return nullptr;
 }
 
-inline const spvtools::ir::BasicBlock* GetBasicBlock(
-    const spvtools::ir::Function* fn, uint32_t id) {
-  for (const spvtools::ir::BasicBlock& bb : *fn) {
+inline const spvtools::opt::BasicBlock* GetBasicBlock(
+    const spvtools::opt::Function* fn, uint32_t id) {
+  for (const spvtools::opt::BasicBlock& bb : *fn) {
     if (bb.id() == id) {
       return &bb;
     }
diff --git a/test/opt/inline_test.cpp b/test/opt/inline_test.cpp
index 727a414..64efdb8 100644
--- a/test/opt/inline_test.cpp
+++ b/test/opt/inline_test.cpp
@@ -2575,13 +2575,13 @@
                OpFunctionEnd
 )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
   opt::InlineExhaustivePass pass;
   pass.Run(context.get());
 
-  for (ir::Function& func : *context->module()) {
-    for (ir::BasicBlock& bb : func) {
+  for (opt::Function& func : *context->module()) {
+    for (opt::BasicBlock& bb : func) {
       EXPECT_TRUE(bb.GetParent() == &func);
     }
   }
diff --git a/test/opt/instruction_list_test.cpp b/test/opt/instruction_list_test.cpp
index b8dec2f..d70dc1c 100644
--- a/test/opt/instruction_list_test.cpp
+++ b/test/opt/instruction_list_test.cpp
@@ -24,8 +24,8 @@
 
 namespace {
 
-using Instruction = spvtools::ir::Instruction;
-using InstructionList = spvtools::ir::InstructionList;
+using Instruction = spvtools::opt::Instruction;
+using InstructionList = spvtools::opt::InstructionList;
 using ::testing::ContainerEq;
 using ::testing::ElementsAre;
 using InstructionListTest = ::testing::Test;
diff --git a/test/opt/instruction_test.cpp b/test/opt/instruction_test.cpp
index 0a632a9..ca05279 100644
--- a/test/opt/instruction_test.cpp
+++ b/test/opt/instruction_test.cpp
@@ -25,9 +25,9 @@
 namespace {
 
 using namespace spvtools;
-using ir::Instruction;
-using ir::IRContext;
-using ir::Operand;
+using opt::IRContext;
+using opt::Instruction;
+using opt::Operand;
 using spvtest::MakeInstruction;
 using ::testing::Eq;
 using DescriptorTypeTest = PassTest<::testing::Test>;
@@ -316,7 +316,7 @@
                OpFunctionEnd
 )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
   Instruction* type = context->get_def_use_mgr()->GetDef(8);
   EXPECT_TRUE(type->IsVulkanStorageImage());
@@ -352,7 +352,7 @@
                OpFunctionEnd
 )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
   Instruction* type = context->get_def_use_mgr()->GetDef(8);
   EXPECT_FALSE(type->IsVulkanStorageImage());
@@ -388,7 +388,7 @@
                OpFunctionEnd
 )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
   Instruction* type = context->get_def_use_mgr()->GetDef(8);
   EXPECT_FALSE(type->IsVulkanStorageImage());
@@ -427,7 +427,7 @@
                OpFunctionEnd
 )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
   Instruction* type = context->get_def_use_mgr()->GetDef(10);
   EXPECT_FALSE(type->IsVulkanStorageImage());
@@ -466,7 +466,7 @@
                OpFunctionEnd
 )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
   Instruction* type = context->get_def_use_mgr()->GetDef(10);
   EXPECT_FALSE(type->IsVulkanStorageImage());
@@ -506,7 +506,7 @@
                OpFunctionEnd
 )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
   Instruction* variable = context->get_def_use_mgr()->GetDef(3);
   EXPECT_TRUE(variable->IsReadOnlyVariable());
@@ -533,7 +533,7 @@
                OpFunctionEnd
 )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
   Instruction* image_type = context->get_def_use_mgr()->GetDef(6);
   EXPECT_TRUE(image_type->IsOpaqueType());
@@ -571,7 +571,7 @@
                OpFunctionEnd
 )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
   for (int i = 7; i <= 10; i++) {
     Instruction* type = context->get_def_use_mgr()->GetDef(i);
@@ -614,7 +614,7 @@
                OpFunctionEnd
 )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
   Instruction* load = context->get_def_use_mgr()->GetDef(21);
   Instruction* base = context->get_def_use_mgr()->GetDef(20);
@@ -649,7 +649,7 @@
                OpFunctionEnd
 )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
   Instruction* load = context->get_def_use_mgr()->GetDef(14);
   Instruction* base = context->get_def_use_mgr()->GetDef(13);
diff --git a/test/opt/ir_builder.cpp b/test/opt/ir_builder.cpp
index 6096b49..90901d8 100644
--- a/test/opt/ir_builder.cpp
+++ b/test/opt/ir_builder.cpp
@@ -32,7 +32,7 @@
 namespace {
 
 using namespace spvtools;
-using ir::IRContext;
+using opt::IRContext;
 using Analysis = IRContext::Analysis;
 
 #ifdef SPIRV_EFFCEE
@@ -51,7 +51,7 @@
   return error == 0;
 }
 
-void Match(const std::string& original, ir::IRContext* context,
+void Match(const std::string& original, opt::IRContext* context,
            bool do_validation = true) {
   std::vector<uint32_t> bin;
   context->module()->ToBinary(&bin, true);
@@ -112,18 +112,18 @@
 )";
 
   {
-    std::unique_ptr<ir::IRContext> context =
+    std::unique_ptr<opt::IRContext> context =
         BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
 
-    ir::BasicBlock* bb = context->cfg()->block(18);
+    opt::BasicBlock* bb = context->cfg()->block(18);
 
     // Build managers.
     context->get_def_use_mgr();
     context->get_instr_block(nullptr);
 
     opt::InstructionBuilder builder(context.get(), &*bb->begin());
-    ir::Instruction* phi1 = builder.AddPhi(7, {9, 14});
-    ir::Instruction* phi2 = builder.AddPhi(10, {16, 14});
+    opt::Instruction* phi1 = builder.AddPhi(7, {9, 14});
+    opt::Instruction* phi2 = builder.AddPhi(10, {16, 14});
 
     // Make sure the InstructionBuilder did not update the def/use manager.
     EXPECT_EQ(context->get_def_use_mgr()->GetDef(phi1->result_id()), nullptr);
@@ -135,20 +135,20 @@
   }
 
   {
-    std::unique_ptr<ir::IRContext> context =
+    std::unique_ptr<opt::IRContext> context =
         BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
 
     // Build managers.
     context->get_def_use_mgr();
     context->get_instr_block(nullptr);
 
-    ir::BasicBlock* bb = context->cfg()->block(18);
+    opt::BasicBlock* bb = context->cfg()->block(18);
     opt::InstructionBuilder builder(
         context.get(), &*bb->begin(),
-        ir::IRContext::kAnalysisDefUse |
-            ir::IRContext::kAnalysisInstrToBlockMapping);
-    ir::Instruction* phi1 = builder.AddPhi(7, {9, 14});
-    ir::Instruction* phi2 = builder.AddPhi(10, {16, 14});
+        opt::IRContext::kAnalysisDefUse |
+            opt::IRContext::kAnalysisInstrToBlockMapping);
+    opt::Instruction* phi1 = builder.AddPhi(7, {9, 14});
+    opt::Instruction* phi2 = builder.AddPhi(10, {16, 14});
 
     // Make sure InstructionBuilder updated the def/use manager
     EXPECT_NE(context->get_def_use_mgr()->GetDef(phi1->result_id()), nullptr);
@@ -197,26 +197,28 @@
 )";
 
   {
-    std::unique_ptr<ir::IRContext> context =
+    std::unique_ptr<opt::IRContext> context =
         BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
 
-    ir::Function& fn = *context->module()->begin();
+    opt::Function& fn = *context->module()->begin();
 
-    ir::BasicBlock& bb_merge = *fn.begin();
+    opt::BasicBlock& bb_merge = *fn.begin();
 
-    fn.begin().InsertBefore(std::unique_ptr<ir::BasicBlock>(
-        new ir::BasicBlock(std::unique_ptr<ir::Instruction>(new ir::Instruction(
-            context.get(), SpvOpLabel, 0, context->TakeNextId(), {})))));
-    ir::BasicBlock& bb_true = *fn.begin();
+    fn.begin().InsertBefore(
+        std::unique_ptr<opt::BasicBlock>(new opt::BasicBlock(
+            std::unique_ptr<opt::Instruction>(new opt::Instruction(
+                context.get(), SpvOpLabel, 0, context->TakeNextId(), {})))));
+    opt::BasicBlock& bb_true = *fn.begin();
     {
       opt::InstructionBuilder builder(context.get(), &*bb_true.begin());
       builder.AddBranch(bb_merge.id());
     }
 
-    fn.begin().InsertBefore(std::unique_ptr<ir::BasicBlock>(
-        new ir::BasicBlock(std::unique_ptr<ir::Instruction>(new ir::Instruction(
-            context.get(), SpvOpLabel, 0, context->TakeNextId(), {})))));
-    ir::BasicBlock& bb_cond = *fn.begin();
+    fn.begin().InsertBefore(
+        std::unique_ptr<opt::BasicBlock>(new opt::BasicBlock(
+            std::unique_ptr<opt::Instruction>(new opt::Instruction(
+                context.get(), SpvOpLabel, 0, context->TakeNextId(), {})))));
+    opt::BasicBlock& bb_cond = *fn.begin();
 
     opt::InstructionBuilder builder(context.get(), &bb_cond);
     // This also test consecutive instruction insertion: merge selection +
@@ -251,7 +253,7 @@
 OpFunctionEnd
 )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
   EXPECT_NE(nullptr, context);
 
@@ -284,7 +286,7 @@
 OpFunctionEnd
 )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
   EXPECT_NE(nullptr, context);
 
@@ -317,7 +319,7 @@
 OpFunctionEnd
 )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
   EXPECT_NE(nullptr, context);
 
@@ -362,14 +364,14 @@
 OpFunctionEnd
 )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
   EXPECT_NE(nullptr, context);
 
   opt::InstructionBuilder builder(
       context.get(), &*context->module()->begin()->begin()->begin());
-  ir::Instruction* const_1 = builder.Add32BitUnsignedIntegerConstant(13);
-  ir::Instruction* const_2 = builder.Add32BitSignedIntegerConstant(-1);
+  opt::Instruction* const_1 = builder.Add32BitUnsignedIntegerConstant(13);
+  opt::Instruction* const_2 = builder.Add32BitSignedIntegerConstant(-1);
 
   EXPECT_NE(nullptr, const_1);
   EXPECT_NE(nullptr, const_2);
@@ -378,15 +380,15 @@
   EXPECT_EQ(const_1, builder.Add32BitUnsignedIntegerConstant(13));
   EXPECT_EQ(const_2, builder.Add32BitSignedIntegerConstant(-1));
 
-  ir::Instruction* const_3 = builder.Add32BitUnsignedIntegerConstant(1);
-  ir::Instruction* const_4 = builder.Add32BitSignedIntegerConstant(34);
+  opt::Instruction* const_3 = builder.Add32BitUnsignedIntegerConstant(1);
+  opt::Instruction* const_4 = builder.Add32BitSignedIntegerConstant(34);
 
   // Try adding different constants to make sure the type is reused.
   EXPECT_NE(nullptr, const_3);
   EXPECT_NE(nullptr, const_4);
 
-  ir::Instruction* const_5 = builder.Add32BitUnsignedIntegerConstant(0);
-  ir::Instruction* const_6 = builder.Add32BitSignedIntegerConstant(0);
+  opt::Instruction* const_5 = builder.Add32BitUnsignedIntegerConstant(0);
+  opt::Instruction* const_6 = builder.Add32BitSignedIntegerConstant(0);
 
   // Try adding 0 as both signed and unsigned.
   EXPECT_NE(nullptr, const_5);
diff --git a/test/opt/ir_context_test.cpp b/test/opt/ir_context_test.cpp
index ad851ed..c57caad 100644
--- a/test/opt/ir_context_test.cpp
+++ b/test/opt/ir_context_test.cpp
@@ -24,7 +24,7 @@
 namespace {
 
 using namespace spvtools;
-using ir::IRContext;
+using opt::IRContext;
 using Analysis = IRContext::Analysis;
 using ::testing::Each;
 
@@ -61,7 +61,7 @@
 using IRContextTest = PassTest<::testing::Test>;
 
 TEST_F(IRContextTest, IndividualValidAfterBuild) {
-  std::unique_ptr<ir::Module> module(new ir::Module());
+  std::unique_ptr<opt::Module> module(new opt::Module());
   IRContext localContext(SPV_ENV_UNIVERSAL_1_2, std::move(module),
                          spvtools::MessageConsumer());
 
@@ -73,7 +73,7 @@
 }
 
 TEST_F(IRContextTest, AllValidAfterBuild) {
-  std::unique_ptr<ir::Module> module = MakeUnique<ir::Module>();
+  std::unique_ptr<opt::Module> module = MakeUnique<opt::Module>();
   IRContext localContext(SPV_ENV_UNIVERSAL_1_2, std::move(module),
                          spvtools::MessageConsumer());
 
@@ -87,7 +87,7 @@
 }
 
 TEST_F(IRContextTest, AllValidAfterPassNoChange) {
-  std::unique_ptr<ir::Module> module = MakeUnique<ir::Module>();
+  std::unique_ptr<opt::Module> module = MakeUnique<opt::Module>();
   IRContext localContext(SPV_ENV_UNIVERSAL_1_2, std::move(module),
                          spvtools::MessageConsumer());
 
@@ -105,7 +105,7 @@
 }
 
 TEST_F(IRContextTest, NoneValidAfterPassWithChange) {
-  std::unique_ptr<ir::Module> module = MakeUnique<ir::Module>();
+  std::unique_ptr<opt::Module> module = MakeUnique<opt::Module>();
   IRContext localContext(SPV_ENV_UNIVERSAL_1_2, std::move(module),
                          spvtools::MessageConsumer());
 
@@ -124,7 +124,7 @@
 }
 
 TEST_F(IRContextTest, AllPreservedAfterPassWithChange) {
-  std::unique_ptr<ir::Module> module = MakeUnique<ir::Module>();
+  std::unique_ptr<opt::Module> module = MakeUnique<opt::Module>();
   IRContext localContext(SPV_ENV_UNIVERSAL_1_2, std::move(module),
                          spvtools::MessageConsumer());
 
@@ -143,7 +143,7 @@
 }
 
 TEST_F(IRContextTest, PreserveFirstOnlyAfterPassWithChange) {
-  std::unique_ptr<ir::Module> module = MakeUnique<ir::Module>();
+  std::unique_ptr<opt::Module> module = MakeUnique<opt::Module>();
   IRContext localContext(SPV_ENV_UNIVERSAL_1_2, std::move(module),
                          spvtools::MessageConsumer());
 
@@ -184,7 +184,7 @@
                OpFunctionEnd
 )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
 
   // Build the decoration manager.
diff --git a/test/opt/ir_loader_test.cpp b/test/opt/ir_loader_test.cpp
index 87e7e97..528d5a8 100644
--- a/test/opt/ir_loader_test.cpp
+++ b/test/opt/ir_loader_test.cpp
@@ -27,7 +27,7 @@
 
 void DoRoundTripCheck(const std::string& text) {
   SpirvTools t(SPV_ENV_UNIVERSAL_1_1);
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text);
   ASSERT_NE(nullptr, context) << "Failed to assemble\n" << text;
 
@@ -214,14 +214,14 @@
   // clang-format on
 
   SpirvTools t(SPV_ENV_UNIVERSAL_1_1);
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text);
   ASSERT_NE(nullptr, context);
 
   const auto opundef_count = std::count_if(
       context->module()->types_values_begin(),
       context->module()->types_values_end(),
-      [](const ir::Instruction& inst) { return inst.opcode() == SpvOpUndef; });
+      [](const opt::Instruction& inst) { return inst.opcode() == SpvOpUndef; });
   EXPECT_EQ(3, opundef_count);
 
   std::vector<uint32_t> binary;
@@ -325,7 +325,7 @@
   };
 
   SpirvTools t(SPV_ENV_UNIVERSAL_1_1);
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, std::move(consumer), assembly);
   EXPECT_EQ(nullptr, context);
 }
@@ -436,12 +436,12 @@
                "OpFunctionEnd\n";
   // clang-format on
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text);
   ASSERT_NE(nullptr, context);
 
   std::unordered_set<uint32_t> ids;
-  context->module()->ForEachInst([&ids](const ir::Instruction* inst) {
+  context->module()->ForEachInst([&ids](const opt::Instruction* inst) {
     EXPECT_TRUE(ids.insert(inst->unique_id()).second);
   });
 }
diff --git a/test/opt/iterator_test.cpp b/test/opt/iterator_test.cpp
index 5918430..8215aac 100644
--- a/test/opt/iterator_test.cpp
+++ b/test/opt/iterator_test.cpp
@@ -32,8 +32,8 @@
     data.emplace_back(new int(i));
   }
 
-  ir::UptrVectorIterator<int> it(&data, data.begin());
-  ir::UptrVectorIterator<int> end(&data, data.end());
+  opt::UptrVectorIterator<int> it(&data, data.begin());
+  opt::UptrVectorIterator<int> end(&data, data.end());
 
   EXPECT_EQ(*data[0], *it);
   for (int i = 1; i < count; ++i) {
@@ -50,8 +50,8 @@
     data.emplace_back(new int(i));
   }
 
-  ir::UptrVectorIterator<int> begin(&data, data.begin());
-  ir::UptrVectorIterator<int> it(&data, data.end());
+  opt::UptrVectorIterator<int> begin(&data, data.begin());
+  opt::UptrVectorIterator<int> it(&data, data.end());
 
   for (int i = count - 1; i >= 0; --i) {
     EXPECT_NE(begin, it);
@@ -67,8 +67,8 @@
     data.emplace_back(new int(i));
   }
 
-  ir::UptrVectorIterator<int> it(&data, data.begin());
-  ir::UptrVectorIterator<int> end(&data, data.end());
+  opt::UptrVectorIterator<int> it(&data, data.begin());
+  opt::UptrVectorIterator<int> end(&data, data.end());
 
   for (int i = 0; i < count; ++i) {
     EXPECT_NE(end, it);
@@ -84,9 +84,9 @@
     data.emplace_back(new int(i));
   }
 
-  ir::UptrVectorIterator<int> begin(&data, data.begin());
-  ir::UptrVectorIterator<int> end(&data, data.end());
-  ir::UptrVectorIterator<int> it(&data, data.end());
+  opt::UptrVectorIterator<int> begin(&data, data.begin());
+  opt::UptrVectorIterator<int> end(&data, data.end());
+  opt::UptrVectorIterator<int> it(&data, data.end());
 
   EXPECT_EQ(end, it--);
   for (int i = count - 1; i >= 1; --i) {
@@ -103,7 +103,7 @@
     data.emplace_back(new int(i));
   }
 
-  ir::UptrVectorIterator<int> it(&data, data.begin());
+  opt::UptrVectorIterator<int> it(&data, data.begin());
 
   for (int i = 0; i < count; ++i) EXPECT_EQ(*data[i], it[i]);
 }
@@ -115,8 +115,8 @@
     data.emplace_back(new int(i));
   }
 
-  ir::UptrVectorIterator<int> it(&data, data.begin());
-  ir::UptrVectorIterator<int> end(&data, data.end());
+  opt::UptrVectorIterator<int> it(&data, data.begin());
+  opt::UptrVectorIterator<int> end(&data, data.end());
 
   for (int i = 0; i < count; ++i, ++it) EXPECT_TRUE(it < end);
   EXPECT_EQ(end, it);
@@ -136,7 +136,7 @@
 
   // Insert at the beginning
   expected.insert(expected.begin(), -100);
-  ir::UptrVectorIterator<int> begin(&data, data.begin());
+  opt::UptrVectorIterator<int> begin(&data, data.begin());
   auto insert_point = begin.InsertBefore(MakeUnique<int>(-100));
   for (int i = 0; i < count + 1; ++i) {
     actual.push_back(*(insert_point++));
@@ -147,13 +147,13 @@
   expected.push_back(-42);
   expected.push_back(-36);
   expected.push_back(-77);
-  ir::UptrVectorIterator<int> end(&data, data.end());
+  opt::UptrVectorIterator<int> end(&data, data.end());
   end = end.InsertBefore(MakeUnique<int>(-77));
   end = end.InsertBefore(MakeUnique<int>(-36));
   end = end.InsertBefore(MakeUnique<int>(-42));
 
   actual.clear();
-  begin = ir::UptrVectorIterator<int>(&data, data.begin());
+  begin = opt::UptrVectorIterator<int>(&data, data.begin());
   for (int i = 0; i < count + 4; ++i) {
     actual.push_back(*(begin++));
   }
@@ -176,11 +176,11 @@
   expected.insert(expected.begin() + insert_pos, -100);
   expected.insert(expected.begin() + insert_pos, -42);
 
-  ir::UptrVectorIterator<int> it(&data, data.begin());
+  opt::UptrVectorIterator<int> it(&data, data.begin());
   for (int i = 0; i < insert_pos; ++i) ++it;
   it = it.InsertBefore(MakeUnique<int>(-100));
   it = it.InsertBefore(MakeUnique<int>(-42));
-  auto begin = ir::UptrVectorIterator<int>(&data, data.begin());
+  auto begin = opt::UptrVectorIterator<int>(&data, data.begin());
   for (int i = 0; i < count + 2; ++i) {
     actual.push_back(*(begin++));
   }
@@ -196,9 +196,9 @@
     data.emplace_back(new uint32_t(i));
   }
 
-  auto b = ir::UptrVectorIterator<uint32_t>(&data, data.begin());
-  auto e = ir::UptrVectorIterator<uint32_t>(&data, data.end());
-  auto range = ir::IteratorRange<decltype(b)>(b, e);
+  auto b = opt::UptrVectorIterator<uint32_t>(&data, data.begin());
+  auto e = opt::UptrVectorIterator<uint32_t>(&data, data.end());
+  auto range = opt::IteratorRange<decltype(b)>(b, e);
 
   EXPECT_EQ(b, range.begin());
   EXPECT_EQ(e, range.end());
@@ -228,7 +228,7 @@
   Predicate pred;
 
   auto filter_range =
-      ir::MakeFilterIteratorRange(data.begin(), data.end(), pred);
+      opt::MakeFilterIteratorRange(data.begin(), data.end(), pred);
 
   EXPECT_EQ(filter_range.begin().Get(), data.begin());
   EXPECT_EQ(filter_range.end(), filter_range.begin().GetEnd());
@@ -247,17 +247,17 @@
     EXPECT_EQ((*it).val % 2, 1);
   }
 
-  EXPECT_EQ(ir::MakeFilterIterator(data.begin(), data.end(), pred).Get(),
+  EXPECT_EQ(opt::MakeFilterIterator(data.begin(), data.end(), pred).Get(),
             data.begin());
-  EXPECT_EQ(ir::MakeFilterIterator(data.end(), data.end(), pred).Get(),
+  EXPECT_EQ(opt::MakeFilterIterator(data.end(), data.end(), pred).Get(),
             data.end());
-  EXPECT_EQ(ir::MakeFilterIterator(data.begin(), data.end(), pred).GetEnd(),
-            ir::MakeFilterIterator(data.end(), data.end(), pred));
-  EXPECT_NE(ir::MakeFilterIterator(data.begin(), data.end(), pred),
-            ir::MakeFilterIterator(data.end(), data.end(), pred));
+  EXPECT_EQ(opt::MakeFilterIterator(data.begin(), data.end(), pred).GetEnd(),
+            opt::MakeFilterIterator(data.end(), data.end(), pred));
+  EXPECT_NE(opt::MakeFilterIterator(data.begin(), data.end(), pred),
+            opt::MakeFilterIterator(data.end(), data.end(), pred));
 
   // Empty range: no values satisfies the predicate.
-  auto empty_range = ir::MakeFilterIteratorRange(
+  auto empty_range = opt::MakeFilterIteratorRange(
       data.begin(), data.end(),
       [](const Placeholder& data) { return data.val > 10; });
   EXPECT_EQ(empty_range.begin(), empty_range.end());
diff --git a/test/opt/line_debug_info_test.cpp b/test/opt/line_debug_info_test.cpp
index 2bb7948..7354afc 100644
--- a/test/opt/line_debug_info_test.cpp
+++ b/test/opt/line_debug_info_test.cpp
@@ -23,10 +23,10 @@
 class NopifyPass : public opt::Pass {
  public:
   const char* name() const override { return "NopifyPass"; }
-  Status Process(ir::IRContext* irContext) override {
+  Status Process(opt::IRContext* irContext) override {
     bool modified = false;
     irContext->module()->ForEachInst(
-        [&modified](ir::Instruction* inst) {
+        [&modified](opt::Instruction* inst) {
           inst->ToNop();
           modified = true;
         },
diff --git a/test/opt/local_ssa_elim_test.cpp b/test/opt/local_ssa_elim_test.cpp
index f840c8f..95aca78 100644
--- a/test/opt/local_ssa_elim_test.cpp
+++ b/test/opt/local_ssa_elim_test.cpp
@@ -1609,7 +1609,7 @@
 OpFunctionEnd
 )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   EXPECT_NE(nullptr, context);
diff --git a/test/opt/loop_optimizations/dependence_analysis.cpp b/test/opt/loop_optimizations/dependence_analysis.cpp
index dbd8065..91d1e6e 100644
--- a/test/opt/loop_optimizations/dependence_analysis.cpp
+++ b/test/opt/loop_optimizations/dependence_analysis.cpp
@@ -120,22 +120,22 @@
                OpReturn
                OpFunctionEnd
 )";
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  const ir::Function* f = spvtest::GetFunction(module, 4);
-  ir::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
+  const opt::Function* f = spvtest::GetFunction(module, 4);
+  opt::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
 
-  ir::Loop* loop = &ld.GetLoopByIndex(0);
-  std::vector<const ir::Loop*> loops{loop};
+  opt::Loop* loop = &ld.GetLoopByIndex(0);
+  std::vector<const opt::Loop*> loops{loop};
   opt::LoopDependenceAnalysis analysis{context.get(), loops};
 
-  const ir::Instruction* store[4];
+  const opt::Instruction* store[4];
   int stores_found = 0;
-  for (const ir::Instruction& inst : *spvtest::GetBasicBlock(f, 13)) {
+  for (const opt::Instruction& inst : *spvtest::GetBasicBlock(f, 13)) {
     if (inst.opcode() == SpvOp::SpvOpStore) {
       store[stores_found] = &inst;
       ++stores_found;
@@ -277,22 +277,22 @@
                OpReturn
                OpFunctionEnd
 )";
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  const ir::Function* f = spvtest::GetFunction(module, 4);
-  ir::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
+  const opt::Function* f = spvtest::GetFunction(module, 4);
+  opt::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
 
-  ir::Loop* loop = &ld.GetLoopByIndex(0);
-  std::vector<const ir::Loop*> loops{loop};
+  opt::Loop* loop = &ld.GetLoopByIndex(0);
+  std::vector<const opt::Loop*> loops{loop};
   opt::LoopDependenceAnalysis analysis{context.get(), loops};
 
-  const ir::Instruction* store[4];
+  const opt::Instruction* store[4];
   int stores_found = 0;
-  for (const ir::Instruction& inst : *spvtest::GetBasicBlock(f, 22)) {
+  for (const opt::Instruction& inst : *spvtest::GetBasicBlock(f, 22)) {
     if (inst.opcode() == SpvOp::SpvOpStore) {
       store[stores_found] = &inst;
       ++stores_found;
@@ -511,24 +511,24 @@
                OpReturn
                OpFunctionEnd
 )";
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
   // For the loop in function a.
   {
-    const ir::Function* f = spvtest::GetFunction(module, 6);
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
+    const opt::Function* f = spvtest::GetFunction(module, 6);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
 
-    ir::Loop* loop = &ld.GetLoopByIndex(0);
-    std::vector<const ir::Loop*> loops{loop};
+    opt::Loop* loop = &ld.GetLoopByIndex(0);
+    std::vector<const opt::Loop*> loops{loop};
     opt::LoopDependenceAnalysis analysis{context.get(), loops};
 
-    const ir::Instruction* store[4];
+    const opt::Instruction* store[4];
     int stores_found = 0;
-    for (const ir::Instruction& inst : *spvtest::GetBasicBlock(f, 17)) {
+    for (const opt::Instruction& inst : *spvtest::GetBasicBlock(f, 17)) {
       if (inst.opcode() == SpvOp::SpvOpStore) {
         store[stores_found] = &inst;
         ++stores_found;
@@ -592,16 +592,16 @@
   }
   // For the loop in function b.
   {
-    const ir::Function* f = spvtest::GetFunction(module, 8);
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
+    const opt::Function* f = spvtest::GetFunction(module, 8);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
 
-    ir::Loop* loop = &ld.GetLoopByIndex(0);
-    std::vector<const ir::Loop*> loops{loop};
+    opt::Loop* loop = &ld.GetLoopByIndex(0);
+    std::vector<const opt::Loop*> loops{loop};
     opt::LoopDependenceAnalysis analysis{context.get(), loops};
 
-    const ir::Instruction* store[4];
+    const opt::Instruction* store[4];
     int stores_found = 0;
-    for (const ir::Instruction& inst : *spvtest::GetBasicBlock(f, 68)) {
+    for (const opt::Instruction& inst : *spvtest::GetBasicBlock(f, 68)) {
       if (inst.opcode() == SpvOp::SpvOpStore) {
         store[stores_found] = &inst;
         ++stores_found;
@@ -905,24 +905,24 @@
                OpReturn
                OpFunctionEnd
 )";
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
   // For the loop in function a.
   {
-    const ir::Function* f = spvtest::GetFunction(module, 6);
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
+    const opt::Function* f = spvtest::GetFunction(module, 6);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
 
-    ir::Loop* loop = &ld.GetLoopByIndex(0);
-    std::vector<const ir::Loop*> loops{loop};
+    opt::Loop* loop = &ld.GetLoopByIndex(0);
+    std::vector<const opt::Loop*> loops{loop};
     opt::LoopDependenceAnalysis analysis{context.get(), loops};
 
-    const ir::Instruction* store[4];
+    const opt::Instruction* store[4];
     int stores_found = 0;
-    for (const ir::Instruction& inst : *spvtest::GetBasicBlock(f, 29)) {
+    for (const opt::Instruction& inst : *spvtest::GetBasicBlock(f, 29)) {
       if (inst.opcode() == SpvOp::SpvOpStore) {
         store[stores_found] = &inst;
         ++stores_found;
@@ -969,16 +969,16 @@
   }
   // For the loop in function b.
   {
-    const ir::Function* f = spvtest::GetFunction(module, 8);
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
+    const opt::Function* f = spvtest::GetFunction(module, 8);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
 
-    ir::Loop* loop = &ld.GetLoopByIndex(0);
-    std::vector<const ir::Loop*> loops{loop};
+    opt::Loop* loop = &ld.GetLoopByIndex(0);
+    std::vector<const opt::Loop*> loops{loop};
     opt::LoopDependenceAnalysis analysis{context.get(), loops};
 
-    const ir::Instruction* store[4];
+    const opt::Instruction* store[4];
     int stores_found = 0;
-    for (const ir::Instruction& inst : *spvtest::GetBasicBlock(f, 114)) {
+    for (const opt::Instruction& inst : *spvtest::GetBasicBlock(f, 114)) {
       if (inst.opcode() == SpvOp::SpvOpStore) {
         store[stores_found] = &inst;
         ++stores_found;
@@ -1401,10 +1401,10 @@
                OpReturn
                OpFunctionEnd
 )";
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
 
@@ -1412,15 +1412,15 @@
   // Tests even crossing subscripts from low to high indexes.
   // 47 -> 48
   {
-    const ir::Function* f = spvtest::GetFunction(module, 6);
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
+    const opt::Function* f = spvtest::GetFunction(module, 6);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
 
-    ir::Loop* loop = &ld.GetLoopByIndex(0);
-    std::vector<const ir::Loop*> loops{loop};
+    opt::Loop* loop = &ld.GetLoopByIndex(0);
+    std::vector<const opt::Loop*> loops{loop};
     opt::LoopDependenceAnalysis analysis{context.get(), loops};
 
-    const ir::Instruction* store = nullptr;
-    for (const ir::Instruction& inst : *spvtest::GetBasicBlock(f, 29)) {
+    const opt::Instruction* store = nullptr;
+    for (const opt::Instruction& inst : *spvtest::GetBasicBlock(f, 29)) {
       if (inst.opcode() == SpvOp::SpvOpStore) {
         store = &inst;
       }
@@ -1433,15 +1433,15 @@
   // Tests even crossing subscripts from high to low indexes.
   // 67 -> 68
   {
-    const ir::Function* f = spvtest::GetFunction(module, 8);
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
+    const opt::Function* f = spvtest::GetFunction(module, 8);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
 
-    ir::Loop* loop = &ld.GetLoopByIndex(0);
-    std::vector<const ir::Loop*> loops{loop};
+    opt::Loop* loop = &ld.GetLoopByIndex(0);
+    std::vector<const opt::Loop*> loops{loop};
     opt::LoopDependenceAnalysis analysis{context.get(), loops};
 
-    const ir::Instruction* store = nullptr;
-    for (const ir::Instruction& inst : *spvtest::GetBasicBlock(f, 54)) {
+    const opt::Instruction* store = nullptr;
+    for (const opt::Instruction& inst : *spvtest::GetBasicBlock(f, 54)) {
       if (inst.opcode() == SpvOp::SpvOpStore) {
         store = &inst;
       }
@@ -1455,15 +1455,15 @@
   // Tests uneven crossing subscripts from low to high indexes.
   // 92 -> 93
   {
-    const ir::Function* f = spvtest::GetFunction(module, 10);
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
+    const opt::Function* f = spvtest::GetFunction(module, 10);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
 
-    ir::Loop* loop = &ld.GetLoopByIndex(0);
-    std::vector<const ir::Loop*> loops{loop};
+    opt::Loop* loop = &ld.GetLoopByIndex(0);
+    std::vector<const opt::Loop*> loops{loop};
     opt::LoopDependenceAnalysis analysis{context.get(), loops};
 
-    const ir::Instruction* store = nullptr;
-    for (const ir::Instruction& inst : *spvtest::GetBasicBlock(f, 75)) {
+    const opt::Instruction* store = nullptr;
+    for (const opt::Instruction& inst : *spvtest::GetBasicBlock(f, 75)) {
       if (inst.opcode() == SpvOp::SpvOpStore) {
         store = &inst;
       }
@@ -1476,15 +1476,15 @@
   // Tests uneven crossing subscripts from high to low indexes.
   // 113 -> 114
   {
-    const ir::Function* f = spvtest::GetFunction(module, 12);
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
+    const opt::Function* f = spvtest::GetFunction(module, 12);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
 
-    ir::Loop* loop = &ld.GetLoopByIndex(0);
-    std::vector<const ir::Loop*> loops{loop};
+    opt::Loop* loop = &ld.GetLoopByIndex(0);
+    std::vector<const opt::Loop*> loops{loop};
     opt::LoopDependenceAnalysis analysis{context.get(), loops};
 
-    const ir::Instruction* store = nullptr;
-    for (const ir::Instruction& inst : *spvtest::GetBasicBlock(f, 99)) {
+    const opt::Instruction* store = nullptr;
+    for (const opt::Instruction& inst : *spvtest::GetBasicBlock(f, 99)) {
       if (inst.opcode() == SpvOp::SpvOpStore) {
         store = &inst;
       }
@@ -1498,15 +1498,15 @@
   // Tests even crossing subscripts from low to high indexes.
   // 134 -> 135
   {
-    const ir::Function* f = spvtest::GetFunction(module, 14);
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
+    const opt::Function* f = spvtest::GetFunction(module, 14);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
 
-    ir::Loop* loop = &ld.GetLoopByIndex(0);
-    std::vector<const ir::Loop*> loops{loop};
+    opt::Loop* loop = &ld.GetLoopByIndex(0);
+    std::vector<const opt::Loop*> loops{loop};
     opt::LoopDependenceAnalysis analysis{context.get(), loops};
 
-    const ir::Instruction* store = nullptr;
-    for (const ir::Instruction& inst : *spvtest::GetBasicBlock(f, 121)) {
+    const opt::Instruction* store = nullptr;
+    for (const opt::Instruction& inst : *spvtest::GetBasicBlock(f, 121)) {
       if (inst.opcode() == SpvOp::SpvOpStore) {
         store = &inst;
       }
@@ -1519,15 +1519,15 @@
   // Tests even crossing subscripts from high to low indexes.
   // 154 -> 155
   {
-    const ir::Function* f = spvtest::GetFunction(module, 16);
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
+    const opt::Function* f = spvtest::GetFunction(module, 16);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
 
-    ir::Loop* loop = &ld.GetLoopByIndex(0);
-    std::vector<const ir::Loop*> loops{loop};
+    opt::Loop* loop = &ld.GetLoopByIndex(0);
+    std::vector<const opt::Loop*> loops{loop};
     opt::LoopDependenceAnalysis analysis{context.get(), loops};
 
-    const ir::Instruction* store = nullptr;
-    for (const ir::Instruction& inst : *spvtest::GetBasicBlock(f, 142)) {
+    const opt::Instruction* store = nullptr;
+    for (const opt::Instruction& inst : *spvtest::GetBasicBlock(f, 142)) {
       if (inst.opcode() == SpvOp::SpvOpStore) {
         store = &inst;
       }
@@ -1541,15 +1541,15 @@
   // Tests uneven crossing subscripts from low to high indexes.
   // 175 -> 176
   {
-    const ir::Function* f = spvtest::GetFunction(module, 18);
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
+    const opt::Function* f = spvtest::GetFunction(module, 18);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
 
-    ir::Loop* loop = &ld.GetLoopByIndex(0);
-    std::vector<const ir::Loop*> loops{loop};
+    opt::Loop* loop = &ld.GetLoopByIndex(0);
+    std::vector<const opt::Loop*> loops{loop};
     opt::LoopDependenceAnalysis analysis{context.get(), loops};
 
-    const ir::Instruction* store = nullptr;
-    for (const ir::Instruction& inst : *spvtest::GetBasicBlock(f, 162)) {
+    const opt::Instruction* store = nullptr;
+    for (const opt::Instruction& inst : *spvtest::GetBasicBlock(f, 162)) {
       if (inst.opcode() == SpvOp::SpvOpStore) {
         store = &inst;
       }
@@ -1562,15 +1562,15 @@
   // Tests uneven crossing subscripts from high to low indexes.
   // 196 -> 197
   {
-    const ir::Function* f = spvtest::GetFunction(module, 20);
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
+    const opt::Function* f = spvtest::GetFunction(module, 20);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
 
-    ir::Loop* loop = &ld.GetLoopByIndex(0);
-    std::vector<const ir::Loop*> loops{loop};
+    opt::Loop* loop = &ld.GetLoopByIndex(0);
+    std::vector<const opt::Loop*> loops{loop};
     opt::LoopDependenceAnalysis analysis{context.get(), loops};
 
-    const ir::Instruction* store = nullptr;
-    for (const ir::Instruction& inst : *spvtest::GetBasicBlock(f, 183)) {
+    const opt::Instruction* store = nullptr;
+    for (const opt::Instruction& inst : *spvtest::GetBasicBlock(f, 183)) {
       if (inst.opcode() == SpvOp::SpvOpStore) {
         store = &inst;
       }
@@ -1829,24 +1829,24 @@
                OpFunctionEnd
 )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
   // For the loop in function a
   {
-    const ir::Function* f = spvtest::GetFunction(module, 6);
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
+    const opt::Function* f = spvtest::GetFunction(module, 6);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
 
-    ir::Loop* loop = &ld.GetLoopByIndex(0);
-    std::vector<const ir::Loop*> loops{loop};
+    opt::Loop* loop = &ld.GetLoopByIndex(0);
+    std::vector<const opt::Loop*> loops{loop};
     opt::LoopDependenceAnalysis analysis{context.get(), loops};
 
-    const ir::Instruction* store[4];
+    const opt::Instruction* store[4];
     int stores_found = 0;
-    for (const ir::Instruction& inst : *spvtest::GetBasicBlock(f, 19)) {
+    for (const opt::Instruction& inst : *spvtest::GetBasicBlock(f, 19)) {
       if (inst.opcode() == SpvOp::SpvOpStore) {
         store[stores_found] = &inst;
         ++stores_found;
@@ -1905,16 +1905,16 @@
   }
   // For the loop in function b
   {
-    const ir::Function* f = spvtest::GetFunction(module, 8);
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
+    const opt::Function* f = spvtest::GetFunction(module, 8);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
 
-    ir::Loop* loop = &ld.GetLoopByIndex(0);
-    std::vector<const ir::Loop*> loops{loop};
+    opt::Loop* loop = &ld.GetLoopByIndex(0);
+    std::vector<const opt::Loop*> loops{loop};
     opt::LoopDependenceAnalysis analysis{context.get(), loops};
 
-    const ir::Instruction* store[4];
+    const opt::Instruction* store[4];
     int stores_found = 0;
-    for (const ir::Instruction& inst : *spvtest::GetBasicBlock(f, 54)) {
+    for (const opt::Instruction& inst : *spvtest::GetBasicBlock(f, 54)) {
       if (inst.opcode() == SpvOp::SpvOpStore) {
         store[stores_found] = &inst;
         ++stores_found;
@@ -1973,15 +1973,15 @@
   }
   // For the loop in function c
   {
-    const ir::Function* f = spvtest::GetFunction(module, 10);
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
+    const opt::Function* f = spvtest::GetFunction(module, 10);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
 
-    ir::Loop* loop = &ld.GetLoopByIndex(0);
-    std::vector<const ir::Loop*> loops{loop};
+    opt::Loop* loop = &ld.GetLoopByIndex(0);
+    std::vector<const opt::Loop*> loops{loop};
     opt::LoopDependenceAnalysis analysis{context.get(), loops};
-    const ir::Instruction* store[4];
+    const opt::Instruction* store[4];
     int stores_found = 0;
-    for (const ir::Instruction& inst : *spvtest::GetBasicBlock(f, 84)) {
+    for (const opt::Instruction& inst : *spvtest::GetBasicBlock(f, 84)) {
       if (inst.opcode() == SpvOp::SpvOpStore) {
         store[stores_found] = &inst;
         ++stores_found;
@@ -2040,16 +2040,16 @@
   }
   // For the loop in function d
   {
-    const ir::Function* f = spvtest::GetFunction(module, 12);
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
+    const opt::Function* f = spvtest::GetFunction(module, 12);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
 
-    ir::Loop* loop = &ld.GetLoopByIndex(0);
-    std::vector<const ir::Loop*> loops{loop};
+    opt::Loop* loop = &ld.GetLoopByIndex(0);
+    std::vector<const opt::Loop*> loops{loop};
     opt::LoopDependenceAnalysis analysis{context.get(), loops};
 
-    const ir::Instruction* store[4];
+    const opt::Instruction* store[4];
     int stores_found = 0;
-    for (const ir::Instruction& inst : *spvtest::GetBasicBlock(f, 111)) {
+    for (const opt::Instruction& inst : *spvtest::GetBasicBlock(f, 111)) {
       if (inst.opcode() == SpvOp::SpvOpStore) {
         store[stores_found] = &inst;
         ++stores_found;
@@ -2195,22 +2195,22 @@
                OpFunctionEnd
 )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  const ir::Function* f = spvtest::GetFunction(module, 4);
-  ir::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
+  const opt::Function* f = spvtest::GetFunction(module, 4);
+  opt::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
 
-  ir::Loop* loop = &ld.GetLoopByIndex(0);
-  std::vector<const ir::Loop*> loops{loop};
+  opt::Loop* loop = &ld.GetLoopByIndex(0);
+  std::vector<const opt::Loop*> loops{loop};
   opt::LoopDependenceAnalysis analysis{context.get(), loops};
 
-  const ir::Instruction* store[6];
+  const opt::Instruction* store[6];
   int stores_found = 0;
-  for (const ir::Instruction& inst : *spvtest::GetBasicBlock(f, 11)) {
+  for (const opt::Instruction& inst : *spvtest::GetBasicBlock(f, 11)) {
     if (inst.opcode() == SpvOp::SpvOpStore) {
       store[stores_found] = &inst;
       ++stores_found;
@@ -2426,24 +2426,24 @@
                OpFunctionEnd
 )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
   // For the loop in function a
   {
-    const ir::Function* f = spvtest::GetFunction(module, 6);
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
+    const opt::Function* f = spvtest::GetFunction(module, 6);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
 
-    std::vector<const ir::Loop*> loops{&ld.GetLoopByIndex(1),
-                                       &ld.GetLoopByIndex(0)};
+    std::vector<const opt::Loop*> loops{&ld.GetLoopByIndex(1),
+                                        &ld.GetLoopByIndex(0)};
     opt::LoopDependenceAnalysis analysis{context.get(), loops};
 
-    const ir::Instruction* store[1];
+    const opt::Instruction* store[1];
     int stores_found = 0;
-    for (const ir::Instruction& inst : *spvtest::GetBasicBlock(f, 25)) {
+    for (const opt::Instruction& inst : *spvtest::GetBasicBlock(f, 25)) {
       if (inst.opcode() == SpvOp::SpvOpStore) {
         store[stores_found] = &inst;
         ++stores_found;
@@ -2470,16 +2470,16 @@
 
   // For the loop in function b
   {
-    const ir::Function* f = spvtest::GetFunction(module, 8);
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
+    const opt::Function* f = spvtest::GetFunction(module, 8);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
 
-    std::vector<const ir::Loop*> loops{&ld.GetLoopByIndex(1),
-                                       &ld.GetLoopByIndex(0)};
+    std::vector<const opt::Loop*> loops{&ld.GetLoopByIndex(1),
+                                        &ld.GetLoopByIndex(0)};
     opt::LoopDependenceAnalysis analysis{context.get(), loops};
 
-    const ir::Instruction* store[1];
+    const opt::Instruction* store[1];
     int stores_found = 0;
-    for (const ir::Instruction& inst : *spvtest::GetBasicBlock(f, 56)) {
+    for (const opt::Instruction& inst : *spvtest::GetBasicBlock(f, 56)) {
       if (inst.opcode() == SpvOp::SpvOpStore) {
         store[stores_found] = &inst;
         ++stores_found;
@@ -2504,8 +2504,8 @@
   }
 }
 
-void CheckDependenceAndDirection(const ir::Instruction* source,
-                                 const ir::Instruction* destination,
+void CheckDependenceAndDirection(const opt::Instruction* source,
+                                 const opt::Instruction* destination,
                                  bool expected_dependence,
                                  opt::DistanceVector expected_distance,
                                  opt::LoopDependenceAnalysis* analysis) {
@@ -2768,30 +2768,30 @@
                OpFunctionEnd
 )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  const ir::Function* f = spvtest::GetFunction(module, 4);
-  ir::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
+  const opt::Function* f = spvtest::GetFunction(module, 4);
+  opt::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
 
-  std::vector<const ir::Loop*> loops{&ld.GetLoopByIndex(0),
-                                     &ld.GetLoopByIndex(1)};
+  std::vector<const opt::Loop*> loops{&ld.GetLoopByIndex(0),
+                                      &ld.GetLoopByIndex(1)};
 
   opt::LoopDependenceAnalysis analysis{context.get(), loops};
 
   const int instructions_expected = 17;
-  const ir::Instruction* store[instructions_expected];
-  const ir::Instruction* load[instructions_expected];
+  const opt::Instruction* store[instructions_expected];
+  const opt::Instruction* load[instructions_expected];
   int stores_found = 0;
   int loads_found = 0;
 
   int block_id = 36;
   ASSERT_TRUE(spvtest::GetBasicBlock(f, block_id));
 
-  for (const ir::Instruction& inst : *spvtest::GetBasicBlock(f, block_id)) {
+  for (const opt::Instruction& inst : *spvtest::GetBasicBlock(f, block_id)) {
     if (inst.opcode() == SpvOp::SpvOpStore) {
       store[stores_found] = &inst;
       ++stores_found;
@@ -2836,19 +2836,19 @@
                               &analysis);
 }
 
-void PartitionSubscripts(const ir::Instruction* instruction_0,
-                         const ir::Instruction* instruction_1,
+void PartitionSubscripts(const opt::Instruction* instruction_0,
+                         const opt::Instruction* instruction_1,
                          opt::LoopDependenceAnalysis* analysis,
                          std::vector<std::vector<int>> expected_ids) {
   auto subscripts_0 = analysis->GetSubscripts(instruction_0);
   auto subscripts_1 = analysis->GetSubscripts(instruction_1);
 
-  std::vector<std::set<std::pair<ir::Instruction*, ir::Instruction*>>>
+  std::vector<std::set<std::pair<opt::Instruction*, opt::Instruction*>>>
       expected_partition{};
 
   for (const auto& partition : expected_ids) {
     expected_partition.push_back(
-        std::set<std::pair<ir::Instruction*, ir::Instruction*>>{});
+        std::set<std::pair<opt::Instruction*, opt::Instruction*>>{});
     for (auto id : partition) {
       expected_partition.back().insert({subscripts_0[id], subscripts_1[id]});
     }
@@ -3059,30 +3059,30 @@
                OpFunctionEnd
   )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  const ir::Function* f = spvtest::GetFunction(module, 4);
-  ir::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
+  const opt::Function* f = spvtest::GetFunction(module, 4);
+  opt::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
 
-  std::vector<const ir::Loop*> loop_nest{
+  std::vector<const opt::Loop*> loop_nest{
       &ld.GetLoopByIndex(0), &ld.GetLoopByIndex(1), &ld.GetLoopByIndex(2),
       &ld.GetLoopByIndex(3)};
   opt::LoopDependenceAnalysis analysis{context.get(), loop_nest};
 
   const int instructions_expected = 13;
-  const ir::Instruction* store[instructions_expected];
-  const ir::Instruction* load[instructions_expected];
+  const opt::Instruction* store[instructions_expected];
+  const opt::Instruction* load[instructions_expected];
   int stores_found = 0;
   int loads_found = 0;
 
   int block_id = 37;
   ASSERT_TRUE(spvtest::GetBasicBlock(f, block_id));
 
-  for (const ir::Instruction& inst : *spvtest::GetBasicBlock(f, block_id)) {
+  for (const opt::Instruction& inst : *spvtest::GetBasicBlock(f, block_id)) {
     if (inst.opcode() == SpvOp::SpvOpStore) {
       store[stores_found] = &inst;
       ++stores_found;
@@ -3445,25 +3445,25 @@
                OpFunctionEnd
     )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   ASSERT_NE(nullptr, context);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
 
   {
-    const ir::Function* f = spvtest::GetFunction(module, 6);
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
+    const opt::Function* f = spvtest::GetFunction(module, 6);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
 
-    const ir::Instruction* store = nullptr;
-    const ir::Instruction* load = nullptr;
+    const opt::Instruction* store = nullptr;
+    const opt::Instruction* load = nullptr;
 
     int block_id = 31;
     ASSERT_TRUE(spvtest::GetBasicBlock(f, block_id));
 
-    for (const ir::Instruction& inst : *spvtest::GetBasicBlock(f, block_id)) {
+    for (const opt::Instruction& inst : *spvtest::GetBasicBlock(f, block_id)) {
       if (inst.opcode() == SpvOp::SpvOpStore) {
         store = &inst;
       }
@@ -3476,8 +3476,8 @@
     EXPECT_NE(nullptr, store);
     EXPECT_NE(nullptr, load);
 
-    std::vector<const ir::Loop*> loop_nest{&ld.GetLoopByIndex(0),
-                                           &ld.GetLoopByIndex(1)};
+    std::vector<const opt::Loop*> loop_nest{&ld.GetLoopByIndex(0),
+                                            &ld.GetLoopByIndex(1)};
     opt::LoopDependenceAnalysis analysis{context.get(), loop_nest};
 
     opt::DistanceVector dv_entry(loop_nest.size());
@@ -3495,16 +3495,16 @@
   }
 
   {
-    const ir::Function* f = spvtest::GetFunction(module, 8);
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
+    const opt::Function* f = spvtest::GetFunction(module, 8);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
 
-    const ir::Instruction* store = nullptr;
-    const ir::Instruction* load = nullptr;
+    const opt::Instruction* store = nullptr;
+    const opt::Instruction* load = nullptr;
 
     int block_id = 62;
     ASSERT_TRUE(spvtest::GetBasicBlock(f, block_id));
 
-    for (const ir::Instruction& inst : *spvtest::GetBasicBlock(f, block_id)) {
+    for (const opt::Instruction& inst : *spvtest::GetBasicBlock(f, block_id)) {
       if (inst.opcode() == SpvOp::SpvOpStore) {
         store = &inst;
       }
@@ -3517,7 +3517,7 @@
     EXPECT_NE(nullptr, store);
     EXPECT_NE(nullptr, load);
 
-    std::vector<const ir::Loop*> loop_nest{&ld.GetLoopByIndex(0)};
+    std::vector<const opt::Loop*> loop_nest{&ld.GetLoopByIndex(0)};
     opt::LoopDependenceAnalysis analysis{context.get(), loop_nest};
 
     opt::DistanceVector dv_entry(loop_nest.size());
@@ -3527,16 +3527,16 @@
   }
 
   {
-    const ir::Function* f = spvtest::GetFunction(module, 10);
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
+    const opt::Function* f = spvtest::GetFunction(module, 10);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
 
-    const ir::Instruction* store = nullptr;
-    const ir::Instruction* load = nullptr;
+    const opt::Instruction* store = nullptr;
+    const opt::Instruction* load = nullptr;
 
     int block_id = 84;
     ASSERT_TRUE(spvtest::GetBasicBlock(f, block_id));
 
-    for (const ir::Instruction& inst : *spvtest::GetBasicBlock(f, block_id)) {
+    for (const opt::Instruction& inst : *spvtest::GetBasicBlock(f, block_id)) {
       if (inst.opcode() == SpvOp::SpvOpStore) {
         store = &inst;
       }
@@ -3549,7 +3549,7 @@
     EXPECT_NE(nullptr, store);
     EXPECT_NE(nullptr, load);
 
-    std::vector<const ir::Loop*> loop_nest{&ld.GetLoopByIndex(0)};
+    std::vector<const opt::Loop*> loop_nest{&ld.GetLoopByIndex(0)};
     opt::LoopDependenceAnalysis analysis{context.get(), loop_nest};
 
     opt::DistanceVector dv_entry(loop_nest.size());
@@ -3562,16 +3562,16 @@
   }
 
   {
-    const ir::Function* f = spvtest::GetFunction(module, 12);
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
+    const opt::Function* f = spvtest::GetFunction(module, 12);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
 
-    const ir::Instruction* store = nullptr;
-    const ir::Instruction* load = nullptr;
+    const opt::Instruction* store = nullptr;
+    const opt::Instruction* load = nullptr;
 
     int block_id = 119;
     ASSERT_TRUE(spvtest::GetBasicBlock(f, block_id));
 
-    for (const ir::Instruction& inst : *spvtest::GetBasicBlock(f, block_id)) {
+    for (const opt::Instruction& inst : *spvtest::GetBasicBlock(f, block_id)) {
       if (inst.opcode() == SpvOp::SpvOpStore) {
         store = &inst;
       }
@@ -3584,7 +3584,7 @@
     EXPECT_NE(nullptr, store);
     EXPECT_NE(nullptr, load);
 
-    std::vector<const ir::Loop*> loop_nest{
+    std::vector<const opt::Loop*> loop_nest{
         &ld.GetLoopByIndex(0), &ld.GetLoopByIndex(1), &ld.GetLoopByIndex(2)};
     opt::LoopDependenceAnalysis analysis{context.get(), loop_nest};
 
@@ -3604,16 +3604,16 @@
   }
 
   {
-    const ir::Function* f = spvtest::GetFunction(module, 14);
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
+    const opt::Function* f = spvtest::GetFunction(module, 14);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
 
-    const ir::Instruction* store = nullptr;
-    const ir::Instruction* load = nullptr;
+    const opt::Instruction* store = nullptr;
+    const opt::Instruction* load = nullptr;
 
     int block_id = 162;
     ASSERT_TRUE(spvtest::GetBasicBlock(f, block_id));
 
-    for (const ir::Instruction& inst : *spvtest::GetBasicBlock(f, block_id)) {
+    for (const opt::Instruction& inst : *spvtest::GetBasicBlock(f, block_id)) {
       if (inst.opcode() == SpvOp::SpvOpStore) {
         store = &inst;
       }
@@ -3626,8 +3626,8 @@
     EXPECT_NE(nullptr, store);
     EXPECT_NE(nullptr, load);
 
-    std::vector<const ir::Loop*> loop_nest{&ld.GetLoopByIndex(0),
-                                           &ld.GetLoopByIndex(1)};
+    std::vector<const opt::Loop*> loop_nest{&ld.GetLoopByIndex(0),
+                                            &ld.GetLoopByIndex(1)};
     opt::LoopDependenceAnalysis analysis{context.get(), loop_nest};
 
     opt::DistanceVector dv_entry(loop_nest.size());
@@ -3638,7 +3638,8 @@
 }
 
 TEST(DependencyAnalysis, ConstraintIntersection) {
-  opt::LoopDependenceAnalysis analysis{nullptr, std::vector<const ir::Loop*>{}};
+  opt::LoopDependenceAnalysis analysis{nullptr,
+                                       std::vector<const opt::Loop*>{}};
   auto scalar_evolution = analysis.GetScalarEvolution();
   {
     // One is none. Other should be returned
diff --git a/test/opt/loop_optimizations/dependence_analysis_helpers.cpp b/test/opt/loop_optimizations/dependence_analysis_helpers.cpp
index f4c5e27..afadb08 100644
--- a/test/opt/loop_optimizations/dependence_analysis_helpers.cpp
+++ b/test/opt/loop_optimizations/dependence_analysis_helpers.cpp
@@ -155,24 +155,24 @@
                OpReturn
                OpFunctionEnd
 )";
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
   {
     // Function a
-    const ir::Function* f = spvtest::GetFunction(module, 6);
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
+    const opt::Function* f = spvtest::GetFunction(module, 6);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
 
-    ir::Loop* loop = &ld.GetLoopByIndex(0);
-    std::vector<const ir::Loop*> loops{loop};
+    opt::Loop* loop = &ld.GetLoopByIndex(0);
+    std::vector<const opt::Loop*> loops{loop};
     opt::LoopDependenceAnalysis analysis{context.get(), loops};
 
-    const ir::Instruction* store[1] = {nullptr};
+    const opt::Instruction* store[1] = {nullptr};
     int stores_found = 0;
-    for (const ir::Instruction& inst : *spvtest::GetBasicBlock(f, 16)) {
+    for (const opt::Instruction& inst : *spvtest::GetBasicBlock(f, 16)) {
       if (inst.opcode() == SpvOp::SpvOpStore) {
         store[stores_found] = &inst;
         ++stores_found;
@@ -190,16 +190,16 @@
   }
   {
     // Function b
-    const ir::Function* f = spvtest::GetFunction(module, 8);
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
+    const opt::Function* f = spvtest::GetFunction(module, 8);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
 
-    ir::Loop* loop = &ld.GetLoopByIndex(0);
-    std::vector<const ir::Loop*> loops{loop};
+    opt::Loop* loop = &ld.GetLoopByIndex(0);
+    std::vector<const opt::Loop*> loops{loop};
     opt::LoopDependenceAnalysis analysis{context.get(), loops};
 
-    const ir::Instruction* store[1] = {nullptr};
+    const opt::Instruction* store[1] = {nullptr};
     int stores_found = 0;
-    for (const ir::Instruction& inst : *spvtest::GetBasicBlock(f, 47)) {
+    for (const opt::Instruction& inst : *spvtest::GetBasicBlock(f, 47)) {
       if (inst.opcode() == SpvOp::SpvOpStore) {
         store[stores_found] = &inst;
         ++stores_found;
@@ -729,18 +729,18 @@
                OpReturn
                OpFunctionEnd
 )";
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
   {
     // Function a
-    const ir::Function* f = spvtest::GetFunction(module, 6);
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
-    ir::Loop* loop = &ld.GetLoopByIndex(0);
-    std::vector<const ir::Loop*> loops{loop};
+    const opt::Function* f = spvtest::GetFunction(module, 6);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
+    opt::Loop* loop = &ld.GetLoopByIndex(0);
+    std::vector<const opt::Loop*> loops{loop};
     opt::LoopDependenceAnalysis analysis{context.get(), loops};
 
     EXPECT_EQ(
@@ -763,10 +763,10 @@
   }
   {
     // Function b
-    const ir::Function* f = spvtest::GetFunction(module, 8);
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
-    ir::Loop* loop = &ld.GetLoopByIndex(0);
-    std::vector<const ir::Loop*> loops{loop};
+    const opt::Function* f = spvtest::GetFunction(module, 8);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
+    opt::Loop* loop = &ld.GetLoopByIndex(0);
+    std::vector<const opt::Loop*> loops{loop};
     opt::LoopDependenceAnalysis analysis{context.get(), loops};
 
     EXPECT_EQ(
@@ -789,10 +789,10 @@
   }
   {
     // Function c
-    const ir::Function* f = spvtest::GetFunction(module, 10);
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
-    ir::Loop* loop = &ld.GetLoopByIndex(0);
-    std::vector<const ir::Loop*> loops{loop};
+    const opt::Function* f = spvtest::GetFunction(module, 10);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
+    opt::Loop* loop = &ld.GetLoopByIndex(0);
+    std::vector<const opt::Loop*> loops{loop};
     opt::LoopDependenceAnalysis analysis{context.get(), loops};
 
     EXPECT_EQ(
@@ -815,10 +815,10 @@
   }
   {
     // Function d
-    const ir::Function* f = spvtest::GetFunction(module, 12);
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
-    ir::Loop* loop = &ld.GetLoopByIndex(0);
-    std::vector<const ir::Loop*> loops{loop};
+    const opt::Function* f = spvtest::GetFunction(module, 12);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
+    opt::Loop* loop = &ld.GetLoopByIndex(0);
+    std::vector<const opt::Loop*> loops{loop};
     opt::LoopDependenceAnalysis analysis{context.get(), loops};
 
     EXPECT_EQ(
@@ -841,10 +841,10 @@
   }
   {
     // Function e
-    const ir::Function* f = spvtest::GetFunction(module, 14);
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
-    ir::Loop* loop = &ld.GetLoopByIndex(0);
-    std::vector<const ir::Loop*> loops{loop};
+    const opt::Function* f = spvtest::GetFunction(module, 14);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
+    opt::Loop* loop = &ld.GetLoopByIndex(0);
+    std::vector<const opt::Loop*> loops{loop};
     opt::LoopDependenceAnalysis analysis{context.get(), loops};
 
     EXPECT_EQ(
@@ -867,10 +867,10 @@
   }
   {
     // Function f
-    const ir::Function* f = spvtest::GetFunction(module, 16);
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
-    ir::Loop* loop = &ld.GetLoopByIndex(0);
-    std::vector<const ir::Loop*> loops{loop};
+    const opt::Function* f = spvtest::GetFunction(module, 16);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
+    opt::Loop* loop = &ld.GetLoopByIndex(0);
+    std::vector<const opt::Loop*> loops{loop};
     opt::LoopDependenceAnalysis analysis{context.get(), loops};
 
     EXPECT_EQ(
@@ -893,10 +893,10 @@
   }
   {
     // Function g
-    const ir::Function* f = spvtest::GetFunction(module, 18);
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
-    ir::Loop* loop = &ld.GetLoopByIndex(0);
-    std::vector<const ir::Loop*> loops{loop};
+    const opt::Function* f = spvtest::GetFunction(module, 18);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
+    opt::Loop* loop = &ld.GetLoopByIndex(0);
+    std::vector<const opt::Loop*> loops{loop};
     opt::LoopDependenceAnalysis analysis{context.get(), loops};
 
     EXPECT_EQ(
@@ -919,10 +919,10 @@
   }
   {
     // Function h
-    const ir::Function* f = spvtest::GetFunction(module, 20);
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
-    ir::Loop* loop = &ld.GetLoopByIndex(0);
-    std::vector<const ir::Loop*> loops{loop};
+    const opt::Function* f = spvtest::GetFunction(module, 20);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
+    opt::Loop* loop = &ld.GetLoopByIndex(0);
+    std::vector<const opt::Loop*> loops{loop};
     opt::LoopDependenceAnalysis analysis{context.get(), loops};
 
     EXPECT_EQ(
@@ -945,10 +945,10 @@
   }
   {
     // Function i
-    const ir::Function* f = spvtest::GetFunction(module, 22);
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
-    ir::Loop* loop = &ld.GetLoopByIndex(0);
-    std::vector<const ir::Loop*> loops{loop};
+    const opt::Function* f = spvtest::GetFunction(module, 22);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
+    opt::Loop* loop = &ld.GetLoopByIndex(0);
+    std::vector<const opt::Loop*> loops{loop};
     opt::LoopDependenceAnalysis analysis{context.get(), loops};
 
     EXPECT_EQ(
@@ -971,10 +971,10 @@
   }
   {
     // Function j
-    const ir::Function* f = spvtest::GetFunction(module, 24);
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
-    ir::Loop* loop = &ld.GetLoopByIndex(0);
-    std::vector<const ir::Loop*> loops{loop};
+    const opt::Function* f = spvtest::GetFunction(module, 24);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
+    opt::Loop* loop = &ld.GetLoopByIndex(0);
+    std::vector<const opt::Loop*> loops{loop};
     opt::LoopDependenceAnalysis analysis{context.get(), loops};
 
     EXPECT_EQ(
@@ -997,10 +997,10 @@
   }
   {
     // Function k
-    const ir::Function* f = spvtest::GetFunction(module, 26);
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
-    ir::Loop* loop = &ld.GetLoopByIndex(0);
-    std::vector<const ir::Loop*> loops{loop};
+    const opt::Function* f = spvtest::GetFunction(module, 26);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
+    opt::Loop* loop = &ld.GetLoopByIndex(0);
+    std::vector<const opt::Loop*> loops{loop};
     opt::LoopDependenceAnalysis analysis{context.get(), loops};
 
     EXPECT_EQ(
@@ -1023,10 +1023,10 @@
   }
   {
     // Function l
-    const ir::Function* f = spvtest::GetFunction(module, 28);
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
-    ir::Loop* loop = &ld.GetLoopByIndex(0);
-    std::vector<const ir::Loop*> loops{loop};
+    const opt::Function* f = spvtest::GetFunction(module, 28);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
+    opt::Loop* loop = &ld.GetLoopByIndex(0);
+    std::vector<const opt::Loop*> loops{loop};
     opt::LoopDependenceAnalysis analysis{context.get(), loops};
 
     EXPECT_EQ(
@@ -1049,10 +1049,10 @@
   }
   {
     // Function m
-    const ir::Function* f = spvtest::GetFunction(module, 30);
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
-    ir::Loop* loop = &ld.GetLoopByIndex(0);
-    std::vector<const ir::Loop*> loops{loop};
+    const opt::Function* f = spvtest::GetFunction(module, 30);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
+    opt::Loop* loop = &ld.GetLoopByIndex(0);
+    std::vector<const opt::Loop*> loops{loop};
     opt::LoopDependenceAnalysis analysis{context.get(), loops};
 
     EXPECT_EQ(
@@ -1075,10 +1075,10 @@
   }
   {
     // Function n
-    const ir::Function* f = spvtest::GetFunction(module, 32);
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
-    ir::Loop* loop = &ld.GetLoopByIndex(0);
-    std::vector<const ir::Loop*> loops{loop};
+    const opt::Function* f = spvtest::GetFunction(module, 32);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
+    opt::Loop* loop = &ld.GetLoopByIndex(0);
+    std::vector<const opt::Loop*> loops{loop};
     opt::LoopDependenceAnalysis analysis{context.get(), loops};
 
     EXPECT_EQ(
@@ -1101,10 +1101,10 @@
   }
   {
     // Function o
-    const ir::Function* f = spvtest::GetFunction(module, 34);
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
-    ir::Loop* loop = &ld.GetLoopByIndex(0);
-    std::vector<const ir::Loop*> loops{loop};
+    const opt::Function* f = spvtest::GetFunction(module, 34);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
+    opt::Loop* loop = &ld.GetLoopByIndex(0);
+    std::vector<const opt::Loop*> loops{loop};
     opt::LoopDependenceAnalysis analysis{context.get(), loops};
 
     EXPECT_EQ(
@@ -1127,10 +1127,10 @@
   }
   {
     // Function p
-    const ir::Function* f = spvtest::GetFunction(module, 36);
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
-    ir::Loop* loop = &ld.GetLoopByIndex(0);
-    std::vector<const ir::Loop*> loops{loop};
+    const opt::Function* f = spvtest::GetFunction(module, 36);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
+    opt::Loop* loop = &ld.GetLoopByIndex(0);
+    std::vector<const opt::Loop*> loops{loop};
     opt::LoopDependenceAnalysis analysis{context.get(), loops};
 
     EXPECT_EQ(
@@ -1202,18 +1202,18 @@
                OpReturn
                OpFunctionEnd
 )";
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
   // We need a shader that includes a loop for this test so we can build a
   // LoopDependenceAnalaysis
-  const ir::Function* f = spvtest::GetFunction(module, 4);
-  ir::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
-  ir::Loop* loop = &ld.GetLoopByIndex(0);
-  std::vector<const ir::Loop*> loops{loop};
+  const opt::Function* f = spvtest::GetFunction(module, 4);
+  opt::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
+  opt::Loop* loop = &ld.GetLoopByIndex(0);
+  std::vector<const opt::Loop*> loops{loop};
   opt::LoopDependenceAnalysis analysis{context.get(), loops};
 
   EXPECT_TRUE(analysis.IsWithinBounds(0, 0, 0));
@@ -1478,24 +1478,24 @@
                OpReturn
                OpFunctionEnd
 )";
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
 
   {
     // Function a
-    const ir::Function* f = spvtest::GetFunction(module, 6);
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
-    ir::Loop* loop = &ld.GetLoopByIndex(0);
-    std::vector<const ir::Loop*> loops{loop};
+    const opt::Function* f = spvtest::GetFunction(module, 6);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
+    opt::Loop* loop = &ld.GetLoopByIndex(0);
+    std::vector<const opt::Loop*> loops{loop};
     opt::LoopDependenceAnalysis analysis{context.get(), loops};
 
-    const ir::Instruction* stores[2];
+    const opt::Instruction* stores[2];
     int stores_found = 0;
-    for (const ir::Instruction& inst : *spvtest::GetBasicBlock(f, 30)) {
+    for (const opt::Instruction& inst : *spvtest::GetBasicBlock(f, 30)) {
       if (inst.opcode() == SpvOp::SpvOpStore) {
         stores[stores_found] = &inst;
         ++stores_found;
@@ -1510,7 +1510,7 @@
     {
       // Analyse and simplify the instruction behind the access chain of this
       // load.
-      ir::Instruction* load_var = context->get_def_use_mgr()->GetDef(
+      opt::Instruction* load_var = context->get_def_use_mgr()->GetDef(
           context->get_def_use_mgr()
               ->GetDef(context->get_def_use_mgr()
                            ->GetDef(47)
@@ -1521,7 +1521,7 @@
 
       // Analyse and simplify the instruction behind the access chain of this
       // store.
-      ir::Instruction* store_var = context->get_def_use_mgr()->GetDef(
+      opt::Instruction* store_var = context->get_def_use_mgr()->GetDef(
           context->get_def_use_mgr()
               ->GetDef(stores[0]->GetSingleWordInOperand(0))
               ->GetSingleWordInOperand(1));
@@ -1540,7 +1540,7 @@
     {
       // Analyse and simplify the instruction behind the access chain of this
       // load.
-      ir::Instruction* load_var = context->get_def_use_mgr()->GetDef(
+      opt::Instruction* load_var = context->get_def_use_mgr()->GetDef(
           context->get_def_use_mgr()
               ->GetDef(context->get_def_use_mgr()
                            ->GetDef(54)
@@ -1551,7 +1551,7 @@
 
       // Analyse and simplify the instruction behind the access chain of this
       // store.
-      ir::Instruction* store_var = context->get_def_use_mgr()->GetDef(
+      opt::Instruction* store_var = context->get_def_use_mgr()->GetDef(
           context->get_def_use_mgr()
               ->GetDef(stores[1]->GetSingleWordInOperand(0))
               ->GetSingleWordInOperand(1));
@@ -1568,15 +1568,15 @@
   }
   {
     // Function b
-    const ir::Function* f = spvtest::GetFunction(module, 8);
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
-    ir::Loop* loop = &ld.GetLoopByIndex(0);
-    std::vector<const ir::Loop*> loops{loop};
+    const opt::Function* f = spvtest::GetFunction(module, 8);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
+    opt::Loop* loop = &ld.GetLoopByIndex(0);
+    std::vector<const opt::Loop*> loops{loop};
     opt::LoopDependenceAnalysis analysis{context.get(), loops};
 
-    const ir::Instruction* stores[2];
+    const opt::Instruction* stores[2];
     int stores_found = 0;
-    for (const ir::Instruction& inst : *spvtest::GetBasicBlock(f, 65)) {
+    for (const opt::Instruction& inst : *spvtest::GetBasicBlock(f, 65)) {
       if (inst.opcode() == SpvOp::SpvOpStore) {
         stores[stores_found] = &inst;
         ++stores_found;
@@ -1591,7 +1591,7 @@
     {
       // Analyse and simplify the instruction behind the access chain of this
       // load.
-      ir::Instruction* load_var = context->get_def_use_mgr()->GetDef(
+      opt::Instruction* load_var = context->get_def_use_mgr()->GetDef(
           context->get_def_use_mgr()
               ->GetDef(context->get_def_use_mgr()
                            ->GetDef(78)
@@ -1601,7 +1601,7 @@
           analysis.GetScalarEvolution()->AnalyzeInstruction(load_var));
       // Analyse and simplify the instruction behind the access chain of this
       // store.
-      ir::Instruction* store_var = context->get_def_use_mgr()->GetDef(
+      opt::Instruction* store_var = context->get_def_use_mgr()->GetDef(
           context->get_def_use_mgr()
               ->GetDef(stores[0]->GetSingleWordInOperand(0))
               ->GetSingleWordInOperand(1));
@@ -1620,7 +1620,7 @@
     {
       // Analyse and simplify the instruction behind the access chain of this
       // load.
-      ir::Instruction* load_var = context->get_def_use_mgr()->GetDef(
+      opt::Instruction* load_var = context->get_def_use_mgr()->GetDef(
           context->get_def_use_mgr()
               ->GetDef(context->get_def_use_mgr()
                            ->GetDef(85)
@@ -1630,7 +1630,7 @@
           analysis.GetScalarEvolution()->AnalyzeInstruction(load_var));
       // Analyse and simplify the instruction behind the access chain of this
       // store.
-      ir::Instruction* store_var = context->get_def_use_mgr()->GetDef(
+      opt::Instruction* store_var = context->get_def_use_mgr()->GetDef(
           context->get_def_use_mgr()
               ->GetDef(stores[1]->GetSingleWordInOperand(0))
               ->GetSingleWordInOperand(1));
@@ -1647,15 +1647,15 @@
   }
   {
     // Function c
-    const ir::Function* f = spvtest::GetFunction(module, 10);
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
-    ir::Loop* loop = &ld.GetLoopByIndex(0);
-    std::vector<const ir::Loop*> loops{loop};
+    const opt::Function* f = spvtest::GetFunction(module, 10);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
+    opt::Loop* loop = &ld.GetLoopByIndex(0);
+    std::vector<const opt::Loop*> loops{loop};
     opt::LoopDependenceAnalysis analysis{context.get(), loops};
 
-    const ir::Instruction* stores[2];
+    const opt::Instruction* stores[2];
     int stores_found = 0;
-    for (const ir::Instruction& inst : *spvtest::GetBasicBlock(f, 96)) {
+    for (const opt::Instruction& inst : *spvtest::GetBasicBlock(f, 96)) {
       if (inst.opcode() == SpvOp::SpvOpStore) {
         stores[stores_found] = &inst;
         ++stores_found;
@@ -1670,7 +1670,7 @@
     {
       // Analyse and simplify the instruction behind the access chain of this
       // load.
-      ir::Instruction* load_var = context->get_def_use_mgr()->GetDef(
+      opt::Instruction* load_var = context->get_def_use_mgr()->GetDef(
           context->get_def_use_mgr()
               ->GetDef(context->get_def_use_mgr()
                            ->GetDef(109)
@@ -1680,7 +1680,7 @@
           analysis.GetScalarEvolution()->AnalyzeInstruction(load_var));
       // Analyse and simplify the instruction behind the access chain of this
       // store.
-      ir::Instruction* store_var = context->get_def_use_mgr()->GetDef(
+      opt::Instruction* store_var = context->get_def_use_mgr()->GetDef(
           context->get_def_use_mgr()
               ->GetDef(stores[0]->GetSingleWordInOperand(0))
               ->GetSingleWordInOperand(1));
@@ -1699,7 +1699,7 @@
     {
       // Analyse and simplify the instruction behind the access chain of this
       // load.
-      ir::Instruction* load_var = context->get_def_use_mgr()->GetDef(
+      opt::Instruction* load_var = context->get_def_use_mgr()->GetDef(
           context->get_def_use_mgr()
               ->GetDef(context->get_def_use_mgr()
                            ->GetDef(116)
@@ -1709,7 +1709,7 @@
           analysis.GetScalarEvolution()->AnalyzeInstruction(load_var));
       // Analyse and simplify the instruction behind the access chain of this
       // store.
-      ir::Instruction* store_var = context->get_def_use_mgr()->GetDef(
+      opt::Instruction* store_var = context->get_def_use_mgr()->GetDef(
           context->get_def_use_mgr()
               ->GetDef(stores[1]->GetSingleWordInOperand(0))
               ->GetSingleWordInOperand(1));
@@ -1726,15 +1726,15 @@
   }
   {
     // Function d
-    const ir::Function* f = spvtest::GetFunction(module, 12);
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
-    ir::Loop* loop = &ld.GetLoopByIndex(0);
-    std::vector<const ir::Loop*> loops{loop};
+    const opt::Function* f = spvtest::GetFunction(module, 12);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
+    opt::Loop* loop = &ld.GetLoopByIndex(0);
+    std::vector<const opt::Loop*> loops{loop};
     opt::LoopDependenceAnalysis analysis{context.get(), loops};
 
-    const ir::Instruction* stores[2];
+    const opt::Instruction* stores[2];
     int stores_found = 0;
-    for (const ir::Instruction& inst : *spvtest::GetBasicBlock(f, 126)) {
+    for (const opt::Instruction& inst : *spvtest::GetBasicBlock(f, 126)) {
       if (inst.opcode() == SpvOp::SpvOpStore) {
         stores[stores_found] = &inst;
         ++stores_found;
@@ -1749,7 +1749,7 @@
     {
       // Analyse and simplify the instruction behind the access chain of this
       // load.
-      ir::Instruction* load_var = context->get_def_use_mgr()->GetDef(
+      opt::Instruction* load_var = context->get_def_use_mgr()->GetDef(
           context->get_def_use_mgr()
               ->GetDef(context->get_def_use_mgr()
                            ->GetDef(139)
@@ -1759,7 +1759,7 @@
           analysis.GetScalarEvolution()->AnalyzeInstruction(load_var));
       // Analyse and simplify the instruction behind the access chain of this
       // store.
-      ir::Instruction* store_var = context->get_def_use_mgr()->GetDef(
+      opt::Instruction* store_var = context->get_def_use_mgr()->GetDef(
           context->get_def_use_mgr()
               ->GetDef(stores[0]->GetSingleWordInOperand(0))
               ->GetSingleWordInOperand(1));
@@ -1778,7 +1778,7 @@
     {
       // Analyse and simplify the instruction behind the access chain of this
       // load.
-      ir::Instruction* load_var = context->get_def_use_mgr()->GetDef(
+      opt::Instruction* load_var = context->get_def_use_mgr()->GetDef(
           context->get_def_use_mgr()
               ->GetDef(context->get_def_use_mgr()
                            ->GetDef(146)
@@ -1788,7 +1788,7 @@
           analysis.GetScalarEvolution()->AnalyzeInstruction(load_var));
       // Analyse and simplify the instruction behind the access chain of this
       // store.
-      ir::Instruction* store_var = context->get_def_use_mgr()->GetDef(
+      opt::Instruction* store_var = context->get_def_use_mgr()->GetDef(
           context->get_def_use_mgr()
               ->GetDef(stores[1]->GetSingleWordInOperand(0))
               ->GetSingleWordInOperand(1));
@@ -2051,23 +2051,23 @@
                OpReturn
                OpFunctionEnd
 )";
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
   {
     // Function a
-    const ir::Function* f = spvtest::GetFunction(module, 6);
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
-    ir::Loop* loop = &ld.GetLoopByIndex(0);
-    std::vector<const ir::Loop*> loops{loop};
+    const opt::Function* f = spvtest::GetFunction(module, 6);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
+    opt::Loop* loop = &ld.GetLoopByIndex(0);
+    std::vector<const opt::Loop*> loops{loop};
     opt::LoopDependenceAnalysis analysis{context.get(), loops};
 
-    const ir::Instruction* stores[2];
+    const opt::Instruction* stores[2];
     int stores_found = 0;
-    for (const ir::Instruction& inst : *spvtest::GetBasicBlock(f, 30)) {
+    for (const opt::Instruction& inst : *spvtest::GetBasicBlock(f, 30)) {
       if (inst.opcode() == SpvOp::SpvOpStore) {
         stores[stores_found] = &inst;
         ++stores_found;
@@ -2082,7 +2082,7 @@
     {
       // Analyse and simplify the instruction behind the access chain of this
       // load.
-      ir::Instruction* load_var = context->get_def_use_mgr()->GetDef(
+      opt::Instruction* load_var = context->get_def_use_mgr()->GetDef(
           context->get_def_use_mgr()
               ->GetDef(context->get_def_use_mgr()
                            ->GetDef(47)
@@ -2093,7 +2093,7 @@
 
       // Analyse and simplify the instruction behind the access chain of this
       // store.
-      ir::Instruction* store_var = context->get_def_use_mgr()->GetDef(
+      opt::Instruction* store_var = context->get_def_use_mgr()->GetDef(
           context->get_def_use_mgr()
               ->GetDef(stores[0]->GetSingleWordInOperand(0))
               ->GetSingleWordInOperand(1));
@@ -2112,7 +2112,7 @@
     {
       // Analyse and simplify the instruction behind the access chain of this
       // load.
-      ir::Instruction* load_var = context->get_def_use_mgr()->GetDef(
+      opt::Instruction* load_var = context->get_def_use_mgr()->GetDef(
           context->get_def_use_mgr()
               ->GetDef(context->get_def_use_mgr()
                            ->GetDef(54)
@@ -2123,7 +2123,7 @@
 
       // Analyse and simplify the instruction behind the access chain of this
       // store.
-      ir::Instruction* store_var = context->get_def_use_mgr()->GetDef(
+      opt::Instruction* store_var = context->get_def_use_mgr()->GetDef(
           context->get_def_use_mgr()
               ->GetDef(stores[1]->GetSingleWordInOperand(0))
               ->GetSingleWordInOperand(1));
@@ -2140,15 +2140,15 @@
   }
   {
     // Function b
-    const ir::Function* f = spvtest::GetFunction(module, 8);
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
-    ir::Loop* loop = &ld.GetLoopByIndex(0);
-    std::vector<const ir::Loop*> loops{loop};
+    const opt::Function* f = spvtest::GetFunction(module, 8);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
+    opt::Loop* loop = &ld.GetLoopByIndex(0);
+    std::vector<const opt::Loop*> loops{loop};
     opt::LoopDependenceAnalysis analysis{context.get(), loops};
 
-    const ir::Instruction* stores[2];
+    const opt::Instruction* stores[2];
     int stores_found = 0;
-    for (const ir::Instruction& inst : *spvtest::GetBasicBlock(f, 66)) {
+    for (const opt::Instruction& inst : *spvtest::GetBasicBlock(f, 66)) {
       if (inst.opcode() == SpvOp::SpvOpStore) {
         stores[stores_found] = &inst;
         ++stores_found;
@@ -2163,7 +2163,7 @@
     {
       // Analyse and simplify the instruction behind the access chain of this
       // load.
-      ir::Instruction* load_var = context->get_def_use_mgr()->GetDef(
+      opt::Instruction* load_var = context->get_def_use_mgr()->GetDef(
           context->get_def_use_mgr()
               ->GetDef(context->get_def_use_mgr()
                            ->GetDef(78)
@@ -2174,7 +2174,7 @@
 
       // Analyse and simplify the instruction behind the access chain of this
       // store.
-      ir::Instruction* store_var = context->get_def_use_mgr()->GetDef(
+      opt::Instruction* store_var = context->get_def_use_mgr()->GetDef(
           context->get_def_use_mgr()
               ->GetDef(stores[0]->GetSingleWordInOperand(0))
               ->GetSingleWordInOperand(1));
@@ -2193,7 +2193,7 @@
     {
       // Analyse and simplify the instruction behind the access chain of this
       // load.
-      ir::Instruction* load_var = context->get_def_use_mgr()->GetDef(
+      opt::Instruction* load_var = context->get_def_use_mgr()->GetDef(
           context->get_def_use_mgr()
               ->GetDef(context->get_def_use_mgr()
                            ->GetDef(85)
@@ -2204,7 +2204,7 @@
 
       // Analyse and simplify the instruction behind the access chain of this
       // store.
-      ir::Instruction* store_var = context->get_def_use_mgr()->GetDef(
+      opt::Instruction* store_var = context->get_def_use_mgr()->GetDef(
           context->get_def_use_mgr()
               ->GetDef(stores[1]->GetSingleWordInOperand(0))
               ->GetSingleWordInOperand(1));
@@ -2221,15 +2221,15 @@
   }
   {
     // Function c
-    const ir::Function* f = spvtest::GetFunction(module, 10);
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
-    ir::Loop* loop = &ld.GetLoopByIndex(0);
-    std::vector<const ir::Loop*> loops{loop};
+    const opt::Function* f = spvtest::GetFunction(module, 10);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
+    opt::Loop* loop = &ld.GetLoopByIndex(0);
+    std::vector<const opt::Loop*> loops{loop};
     opt::LoopDependenceAnalysis analysis{context.get(), loops};
 
-    const ir::Instruction* stores[2];
+    const opt::Instruction* stores[2];
     int stores_found = 0;
-    for (const ir::Instruction& inst : *spvtest::GetBasicBlock(f, 96)) {
+    for (const opt::Instruction& inst : *spvtest::GetBasicBlock(f, 96)) {
       if (inst.opcode() == SpvOp::SpvOpStore) {
         stores[stores_found] = &inst;
         ++stores_found;
@@ -2244,7 +2244,7 @@
     {
       // Analyse and simplify the instruction behind the access chain of this
       // load.
-      ir::Instruction* load_var = context->get_def_use_mgr()->GetDef(
+      opt::Instruction* load_var = context->get_def_use_mgr()->GetDef(
           context->get_def_use_mgr()
               ->GetDef(context->get_def_use_mgr()
                            ->GetDef(109)
@@ -2255,7 +2255,7 @@
 
       // Analyse and simplify the instruction behind the access chain of this
       // store.
-      ir::Instruction* store_var = context->get_def_use_mgr()->GetDef(
+      opt::Instruction* store_var = context->get_def_use_mgr()->GetDef(
           context->get_def_use_mgr()
               ->GetDef(stores[0]->GetSingleWordInOperand(0))
               ->GetSingleWordInOperand(1));
@@ -2274,7 +2274,7 @@
     {
       // Analyse and simplify the instruction behind the access chain of this
       // load.
-      ir::Instruction* load_var = context->get_def_use_mgr()->GetDef(
+      opt::Instruction* load_var = context->get_def_use_mgr()->GetDef(
           context->get_def_use_mgr()
               ->GetDef(context->get_def_use_mgr()
                            ->GetDef(116)
@@ -2285,7 +2285,7 @@
 
       // Analyse and simplify the instruction behind the access chain of this
       // store.
-      ir::Instruction* store_var = context->get_def_use_mgr()->GetDef(
+      opt::Instruction* store_var = context->get_def_use_mgr()->GetDef(
           context->get_def_use_mgr()
               ->GetDef(stores[1]->GetSingleWordInOperand(0))
               ->GetSingleWordInOperand(1));
@@ -2302,15 +2302,15 @@
   }
   {
     // Function d
-    const ir::Function* f = spvtest::GetFunction(module, 12);
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
-    ir::Loop* loop = &ld.GetLoopByIndex(0);
-    std::vector<const ir::Loop*> loops{loop};
+    const opt::Function* f = spvtest::GetFunction(module, 12);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
+    opt::Loop* loop = &ld.GetLoopByIndex(0);
+    std::vector<const opt::Loop*> loops{loop};
     opt::LoopDependenceAnalysis analysis{context.get(), loops};
 
-    const ir::Instruction* stores[2];
+    const opt::Instruction* stores[2];
     int stores_found = 0;
-    for (const ir::Instruction& inst : *spvtest::GetBasicBlock(f, 127)) {
+    for (const opt::Instruction& inst : *spvtest::GetBasicBlock(f, 127)) {
       if (inst.opcode() == SpvOp::SpvOpStore) {
         stores[stores_found] = &inst;
         ++stores_found;
@@ -2325,7 +2325,7 @@
     {
       // Analyse and simplify the instruction behind the access chain of this
       // load.
-      ir::Instruction* load_var = context->get_def_use_mgr()->GetDef(
+      opt::Instruction* load_var = context->get_def_use_mgr()->GetDef(
           context->get_def_use_mgr()
               ->GetDef(context->get_def_use_mgr()
                            ->GetDef(139)
@@ -2336,7 +2336,7 @@
 
       // Analyse and simplify the instruction behind the access chain of this
       // store.
-      ir::Instruction* store_var = context->get_def_use_mgr()->GetDef(
+      opt::Instruction* store_var = context->get_def_use_mgr()->GetDef(
           context->get_def_use_mgr()
               ->GetDef(stores[0]->GetSingleWordInOperand(0))
               ->GetSingleWordInOperand(1));
@@ -2355,7 +2355,7 @@
     {
       // Analyse and simplify the instruction behind the access chain of this
       // load.
-      ir::Instruction* load_var = context->get_def_use_mgr()->GetDef(
+      opt::Instruction* load_var = context->get_def_use_mgr()->GetDef(
           context->get_def_use_mgr()
               ->GetDef(context->get_def_use_mgr()
                            ->GetDef(146)
@@ -2366,7 +2366,7 @@
 
       // Analyse and simplify the instruction behind the access chain of this
       // store.
-      ir::Instruction* store_var = context->get_def_use_mgr()->GetDef(
+      opt::Instruction* store_var = context->get_def_use_mgr()->GetDef(
           context->get_def_use_mgr()
               ->GetDef(stores[1]->GetSingleWordInOperand(0))
               ->GetSingleWordInOperand(1));
@@ -2689,23 +2689,23 @@
                OpReturn
                OpFunctionEnd
 )";
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
   {
     // Function a
-    const ir::Function* f = spvtest::GetFunction(module, 6);
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
-    ir::Loop* loop = &ld.GetLoopByIndex(0);
-    std::vector<const ir::Loop*> loops{loop};
+    const opt::Function* f = spvtest::GetFunction(module, 6);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
+    opt::Loop* loop = &ld.GetLoopByIndex(0);
+    std::vector<const opt::Loop*> loops{loop};
     opt::LoopDependenceAnalysis analysis{context.get(), loops};
 
-    const ir::Instruction* stores[2];
+    const opt::Instruction* stores[2];
     int stores_found = 0;
-    for (const ir::Instruction& inst : *spvtest::GetBasicBlock(f, 35)) {
+    for (const opt::Instruction& inst : *spvtest::GetBasicBlock(f, 35)) {
       if (inst.opcode() == SpvOp::SpvOpStore) {
         stores[stores_found] = &inst;
         ++stores_found;
@@ -2720,7 +2720,7 @@
     {
       // Analyse and simplify the instruction behind the access chain of this
       // load.
-      ir::Instruction* load_var = context->get_def_use_mgr()->GetDef(
+      opt::Instruction* load_var = context->get_def_use_mgr()->GetDef(
           context->get_def_use_mgr()
               ->GetDef(context->get_def_use_mgr()
                            ->GetDef(60)
@@ -2731,7 +2731,7 @@
 
       // Analyse and simplify the instruction behind the access chain of this
       // store.
-      ir::Instruction* store_var = context->get_def_use_mgr()->GetDef(
+      opt::Instruction* store_var = context->get_def_use_mgr()->GetDef(
           context->get_def_use_mgr()
               ->GetDef(stores[0]->GetSingleWordInOperand(0))
               ->GetSingleWordInOperand(1));
@@ -2749,7 +2749,7 @@
     {
       // Analyse and simplify the instruction behind the access chain of this
       // load.
-      ir::Instruction* load_var = context->get_def_use_mgr()->GetDef(
+      opt::Instruction* load_var = context->get_def_use_mgr()->GetDef(
           context->get_def_use_mgr()
               ->GetDef(context->get_def_use_mgr()
                            ->GetDef(74)
@@ -2760,7 +2760,7 @@
 
       // Analyse and simplify the instruction behind the access chain of this
       // store.
-      ir::Instruction* store_var = context->get_def_use_mgr()->GetDef(
+      opt::Instruction* store_var = context->get_def_use_mgr()->GetDef(
           context->get_def_use_mgr()
               ->GetDef(stores[1]->GetSingleWordInOperand(0))
               ->GetSingleWordInOperand(1));
@@ -2776,15 +2776,15 @@
   }
   {
     // Function b
-    const ir::Function* f = spvtest::GetFunction(module, 8);
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
-    ir::Loop* loop = &ld.GetLoopByIndex(0);
-    std::vector<const ir::Loop*> loops{loop};
+    const opt::Function* f = spvtest::GetFunction(module, 8);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
+    opt::Loop* loop = &ld.GetLoopByIndex(0);
+    std::vector<const opt::Loop*> loops{loop};
     opt::LoopDependenceAnalysis analysis{context.get(), loops};
 
-    const ir::Instruction* stores[2];
+    const opt::Instruction* stores[2];
     int stores_found = 0;
-    for (const ir::Instruction& inst : *spvtest::GetBasicBlock(f, 90)) {
+    for (const opt::Instruction& inst : *spvtest::GetBasicBlock(f, 90)) {
       if (inst.opcode() == SpvOp::SpvOpStore) {
         stores[stores_found] = &inst;
         ++stores_found;
@@ -2799,7 +2799,7 @@
     {
       // Analyse and simplify the instruction behind the access chain of this
       // load.
-      ir::Instruction* load_var = context->get_def_use_mgr()->GetDef(
+      opt::Instruction* load_var = context->get_def_use_mgr()->GetDef(
           context->get_def_use_mgr()
               ->GetDef(context->get_def_use_mgr()
                            ->GetDef(110)
@@ -2810,7 +2810,7 @@
 
       // Analyse and simplify the instruction behind the access chain of this
       // store.
-      ir::Instruction* store_var = context->get_def_use_mgr()->GetDef(
+      opt::Instruction* store_var = context->get_def_use_mgr()->GetDef(
           context->get_def_use_mgr()
               ->GetDef(stores[0]->GetSingleWordInOperand(0))
               ->GetSingleWordInOperand(1));
@@ -2828,7 +2828,7 @@
     {
       // Analyse and simplify the instruction behind the access chain of this
       // load.
-      ir::Instruction* load_var = context->get_def_use_mgr()->GetDef(
+      opt::Instruction* load_var = context->get_def_use_mgr()->GetDef(
           context->get_def_use_mgr()
               ->GetDef(context->get_def_use_mgr()
                            ->GetDef(124)
@@ -2839,7 +2839,7 @@
 
       // Analyse and simplify the instruction behind the access chain of this
       // store.
-      ir::Instruction* store_var = context->get_def_use_mgr()->GetDef(
+      opt::Instruction* store_var = context->get_def_use_mgr()->GetDef(
           context->get_def_use_mgr()
               ->GetDef(stores[1]->GetSingleWordInOperand(0))
               ->GetSingleWordInOperand(1));
@@ -2855,15 +2855,15 @@
   }
   {
     // Function c
-    const ir::Function* f = spvtest::GetFunction(module, 10);
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
-    ir::Loop* loop = &ld.GetLoopByIndex(0);
-    std::vector<const ir::Loop*> loops{loop};
+    const opt::Function* f = spvtest::GetFunction(module, 10);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
+    opt::Loop* loop = &ld.GetLoopByIndex(0);
+    std::vector<const opt::Loop*> loops{loop};
     opt::LoopDependenceAnalysis analysis{context.get(), loops};
 
-    const ir::Instruction* stores[2];
+    const opt::Instruction* stores[2];
     int stores_found = 0;
-    for (const ir::Instruction& inst : *spvtest::GetBasicBlock(f, 139)) {
+    for (const opt::Instruction& inst : *spvtest::GetBasicBlock(f, 139)) {
       if (inst.opcode() == SpvOp::SpvOpStore) {
         stores[stores_found] = &inst;
         ++stores_found;
@@ -2878,7 +2878,7 @@
     {
       // Analyse and simplify the instruction behind the access chain of this
       // load.
-      ir::Instruction* load_var = context->get_def_use_mgr()->GetDef(
+      opt::Instruction* load_var = context->get_def_use_mgr()->GetDef(
           context->get_def_use_mgr()
               ->GetDef(context->get_def_use_mgr()
                            ->GetDef(159)
@@ -2889,7 +2889,7 @@
 
       // Analyse and simplify the instruction behind the access chain of this
       // store.
-      ir::Instruction* store_var = context->get_def_use_mgr()->GetDef(
+      opt::Instruction* store_var = context->get_def_use_mgr()->GetDef(
           context->get_def_use_mgr()
               ->GetDef(stores[0]->GetSingleWordInOperand(0))
               ->GetSingleWordInOperand(1));
@@ -2907,7 +2907,7 @@
     {
       // Analyse and simplify the instruction behind the access chain of this
       // load.
-      ir::Instruction* load_var = context->get_def_use_mgr()->GetDef(
+      opt::Instruction* load_var = context->get_def_use_mgr()->GetDef(
           context->get_def_use_mgr()
               ->GetDef(context->get_def_use_mgr()
                            ->GetDef(173)
@@ -2918,7 +2918,7 @@
 
       // Analyse and simplify the instruction behind the access chain of this
       // store.
-      ir::Instruction* store_var = context->get_def_use_mgr()->GetDef(
+      opt::Instruction* store_var = context->get_def_use_mgr()->GetDef(
           context->get_def_use_mgr()
               ->GetDef(stores[1]->GetSingleWordInOperand(0))
               ->GetSingleWordInOperand(1));
@@ -2934,15 +2934,15 @@
   }
   {
     // Function d
-    const ir::Function* f = spvtest::GetFunction(module, 12);
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
-    ir::Loop* loop = &ld.GetLoopByIndex(0);
-    std::vector<const ir::Loop*> loops{loop};
+    const opt::Function* f = spvtest::GetFunction(module, 12);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
+    opt::Loop* loop = &ld.GetLoopByIndex(0);
+    std::vector<const opt::Loop*> loops{loop};
     opt::LoopDependenceAnalysis analysis{context.get(), loops};
 
-    const ir::Instruction* stores[2];
+    const opt::Instruction* stores[2];
     int stores_found = 0;
-    for (const ir::Instruction& inst : *spvtest::GetBasicBlock(f, 188)) {
+    for (const opt::Instruction& inst : *spvtest::GetBasicBlock(f, 188)) {
       if (inst.opcode() == SpvOp::SpvOpStore) {
         stores[stores_found] = &inst;
         ++stores_found;
@@ -2957,7 +2957,7 @@
     {
       // Analyse and simplify the instruction behind the access chain of this
       // load.
-      ir::Instruction* load_var = context->get_def_use_mgr()->GetDef(
+      opt::Instruction* load_var = context->get_def_use_mgr()->GetDef(
           context->get_def_use_mgr()
               ->GetDef(context->get_def_use_mgr()
                            ->GetDef(208)
@@ -2968,7 +2968,7 @@
 
       // Analyse and simplify the instruction behind the access chain of this
       // store.
-      ir::Instruction* store_var = context->get_def_use_mgr()->GetDef(
+      opt::Instruction* store_var = context->get_def_use_mgr()->GetDef(
           context->get_def_use_mgr()
               ->GetDef(stores[0]->GetSingleWordInOperand(0))
               ->GetSingleWordInOperand(1));
@@ -2986,7 +2986,7 @@
     {
       // Analyse and simplify the instruction behind the access chain of this
       // load.
-      ir::Instruction* load_var = context->get_def_use_mgr()->GetDef(
+      opt::Instruction* load_var = context->get_def_use_mgr()->GetDef(
           context->get_def_use_mgr()
               ->GetDef(context->get_def_use_mgr()
                            ->GetDef(222)
@@ -2997,7 +2997,7 @@
 
       // Analyse and simplify the instruction behind the access chain of this
       // store.
-      ir::Instruction* store_var = context->get_def_use_mgr()->GetDef(
+      opt::Instruction* store_var = context->get_def_use_mgr()->GetDef(
           context->get_def_use_mgr()
               ->GetDef(stores[1]->GetSingleWordInOperand(0))
               ->GetSingleWordInOperand(1));
diff --git a/test/opt/loop_optimizations/fusion_compatibility.cpp b/test/opt/loop_optimizations/fusion_compatibility.cpp
index 709b34f..d304d5a 100644
--- a/test/opt/loop_optimizations/fusion_compatibility.cpp
+++ b/test/opt/loop_optimizations/fusion_compatibility.cpp
@@ -96,14 +96,14 @@
                OpFunctionEnd
   )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  ir::Function& f = *module->begin();
-  ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+  opt::Function& f = *module->begin();
+  opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
   EXPECT_EQ(ld.NumLoops(), 2u);
 
   auto loops = ld.GetLoopsInBinaryLayoutOrder();
@@ -181,14 +181,14 @@
                OpFunctionEnd
   )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  ir::Function& f = *module->begin();
-  ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+  opt::Function& f = *module->begin();
+  opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
   EXPECT_EQ(ld.NumLoops(), 2u);
 
   auto loops = ld.GetLoopsInBinaryLayoutOrder();
@@ -267,14 +267,14 @@
                OpFunctionEnd
   )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  ir::Function& f = *module->begin();
-  ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+  opt::Function& f = *module->begin();
+  opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
   EXPECT_EQ(ld.NumLoops(), 2u);
 
   auto loops = ld.GetLoopsInBinaryLayoutOrder();
@@ -354,14 +354,14 @@
                OpFunctionEnd
   )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  ir::Function& f = *module->begin();
-  ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+  opt::Function& f = *module->begin();
+  opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
   EXPECT_EQ(ld.NumLoops(), 2u);
 
   auto loops = ld.GetLoopsInBinaryLayoutOrder();
@@ -442,14 +442,14 @@
                OpFunctionEnd
   )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  ir::Function& f = *module->begin();
-  ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+  opt::Function& f = *module->begin();
+  opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
   EXPECT_EQ(ld.NumLoops(), 2u);
 
   auto loops = ld.GetLoopsInBinaryLayoutOrder();
@@ -530,14 +530,14 @@
                OpFunctionEnd
   )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  ir::Function& f = *module->begin();
-  ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+  opt::Function& f = *module->begin();
+  opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
   EXPECT_EQ(ld.NumLoops(), 2u);
 
   auto loops = ld.GetLoopsInBinaryLayoutOrder();
@@ -628,14 +628,14 @@
                OpFunctionEnd
   )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  ir::Function& f = *module->begin();
-  ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+  opt::Function& f = *module->begin();
+  opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
   EXPECT_EQ(ld.NumLoops(), 2u);
 
   auto loops = ld.GetLoopsInBinaryLayoutOrder();
@@ -729,14 +729,14 @@
                OpFunctionEnd
   )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  ir::Function& f = *module->begin();
-  ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+  opt::Function& f = *module->begin();
+  opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
   EXPECT_EQ(ld.NumLoops(), 2u);
 
   auto loops = ld.GetLoopsInBinaryLayoutOrder();
@@ -829,14 +829,14 @@
                OpFunctionEnd
   )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  ir::Function& f = *module->begin();
-  ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+  opt::Function& f = *module->begin();
+  opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
   EXPECT_EQ(ld.NumLoops(), 2u);
 
   auto loops = ld.GetLoopsInBinaryLayoutOrder();
@@ -932,14 +932,14 @@
                OpFunctionEnd
   )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  ir::Function& f = *module->begin();
-  ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+  opt::Function& f = *module->begin();
+  opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
   EXPECT_EQ(ld.NumLoops(), 2u);
 
   auto loops = ld.GetLoopsInBinaryLayoutOrder();
@@ -1037,14 +1037,14 @@
                OpFunctionEnd
   )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  ir::Function& f = *module->begin();
-  ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+  opt::Function& f = *module->begin();
+  opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
   EXPECT_EQ(ld.NumLoops(), 3u);
 
   auto loops = ld.GetLoopsInBinaryLayoutOrder();
@@ -1170,14 +1170,14 @@
                OpFunctionEnd
   )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  ir::Function& f = *module->begin();
-  ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+  opt::Function& f = *module->begin();
+  opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
   EXPECT_EQ(ld.NumLoops(), 3u);
 
   auto loops = ld.GetLoopsInBinaryLayoutOrder();
@@ -1264,14 +1264,14 @@
                OpFunctionEnd
   )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  ir::Function& f = *module->begin();
-  ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+  opt::Function& f = *module->begin();
+  opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
   EXPECT_EQ(ld.NumLoops(), 2u);
 
   auto loops = ld.GetLoopsInBinaryLayoutOrder();
@@ -1377,14 +1377,14 @@
                OpFunctionEnd
   )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  ir::Function& f = *module->begin();
-  ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+  opt::Function& f = *module->begin();
+  opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
   EXPECT_EQ(ld.NumLoops(), 2u);
 
   auto loops = ld.GetLoopsInBinaryLayoutOrder();
@@ -1470,14 +1470,14 @@
                OpFunctionEnd
   )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  ir::Function& f = *module->begin();
-  ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+  opt::Function& f = *module->begin();
+  opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
   EXPECT_EQ(ld.NumLoops(), 2u);
 
   auto loops = ld.GetLoopsInBinaryLayoutOrder();
@@ -1562,14 +1562,14 @@
                OpFunctionEnd
   )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  ir::Function& f = *module->begin();
-  ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+  opt::Function& f = *module->begin();
+  opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
   EXPECT_EQ(ld.NumLoops(), 2u);
 
   auto loops = ld.GetLoopsInBinaryLayoutOrder();
@@ -1661,14 +1661,14 @@
                OpFunctionEnd
   )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  ir::Function& f = *module->begin();
-  ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+  opt::Function& f = *module->begin();
+  opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
   EXPECT_EQ(ld.NumLoops(), 2u);
 
   auto loops = ld.GetLoopsInBinaryLayoutOrder();
@@ -1771,14 +1771,14 @@
                OpFunctionEnd
   )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  ir::Function& f = *module->begin();
-  ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+  opt::Function& f = *module->begin();
+  opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
   EXPECT_EQ(ld.NumLoops(), 2u);
 
   auto loops = ld.GetLoopsInBinaryLayoutOrder();
diff --git a/test/opt/loop_optimizations/fusion_illegal.cpp b/test/opt/loop_optimizations/fusion_illegal.cpp
index a307022..5747a4d 100644
--- a/test/opt/loop_optimizations/fusion_illegal.cpp
+++ b/test/opt/loop_optimizations/fusion_illegal.cpp
@@ -130,14 +130,14 @@
                OpFunctionEnd
     )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  ir::Function& f = *module->begin();
-  ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+  opt::Function& f = *module->begin();
+  opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
   EXPECT_EQ(ld.NumLoops(), 2u);
 
   auto loops = ld.GetLoopsInBinaryLayoutOrder();
@@ -249,14 +249,14 @@
                OpFunctionEnd
     )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  ir::Function& f = *module->begin();
-  ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+  opt::Function& f = *module->begin();
+  opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
   EXPECT_EQ(ld.NumLoops(), 2u);
 
   auto loops = ld.GetLoopsInBinaryLayoutOrder();
@@ -408,16 +408,16 @@
                OpFunctionEnd
     )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  ir::Function& f = *module->begin();
+  opt::Function& f = *module->begin();
 
   {
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
     EXPECT_EQ(ld.NumLoops(), 4u);
 
     auto loops = ld.GetLoopsInBinaryLayoutOrder();
@@ -548,16 +548,16 @@
                OpFunctionEnd
     )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  ir::Function& f = *module->begin();
+  opt::Function& f = *module->begin();
 
   {
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
     EXPECT_EQ(ld.NumLoops(), 2u);
 
     auto loops = ld.GetLoopsInBinaryLayoutOrder();
@@ -669,16 +669,16 @@
                OpFunctionEnd
     )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  ir::Function& f = *module->begin();
+  opt::Function& f = *module->begin();
 
   {
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
     EXPECT_EQ(ld.NumLoops(), 2u);
 
     auto loops = ld.GetLoopsInBinaryLayoutOrder();
@@ -790,16 +790,16 @@
                OpFunctionEnd
     )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  ir::Function& f = *module->begin();
+  opt::Function& f = *module->begin();
 
   {
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
     EXPECT_EQ(ld.NumLoops(), 2u);
 
     auto loops = ld.GetLoopsInBinaryLayoutOrder();
@@ -911,16 +911,16 @@
                OpFunctionEnd
     )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  ir::Function& f = *module->begin();
+  opt::Function& f = *module->begin();
 
   {
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
     EXPECT_EQ(ld.NumLoops(), 2u);
 
     auto loops = ld.GetLoopsInBinaryLayoutOrder();
@@ -1033,16 +1033,16 @@
                OpFunctionEnd
     )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  ir::Function& f = *module->begin();
+  opt::Function& f = *module->begin();
 
   {
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
     EXPECT_EQ(ld.NumLoops(), 2u);
 
     auto loops = ld.GetLoopsInBinaryLayoutOrder();
@@ -1158,16 +1158,16 @@
                OpFunctionEnd
     )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  ir::Function& f = *module->begin();
+  opt::Function& f = *module->begin();
 
   {
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
     EXPECT_EQ(ld.NumLoops(), 2u);
 
     auto loops = ld.GetLoopsInBinaryLayoutOrder();
@@ -1279,16 +1279,16 @@
                OpFunctionEnd
     )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  ir::Function& f = *module->begin();
+  opt::Function& f = *module->begin();
 
   {
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
     EXPECT_EQ(ld.NumLoops(), 2u);
 
     auto loops = ld.GetLoopsInBinaryLayoutOrder();
@@ -1396,16 +1396,16 @@
                OpFunctionEnd
     )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  ir::Function& f = *module->begin();
+  opt::Function& f = *module->begin();
 
   {
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
     EXPECT_EQ(ld.NumLoops(), 2u);
 
     auto loops = ld.GetLoopsInBinaryLayoutOrder();
@@ -1568,16 +1568,16 @@
                OpFunctionEnd
     )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  ir::Function& f = *module->begin();
+  opt::Function& f = *module->begin();
 
   {
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
     EXPECT_EQ(ld.NumLoops(), 2u);
 
     auto loops = ld.GetLoopsInBinaryLayoutOrder();
diff --git a/test/opt/loop_optimizations/fusion_legal.cpp b/test/opt/loop_optimizations/fusion_legal.cpp
index 4f0514c..eaeb695 100644
--- a/test/opt/loop_optimizations/fusion_legal.cpp
+++ b/test/opt/loop_optimizations/fusion_legal.cpp
@@ -46,7 +46,7 @@
   return error == 0;
 }
 
-void Match(const std::string& checks, ir::IRContext* context) {
+void Match(const std::string& checks, opt::IRContext* context) {
   // Silence unused warnings with !defined(SPIRV_EFFCE)
   (void)checks;
 
@@ -162,14 +162,14 @@
                OpFunctionEnd
     )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  ir::Function& f = *module->begin();
-  ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+  opt::Function& f = *module->begin();
+  opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
   EXPECT_EQ(ld.NumLoops(), 2u);
 
   auto loops = ld.GetLoopsInBinaryLayoutOrder();
@@ -298,14 +298,14 @@
                OpFunctionEnd
     )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  ir::Function& f = *module->begin();
-  ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+  opt::Function& f = *module->begin();
+  opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
   EXPECT_EQ(ld.NumLoops(), 2u);
 
   auto loops = ld.GetLoopsInBinaryLayoutOrder();
@@ -431,14 +431,14 @@
                OpFunctionEnd
     )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  ir::Function& f = *module->begin();
-  ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+  opt::Function& f = *module->begin();
+  opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
   EXPECT_EQ(ld.NumLoops(), 2u);
 
   auto loops = ld.GetLoopsInBinaryLayoutOrder();
@@ -569,14 +569,14 @@
                OpFunctionEnd
     )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  ir::Function& f = *module->begin();
-  ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+  opt::Function& f = *module->begin();
+  opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
   EXPECT_EQ(ld.NumLoops(), 2u);
 
   auto loops = ld.GetLoopsInBinaryLayoutOrder();
@@ -709,16 +709,16 @@
                OpFunctionEnd
     )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  ir::Function& f = *module->begin();
+  opt::Function& f = *module->begin();
 
   {
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
     EXPECT_EQ(ld.NumLoops(), 2u);
 
     auto loops = ld.GetLoopsInBinaryLayoutOrder();
@@ -854,14 +854,14 @@
                OpFunctionEnd
     )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  ir::Function& f = *module->begin();
-  ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+  opt::Function& f = *module->begin();
+  opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
   EXPECT_EQ(ld.NumLoops(), 2u);
 
   auto loops = ld.GetLoopsInBinaryLayoutOrder();
@@ -995,14 +995,14 @@
                OpFunctionEnd
     )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  ir::Function& f = *module->begin();
-  ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+  opt::Function& f = *module->begin();
+  opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
   EXPECT_EQ(ld.NumLoops(), 2u);
 
   auto loops = ld.GetLoopsInBinaryLayoutOrder();
@@ -1135,14 +1135,14 @@
                OpFunctionEnd
     )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  ir::Function& f = *module->begin();
-  ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+  opt::Function& f = *module->begin();
+  opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
   EXPECT_EQ(ld.NumLoops(), 2u);
 
   auto loops = ld.GetLoopsInBinaryLayoutOrder();
@@ -1275,14 +1275,14 @@
                OpFunctionEnd
     )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  ir::Function& f = *module->begin();
-  ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+  opt::Function& f = *module->begin();
+  opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
   EXPECT_EQ(ld.NumLoops(), 2u);
 
   auto loops = ld.GetLoopsInBinaryLayoutOrder();
@@ -1438,16 +1438,16 @@
                OpFunctionEnd
     )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  ir::Function& f = *module->begin();
+  opt::Function& f = *module->begin();
 
   {
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
     EXPECT_EQ(ld.NumLoops(), 3u);
 
     auto loops = ld.GetLoopsInBinaryLayoutOrder();
@@ -1483,7 +1483,7 @@
   Match(checks, context.get());
 
   {
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
     EXPECT_EQ(ld.NumLoops(), 2u);
 
     auto loops = ld.GetLoopsInBinaryLayoutOrder();
@@ -1640,14 +1640,14 @@
                OpFunctionEnd
     )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  ir::Function& f = *module->begin();
-  ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+  opt::Function& f = *module->begin();
+  opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
   EXPECT_EQ(ld.NumLoops(), 3u);
 
   auto loops = ld.GetLoopsInBinaryLayoutOrder();
@@ -1836,16 +1836,16 @@
                OpFunctionEnd
     )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  ir::Function& f = *module->begin();
+  opt::Function& f = *module->begin();
 
   {
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
     EXPECT_EQ(ld.NumLoops(), 4u);
 
     auto loops = ld.GetLoopsInBinaryLayoutOrder();
@@ -2110,16 +2110,16 @@
                OpFunctionEnd
     )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  ir::Function& f = *module->begin();
+  opt::Function& f = *module->begin();
 
   {
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
     EXPECT_EQ(ld.NumLoops(), 4u);
 
     auto loops = ld.GetLoopsInBinaryLayoutOrder();
@@ -2180,7 +2180,7 @@
   }
 
   {
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
     EXPECT_EQ(ld.NumLoops(), 3u);
 
     auto loops = ld.GetLoopsInBinaryLayoutOrder();
@@ -2228,7 +2228,7 @@
   }
 
   {
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
     EXPECT_EQ(ld.NumLoops(), 2u);
   }
 }
@@ -2354,16 +2354,16 @@
                OpFunctionEnd
     )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  ir::Function& f = *module->begin();
+  opt::Function& f = *module->begin();
 
   {
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
     EXPECT_EQ(ld.NumLoops(), 3u);
 
     auto loops = ld.GetLoopsInBinaryLayoutOrder();
@@ -2392,7 +2392,7 @@
   }
 
   {
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
     EXPECT_EQ(ld.NumLoops(), 2u);
 
     std::string checks = R"(
@@ -2554,16 +2554,16 @@
                OpFunctionEnd
     )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  ir::Function& f = *module->begin();
+  opt::Function& f = *module->begin();
 
   {
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
     EXPECT_EQ(ld.NumLoops(), 4u);
 
     auto loops = ld.GetLoopsInBinaryLayoutOrder();
@@ -2617,7 +2617,7 @@
   }
 
   {
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
     EXPECT_EQ(ld.NumLoops(), 3u);
 
     auto loops = ld.GetLoopsInBinaryLayoutOrder();
@@ -2761,16 +2761,16 @@
                OpFunctionEnd
     )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  ir::Function& f = *module->begin();
+  opt::Function& f = *module->begin();
 
   {
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
     EXPECT_EQ(ld.NumLoops(), 2u);
 
     auto loops = ld.GetLoopsInBinaryLayoutOrder();
@@ -2904,16 +2904,16 @@
                OpFunctionEnd
     )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  ir::Function& f = *module->begin();
+  opt::Function& f = *module->begin();
 
   {
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
     EXPECT_EQ(ld.NumLoops(), 2u);
 
     auto loops = ld.GetLoopsInBinaryLayoutOrder();
@@ -2926,7 +2926,7 @@
   }
 
   {
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
     EXPECT_EQ(ld.NumLoops(), 1u);
 
     std::string checks = R"(
@@ -3048,16 +3048,16 @@
                OpFunctionEnd
     )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  ir::Function& f = *module->begin();
+  opt::Function& f = *module->begin();
 
   {
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
     EXPECT_EQ(ld.NumLoops(), 2u);
 
     auto loops = ld.GetLoopsInBinaryLayoutOrder();
@@ -3070,7 +3070,7 @@
   }
 
   {
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
     EXPECT_EQ(ld.NumLoops(), 1u);
 
     std::string checks = R"(
@@ -3257,16 +3257,16 @@
                OpFunctionEnd
     )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  ir::Function& f = *module->begin();
+  opt::Function& f = *module->begin();
 
   {
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
     EXPECT_EQ(ld.NumLoops(), 4u);
 
     auto loops = ld.GetLoopsInBinaryLayoutOrder();
@@ -3279,7 +3279,7 @@
   }
 
   {
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
     EXPECT_EQ(ld.NumLoops(), 3u);
 
     auto loops = ld.GetLoopsInBinaryLayoutOrder();
@@ -3405,16 +3405,16 @@
                OpFunctionEnd
     )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  ir::Function& f = *module->begin();
+  opt::Function& f = *module->begin();
 
   {
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
     EXPECT_EQ(ld.NumLoops(), 2u);
 
     auto loops = ld.GetLoopsInBinaryLayoutOrder();
@@ -3436,7 +3436,7 @@
   }
 
   {
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
     EXPECT_EQ(ld.NumLoops(), 1u);
 
     std::string checks = R"(
@@ -3578,16 +3578,16 @@
                OpFunctionEnd
     )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  ir::Function& f = *module->begin();
+  opt::Function& f = *module->begin();
 
   {
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
     EXPECT_EQ(ld.NumLoops(), 3u);
 
     auto loops = ld.GetLoopsInBinaryLayoutOrder();
@@ -3609,7 +3609,7 @@
   }
 
   {
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
     EXPECT_EQ(ld.NumLoops(), 2u);
 
     std::string checks = R"(
@@ -3644,7 +3644,7 @@
   }
 
   {
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
     EXPECT_EQ(ld.NumLoops(), 1u);
 
     std::string checks = R"(
@@ -3780,16 +3780,16 @@
                OpFunctionEnd
     )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  ir::Function& f = *module->begin();
+  opt::Function& f = *module->begin();
 
   {
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
     EXPECT_EQ(ld.NumLoops(), 2u);
 
     auto loops = ld.GetLoopsInBinaryLayoutOrder();
@@ -3802,7 +3802,7 @@
   }
 
   {
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
     EXPECT_EQ(ld.NumLoops(), 1u);
 
     std::string checks = R"(
@@ -3935,16 +3935,16 @@
                OpFunctionEnd
     )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  ir::Function& f = *module->begin();
+  opt::Function& f = *module->begin();
 
   {
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
     EXPECT_EQ(ld.NumLoops(), 2u);
 
     auto loops = ld.GetLoopsInBinaryLayoutOrder();
@@ -3960,7 +3960,7 @@
   }
 
   {
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
     EXPECT_EQ(ld.NumLoops(), 1u);
 
     std::string checks = R"(
@@ -4093,16 +4093,16 @@
                OpFunctionEnd
     )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  ir::Function& f = *module->begin();
+  opt::Function& f = *module->begin();
 
   {
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
     EXPECT_EQ(ld.NumLoops(), 2u);
 
     auto loops = ld.GetLoopsInBinaryLayoutOrder();
@@ -4120,7 +4120,7 @@
   }
 
   {
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
     EXPECT_EQ(ld.NumLoops(), 1u);
 
     std::string checks = R"(
@@ -4242,16 +4242,16 @@
                OpFunctionEnd
     )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  ir::Function& f = *module->begin();
+  opt::Function& f = *module->begin();
 
   {
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
     EXPECT_EQ(ld.NumLoops(), 2u);
 
     auto loops = ld.GetLoopsInBinaryLayoutOrder();
@@ -4266,7 +4266,7 @@
   }
 
   {
-    // ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+    // opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
     // EXPECT_EQ(ld.NumLoops(), 1u);
 
     //       std::string checks = R"(
@@ -4387,16 +4387,16 @@
                OpFunctionEnd
     )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  ir::Function& f = *module->begin();
+  opt::Function& f = *module->begin();
 
   {
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
     EXPECT_EQ(ld.NumLoops(), 2u);
 
     auto loops = ld.GetLoopsInBinaryLayoutOrder();
@@ -4409,7 +4409,7 @@
   }
 
   {
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
     EXPECT_EQ(ld.NumLoops(), 1u);
 
     std::string checks = R"(
@@ -4537,16 +4537,16 @@
                OpFunctionEnd
     )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  ir::Function& f = *module->begin();
+  opt::Function& f = *module->begin();
 
   {
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
     EXPECT_EQ(ld.NumLoops(), 2u);
 
     auto loops = ld.GetLoopsInBinaryLayoutOrder();
@@ -4559,7 +4559,7 @@
   }
 
   {
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
     EXPECT_EQ(ld.NumLoops(), 1u);
 
     // clang-format off
diff --git a/test/opt/loop_optimizations/lcssa.cpp b/test/opt/loop_optimizations/lcssa.cpp
index 95d5a2a..333f6a5 100644
--- a/test/opt/loop_optimizations/lcssa.cpp
+++ b/test/opt/loop_optimizations/lcssa.cpp
@@ -48,7 +48,7 @@
   return error == 0;
 }
 
-void Match(const std::string& original, ir::IRContext* context,
+void Match(const std::string& original, opt::IRContext* context,
            bool do_validation = true) {
   std::vector<uint32_t> bin;
   context->module()->ToBinary(&bin, true);
@@ -136,16 +136,16 @@
                OpReturn
                OpFunctionEnd
   )";
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  const ir::Function* f = spvtest::GetFunction(module, 2);
-  ir::LoopDescriptor ld{f};
+  const opt::Function* f = spvtest::GetFunction(module, 2);
+  opt::LoopDescriptor ld{f};
 
-  ir::Loop* loop = ld[17];
+  opt::Loop* loop = ld[17];
   EXPECT_FALSE(loop->IsLCSSA());
   opt::LoopUtils Util(context.get(), loop);
   Util.MakeLoopClosedSSA();
@@ -222,16 +222,16 @@
                OpReturn
                OpFunctionEnd
   )";
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  const ir::Function* f = spvtest::GetFunction(module, 2);
-  ir::LoopDescriptor ld{f};
+  const opt::Function* f = spvtest::GetFunction(module, 2);
+  opt::LoopDescriptor ld{f};
 
-  ir::Loop* loop = ld[17];
+  opt::Loop* loop = ld[17];
   EXPECT_FALSE(loop->IsLCSSA());
   opt::LoopUtils Util(context.get(), loop);
   Util.MakeLoopClosedSSA();
@@ -321,16 +321,16 @@
                OpReturn
                OpFunctionEnd
   )";
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  const ir::Function* f = spvtest::GetFunction(module, 2);
-  ir::LoopDescriptor ld{f};
+  const opt::Function* f = spvtest::GetFunction(module, 2);
+  opt::LoopDescriptor ld{f};
 
-  ir::Loop* loop = ld[16];
+  opt::Loop* loop = ld[16];
   EXPECT_FALSE(loop->IsLCSSA());
   opt::LoopUtils Util(context.get(), loop);
   Util.MakeLoopClosedSSA();
@@ -414,16 +414,16 @@
                OpReturn
                OpFunctionEnd
   )";
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  const ir::Function* f = spvtest::GetFunction(module, 2);
-  ir::LoopDescriptor ld{f};
+  const opt::Function* f = spvtest::GetFunction(module, 2);
+  opt::LoopDescriptor ld{f};
 
-  ir::Loop* loop = ld[19];
+  opt::Loop* loop = ld[19];
   EXPECT_FALSE(loop->IsLCSSA());
   opt::LoopUtils Util(context.get(), loop);
   Util.MakeLoopClosedSSA();
@@ -509,16 +509,16 @@
                OpReturn
                OpFunctionEnd
   )";
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  const ir::Function* f = spvtest::GetFunction(module, 2);
-  ir::LoopDescriptor ld{f};
+  const opt::Function* f = spvtest::GetFunction(module, 2);
+  opt::LoopDescriptor ld{f};
 
-  ir::Loop* loop = ld[19];
+  opt::Loop* loop = ld[19];
   EXPECT_FALSE(loop->IsLCSSA());
   opt::LoopUtils Util(context.get(), loop);
   Util.MakeLoopClosedSSA();
@@ -592,16 +592,16 @@
                OpReturn
                OpFunctionEnd
   )";
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  const ir::Function* f = spvtest::GetFunction(module, 2);
-  ir::LoopDescriptor ld{f};
+  const opt::Function* f = spvtest::GetFunction(module, 2);
+  opt::LoopDescriptor ld{f};
 
-  ir::Loop* loop = ld[12];
+  opt::Loop* loop = ld[12];
   EXPECT_FALSE(loop->IsLCSSA());
   opt::LoopUtils Util(context.get(), loop);
   Util.MakeLoopClosedSSA();
diff --git a/test/opt/loop_optimizations/loop_descriptions.cpp b/test/opt/loop_optimizations/loop_descriptions.cpp
index b74dc90..ac957d9 100644
--- a/test/opt/loop_optimizations/loop_descriptions.cpp
+++ b/test/opt/loop_optimizations/loop_descriptions.cpp
@@ -90,18 +90,18 @@
                OpFunctionEnd
   )";
   // clang-format on
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  const ir::Function* f = spvtest::GetFunction(module, 2);
-  ir::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
+  const opt::Function* f = spvtest::GetFunction(module, 2);
+  opt::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
 
   EXPECT_EQ(ld.NumLoops(), 1u);
 
-  ir::Loop& loop = ld.GetLoopByIndex(0);
+  opt::Loop& loop = ld.GetLoopByIndex(0);
   EXPECT_EQ(loop.GetHeaderBlock(), spvtest::GetBasicBlock(f, 18));
   EXPECT_EQ(loop.GetLatchBlock(), spvtest::GetBasicBlock(f, 20));
   EXPECT_EQ(loop.GetMergeBlock(), spvtest::GetBasicBlock(f, 19));
@@ -187,18 +187,18 @@
                OpFunctionEnd
   )";
   // clang-format on
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  const ir::Function* f = spvtest::GetFunction(module, 2);
-  ir::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
+  const opt::Function* f = spvtest::GetFunction(module, 2);
+  opt::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
 
   EXPECT_EQ(ld.NumLoops(), 2u);
 
-  ir::Loop* loop = ld[27];
+  opt::Loop* loop = ld[27];
   EXPECT_EQ(loop->GetPreHeaderBlock(), nullptr);
   EXPECT_NE(loop->GetOrCreatePreHeaderBlock(), nullptr);
 }
@@ -285,14 +285,14 @@
                OpFunctionEnd
   )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  const ir::Function* f = spvtest::GetFunction(module, 4);
-  ir::LoopDescriptor ld{f};
+  const opt::Function* f = spvtest::GetFunction(module, 4);
+  opt::LoopDescriptor ld{f};
 
   EXPECT_EQ(ld.NumLoops(), 0u);
 }
@@ -361,18 +361,18 @@
                OpFunctionEnd
   )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  const ir::Function* f = spvtest::GetFunction(module, 2);
-  ir::LoopDescriptor ld{f};
+  const opt::Function* f = spvtest::GetFunction(module, 2);
+  opt::LoopDescriptor ld{f};
 
   EXPECT_EQ(ld.NumLoops(), 1u);
 
-  ir::Loop& loop = ld.GetLoopByIndex(0u);
+  opt::Loop& loop = ld.GetLoopByIndex(0u);
 
   EXPECT_NE(loop.GetLatchBlock(), loop.GetContinueBlock());
 
diff --git a/test/opt/loop_optimizations/loop_fission.cpp b/test/opt/loop_optimizations/loop_fission.cpp
index 24e8959..ef2bfbd 100644
--- a/test/opt/loop_optimizations/loop_fission.cpp
+++ b/test/opt/loop_optimizations/loop_fission.cpp
@@ -187,23 +187,21 @@
 OpFunctionEnd
 )";
   // clang-format on
-  std::unique_ptr<ir::IRContext> context =
-      BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, source,
-                  SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
-  EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
-                             << source << std::endl;
+std::unique_ptr<opt::IRContext> context =
+    BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, source,
+                SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
+opt::Module* module = context->module();
+EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
+                           << source << std::endl;
 
-  SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
-  SinglePassRunAndCheck<opt::LoopFissionPass>(source, expected, true);
+SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
+SinglePassRunAndCheck<opt::LoopFissionPass>(source, expected, true);
 
-  // Check that the loop will NOT be split when provided with a pass-through
-  // register pressure functor which just returns false.
-  SinglePassRunAndCheck<opt::LoopFissionPass>(
-      source, source, true,
-      [](const opt::RegisterLiveness::RegionRegisterLiveness&) {
-        return false;
-      });
+// Check that the loop will NOT be split when provided with a pass-through
+// register pressure functor which just returns false.
+SinglePassRunAndCheck<opt::LoopFissionPass>(
+    source, source, true,
+    [](const opt::RegisterLiveness::RegionRegisterLiveness&) { return false; });
 }
 
 /*
@@ -283,10 +281,10 @@
 OpFunctionEnd
 )";
   // clang-format on
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, source,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for ushader:\n"
                              << source << std::endl;
 
@@ -370,15 +368,15 @@
 OpFunctionEnd
 )";
   // clang-format on
-  std::unique_ptr<ir::IRContext> context =
-      BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, source,
-                  SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
-  EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
-                             << source << std::endl;
+std::unique_ptr<opt::IRContext> context =
+    BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, source,
+                SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
+opt::Module* module = context->module();
+EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
+                           << source << std::endl;
 
-  SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
-  SinglePassRunAndCheck<opt::LoopFissionPass>(source, source, true);
+SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
+SinglePassRunAndCheck<opt::LoopFissionPass>(source, source, true);
 }
 
 /*
@@ -682,22 +680,22 @@
 OpFunctionEnd
 )";
   // clang-format on
-  std::unique_ptr<ir::IRContext> context =
-      BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, source,
-                  SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
-  EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
-                             << source << std::endl;
+std::unique_ptr<opt::IRContext> context =
+    BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, source,
+                SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
+opt::Module* module = context->module();
+EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
+                           << source << std::endl;
 
-  SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
-  SinglePassRunAndCheck<opt::LoopFissionPass>(source, expected, true);
+SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
+SinglePassRunAndCheck<opt::LoopFissionPass>(source, expected, true);
 
-  // By passing 1 as argument we are using the constructor which makes the
-  // critera to split the loop be if the registers in the loop exceede 1. By
-  // using this constructor we are also enabling multiple passes (disabled by
-  // default).
-  SinglePassRunAndCheck<opt::LoopFissionPass>(source, expected_multiple_passes,
-                                              true, 1);
+// By passing 1 as argument we are using the constructor which makes the
+// critera to split the loop be if the registers in the loop exceede 1. By
+// using this constructor we are also enabling multiple passes (disabled by
+// default).
+SinglePassRunAndCheck<opt::LoopFissionPass>(source, expected_multiple_passes,
+                                            true, 1);
 }
 
 /*
@@ -866,10 +864,10 @@
 OpFunctionEnd
 )";
   // clang-format on
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, source,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << source << std::endl;
 
@@ -1052,10 +1050,10 @@
 )";
 
   // clang-format on
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, source,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << source << std::endl;
 
@@ -1266,10 +1264,10 @@
 )";
 
   // clang-format on
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, source,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << source << std::endl;
 
@@ -1370,15 +1368,15 @@
 OpFunctionEnd
 )";
   // clang-format on
-  std::unique_ptr<ir::IRContext> context =
-      BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, source,
-                  SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
-  EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
-                             << source << std::endl;
+std::unique_ptr<opt::IRContext> context =
+    BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, source,
+                SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
+opt::Module* module = context->module();
+EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
+                           << source << std::endl;
 
-  SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
-  SinglePassRunAndCheck<opt::LoopFissionPass>(source, source, true);
+SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
+SinglePassRunAndCheck<opt::LoopFissionPass>(source, source, true);
 }
 
 /*
@@ -1592,10 +1590,10 @@
 )";
 
   // clang-format on
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, source,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << source << std::endl;
 
@@ -1867,10 +1865,10 @@
 )";
 
   // clang-format on
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, source,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << source << std::endl;
 
@@ -1961,15 +1959,15 @@
 OpFunctionEnd
 )";
   // clang-format on
-  std::unique_ptr<ir::IRContext> context =
-      BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, source,
-                  SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
-  EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
-                             << source << std::endl;
+std::unique_ptr<opt::IRContext> context =
+    BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, source,
+                SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
+opt::Module* module = context->module();
+EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
+                           << source << std::endl;
 
-  SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
-  SinglePassRunAndCheck<opt::LoopFissionPass>(source, source, true);
+SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
+SinglePassRunAndCheck<opt::LoopFissionPass>(source, source, true);
 }
 
 /*
@@ -2053,15 +2051,15 @@
 OpFunctionEnd
 )";
   // clang-format on
-  std::unique_ptr<ir::IRContext> context =
-      BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, source,
-                  SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
-  EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
-                             << source << std::endl;
+std::unique_ptr<opt::IRContext> context =
+    BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, source,
+                SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
+opt::Module* module = context->module();
+EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
+                           << source << std::endl;
 
-  SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
-  SinglePassRunAndCheck<opt::LoopFissionPass>(source, source, true);
+SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
+SinglePassRunAndCheck<opt::LoopFissionPass>(source, source, true);
 }
 
 /*
@@ -2244,15 +2242,15 @@
 OpFunctionEnd
 )";
   // clang-format on
-  std::unique_ptr<ir::IRContext> context =
-      BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, source,
-                  SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
-  EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
-                             << source << std::endl;
+std::unique_ptr<opt::IRContext> context =
+    BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, source,
+                SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
+opt::Module* module = context->module();
+EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
+                           << source << std::endl;
 
-  SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
-  SinglePassRunAndCheck<opt::LoopFissionPass>(source, expected, true);
+SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
+SinglePassRunAndCheck<opt::LoopFissionPass>(source, expected, true);
 }
 
 /*
@@ -2410,15 +2408,15 @@
 OpFunctionEnd
 )";
   // clang-format on
-  std::unique_ptr<ir::IRContext> context =
-      BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, source,
-                  SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
-  EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
-                             << source << std::endl;
+std::unique_ptr<opt::IRContext> context =
+    BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, source,
+                SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
+opt::Module* module = context->module();
+EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
+                           << source << std::endl;
 
-  SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
-  SinglePassRunAndCheck<opt::LoopFissionPass>(source, expected, true);
+SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
+SinglePassRunAndCheck<opt::LoopFissionPass>(source, expected, true);
 }
 
 /*
@@ -2517,15 +2515,15 @@
 )";
 
   // clang-format on
-  std::unique_ptr<ir::IRContext> context =
-      BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, source,
-                  SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
-  EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
-                             << source << std::endl;
+std::unique_ptr<opt::IRContext> context =
+    BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, source,
+                SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
+opt::Module* module = context->module();
+EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
+                           << source << std::endl;
 
-  SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
-  SinglePassRunAndCheck<opt::LoopFissionPass>(source, source, true);
+SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
+SinglePassRunAndCheck<opt::LoopFissionPass>(source, source, true);
 }
 
 /*
@@ -2627,15 +2625,15 @@
 )";
 
   // clang-format on
-  std::unique_ptr<ir::IRContext> context =
-      BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, source,
-                  SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
-  EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
-                             << source << std::endl;
+std::unique_ptr<opt::IRContext> context =
+    BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, source,
+                SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
+opt::Module* module = context->module();
+EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
+                           << source << std::endl;
 
-  SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
-  SinglePassRunAndCheck<opt::LoopFissionPass>(source, source, true);
+SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
+SinglePassRunAndCheck<opt::LoopFissionPass>(source, source, true);
 }
 
 /*
@@ -2906,32 +2904,32 @@
 OpFunctionEnd
 )";
   // clang-format on
-  std::unique_ptr<ir::IRContext> context =
-      BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, source,
-                  SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
-  EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
-                             << source << std::endl;
-  const ir::Function* function = spvtest::GetFunction(module, 2);
-  ir::LoopDescriptor& pre_pass_descriptor =
-      *context->GetLoopDescriptor(function);
-  EXPECT_EQ(pre_pass_descriptor.NumLoops(), 3u);
-  EXPECT_EQ(pre_pass_descriptor.pre_begin()->NumImmediateChildren(), 2u);
+std::unique_ptr<opt::IRContext> context =
+    BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, source,
+                SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
+opt::Module* module = context->module();
+EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
+                           << source << std::endl;
+const opt::Function* function = spvtest::GetFunction(module, 2);
+opt::LoopDescriptor& pre_pass_descriptor =
+    *context->GetLoopDescriptor(function);
+EXPECT_EQ(pre_pass_descriptor.NumLoops(), 3u);
+EXPECT_EQ(pre_pass_descriptor.pre_begin()->NumImmediateChildren(), 2u);
 
-  // Test that the pass transforms the ir into the expected output.
-  SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
-  SinglePassRunAndCheck<opt::LoopFissionPass>(source, expected, true);
+// Test that the pass transforms the ir into the expected output.
+SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
+SinglePassRunAndCheck<opt::LoopFissionPass>(source, expected, true);
 
-  // Test that the loop descriptor is correctly maintained and updated by the
-  // pass.
-  opt::LoopFissionPass loop_fission{};
-  loop_fission.Process(context.get());
+// Test that the loop descriptor is correctly maintained and updated by the
+// pass.
+opt::LoopFissionPass loop_fission{};
+loop_fission.Process(context.get());
 
-  function = spvtest::GetFunction(module, 2);
-  ir::LoopDescriptor& post_pass_descriptor =
-      *context->GetLoopDescriptor(function);
-  EXPECT_EQ(post_pass_descriptor.NumLoops(), 5u);
-  EXPECT_EQ(post_pass_descriptor.pre_begin()->NumImmediateChildren(), 4u);
+function = spvtest::GetFunction(module, 2);
+opt::LoopDescriptor& post_pass_descriptor =
+    *context->GetLoopDescriptor(function);
+EXPECT_EQ(post_pass_descriptor.NumLoops(), 5u);
+EXPECT_EQ(post_pass_descriptor.pre_begin()->NumImmediateChildren(), 4u);
 }
 
 /*
@@ -3161,36 +3159,36 @@
 OpFunctionEnd
 )";
   // clang-format on
-  std::unique_ptr<ir::IRContext> context =
-      BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, source,
-                  SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
-  EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
-                             << source << std::endl;
+std::unique_ptr<opt::IRContext> context =
+    BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, source,
+                SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
+opt::Module* module = context->module();
+EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
+                           << source << std::endl;
 
-  SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
-  SinglePassRunAndCheck<opt::LoopFissionPass>(source, expected, true);
+SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
+SinglePassRunAndCheck<opt::LoopFissionPass>(source, expected, true);
 
-  const ir::Function* function = spvtest::GetFunction(module, 2);
-  ir::LoopDescriptor& pre_pass_descriptor =
-      *context->GetLoopDescriptor(function);
-  EXPECT_EQ(pre_pass_descriptor.NumLoops(), 2u);
-  EXPECT_EQ(pre_pass_descriptor.pre_begin()->NumImmediateChildren(), 0u);
+const opt::Function* function = spvtest::GetFunction(module, 2);
+opt::LoopDescriptor& pre_pass_descriptor =
+    *context->GetLoopDescriptor(function);
+EXPECT_EQ(pre_pass_descriptor.NumLoops(), 2u);
+EXPECT_EQ(pre_pass_descriptor.pre_begin()->NumImmediateChildren(), 0u);
 
-  // Test that the pass transforms the ir into the expected output.
-  SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
-  SinglePassRunAndCheck<opt::LoopFissionPass>(source, expected, true);
+// Test that the pass transforms the ir into the expected output.
+SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
+SinglePassRunAndCheck<opt::LoopFissionPass>(source, expected, true);
 
-  // Test that the loop descriptor is correctly maintained and updated by the
-  // pass.
-  opt::LoopFissionPass loop_fission{};
-  loop_fission.Process(context.get());
+// Test that the loop descriptor is correctly maintained and updated by the
+// pass.
+opt::LoopFissionPass loop_fission{};
+loop_fission.Process(context.get());
 
-  function = spvtest::GetFunction(module, 2);
-  ir::LoopDescriptor& post_pass_descriptor =
-      *context->GetLoopDescriptor(function);
-  EXPECT_EQ(post_pass_descriptor.NumLoops(), 4u);
-  EXPECT_EQ(post_pass_descriptor.pre_begin()->NumImmediateChildren(), 0u);
+function = spvtest::GetFunction(module, 2);
+opt::LoopDescriptor& post_pass_descriptor =
+    *context->GetLoopDescriptor(function);
+EXPECT_EQ(post_pass_descriptor.NumLoops(), 4u);
+EXPECT_EQ(post_pass_descriptor.pre_begin()->NumImmediateChildren(), 0u);
 }
 
 /*
@@ -3277,15 +3275,15 @@
 )";
 
   // clang-format on
-  std::unique_ptr<ir::IRContext> context =
-      BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, source,
-                  SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
-  EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
-                             << source << std::endl;
+std::unique_ptr<opt::IRContext> context =
+    BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, source,
+                SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
+opt::Module* module = context->module();
+EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
+                           << source << std::endl;
 
-  SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
-  SinglePassRunAndCheck<opt::LoopFissionPass>(source, source, true);
+SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
+SinglePassRunAndCheck<opt::LoopFissionPass>(source, source, true);
 }
 
 /*
@@ -3478,15 +3476,15 @@
 OpFunctionEnd
 )";
   // clang-format on
-  std::unique_ptr<ir::IRContext> context =
-      BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, source,
-                  SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
-  EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
-                             << source << std::endl;
+std::unique_ptr<opt::IRContext> context =
+    BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, source,
+                SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
+opt::Module* module = context->module();
+EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
+                           << source << std::endl;
 
-  SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
-  SinglePassRunAndCheck<opt::LoopFissionPass>(source, expected, true);
+SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
+SinglePassRunAndCheck<opt::LoopFissionPass>(source, expected, true);
 }
 
 }  // namespace
diff --git a/test/opt/loop_optimizations/nested_loops.cpp b/test/opt/loop_optimizations/nested_loops.cpp
index 480a280..a9fafdb 100644
--- a/test/opt/loop_optimizations/nested_loops.cpp
+++ b/test/opt/loop_optimizations/nested_loops.cpp
@@ -150,14 +150,14 @@
                OpFunctionEnd
   )";
   // clang-format on
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  const ir::Function* f = spvtest::GetFunction(module, 2);
-  ir::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
+  const opt::Function* f = spvtest::GetFunction(module, 2);
+  opt::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
 
   EXPECT_EQ(ld.NumLoops(), 3u);
 
@@ -166,7 +166,7 @@
   // Not a loop header.
   EXPECT_EQ(ld[20], nullptr);
 
-  ir::Loop& parent_loop = *ld[21];
+  opt::Loop& parent_loop = *ld[21];
   EXPECT_TRUE(parent_loop.HasNestedLoops());
   EXPECT_FALSE(parent_loop.IsNested());
   EXPECT_EQ(parent_loop.GetDepth(), 1u);
@@ -175,7 +175,7 @@
   EXPECT_EQ(parent_loop.GetLatchBlock(), spvtest::GetBasicBlock(f, 23));
   EXPECT_EQ(parent_loop.GetMergeBlock(), spvtest::GetBasicBlock(f, 22));
 
-  ir::Loop& child_loop_1 = *ld[28];
+  opt::Loop& child_loop_1 = *ld[28];
   EXPECT_FALSE(child_loop_1.HasNestedLoops());
   EXPECT_TRUE(child_loop_1.IsNested());
   EXPECT_EQ(child_loop_1.GetDepth(), 2u);
@@ -184,7 +184,7 @@
   EXPECT_EQ(child_loop_1.GetLatchBlock(), spvtest::GetBasicBlock(f, 30));
   EXPECT_EQ(child_loop_1.GetMergeBlock(), spvtest::GetBasicBlock(f, 29));
 
-  ir::Loop& child_loop_2 = *ld[37];
+  opt::Loop& child_loop_2 = *ld[37];
   EXPECT_FALSE(child_loop_2.HasNestedLoops());
   EXPECT_TRUE(child_loop_2.IsNested());
   EXPECT_EQ(child_loop_2.GetDepth(), 2u);
@@ -194,7 +194,7 @@
   EXPECT_EQ(child_loop_2.GetMergeBlock(), spvtest::GetBasicBlock(f, 38));
 }
 
-static void CheckLoopBlocks(ir::Loop* loop,
+static void CheckLoopBlocks(opt::Loop* loop,
                             std::unordered_set<uint32_t>* expected_ids) {
   SCOPED_TRACE("Check loop " + std::to_string(loop->GetHeaderBlock()->id()));
   for (uint32_t bb_id : loop->GetBlocks()) {
@@ -336,14 +336,14 @@
                OpFunctionEnd
   )";
   // clang-format on
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  const ir::Function* f = spvtest::GetFunction(module, 2);
-  ir::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
+  const opt::Function* f = spvtest::GetFunction(module, 2);
+  opt::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
 
   EXPECT_EQ(ld.NumLoops(), 4u);
 
@@ -360,7 +360,7 @@
     std::unordered_set<uint32_t> basic_block_in_loop = {
         {23, 26, 29, 30, 33, 36, 40, 41, 44, 47, 43,
          42, 39, 50, 53, 56, 52, 51, 32, 31, 25}};
-    ir::Loop* loop = ld[23];
+    opt::Loop* loop = ld[23];
     CheckLoopBlocks(loop, &basic_block_in_loop);
 
     EXPECT_TRUE(loop->HasNestedLoops());
@@ -378,7 +378,7 @@
   {
     std::unordered_set<uint32_t> basic_block_in_loop = {
         {30, 33, 36, 40, 41, 44, 47, 43, 42, 39, 50, 53, 56, 52, 51, 32}};
-    ir::Loop* loop = ld[30];
+    opt::Loop* loop = ld[30];
     CheckLoopBlocks(loop, &basic_block_in_loop);
 
     EXPECT_TRUE(loop->HasNestedLoops());
@@ -395,7 +395,7 @@
 
   {
     std::unordered_set<uint32_t> basic_block_in_loop = {{41, 44, 47, 43}};
-    ir::Loop* loop = ld[41];
+    opt::Loop* loop = ld[41];
     CheckLoopBlocks(loop, &basic_block_in_loop);
 
     EXPECT_FALSE(loop->HasNestedLoops());
@@ -412,7 +412,7 @@
 
   {
     std::unordered_set<uint32_t> basic_block_in_loop = {{50, 53, 56, 52}};
-    ir::Loop* loop = ld[50];
+    opt::Loop* loop = ld[50];
     CheckLoopBlocks(loop, &basic_block_in_loop);
 
     EXPECT_FALSE(loop->HasNestedLoops());
@@ -429,11 +429,11 @@
 
   // Make sure LoopDescriptor gives us the inner most loop when we query for
   // loops.
-  for (const ir::BasicBlock& bb : *f) {
-    if (ir::Loop* loop = ld[&bb]) {
-      for (ir::Loop& sub_loop :
-           ir::make_range(++opt::TreeDFIterator<ir::Loop>(loop),
-                          opt::TreeDFIterator<ir::Loop>())) {
+  for (const opt::BasicBlock& bb : *f) {
+    if (opt::Loop* loop = ld[&bb]) {
+      for (opt::Loop& sub_loop :
+           opt::make_range(++opt::TreeDFIterator<opt::Loop>(loop),
+                           opt::TreeDFIterator<opt::Loop>())) {
         EXPECT_FALSE(sub_loop.IsInsideLoop(bb.id()));
       }
     }
@@ -560,19 +560,19 @@
                OpFunctionEnd
   )";
   // clang-format on
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  const ir::Function* f = spvtest::GetFunction(module, 2);
-  ir::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
+  const opt::Function* f = spvtest::GetFunction(module, 2);
+  opt::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
 
   EXPECT_EQ(ld.NumLoops(), 4u);
 
   {
-    ir::Loop& loop = *ld[22];
+    opt::Loop& loop = *ld[22];
     EXPECT_TRUE(loop.HasNestedLoops());
     EXPECT_FALSE(loop.IsNested());
     EXPECT_EQ(loop.GetDepth(), 1u);
@@ -580,7 +580,7 @@
   }
 
   {
-    ir::Loop& loop = *ld[29];
+    opt::Loop& loop = *ld[29];
     EXPECT_TRUE(loop.HasNestedLoops());
     EXPECT_TRUE(loop.IsNested());
     EXPECT_EQ(loop.GetDepth(), 2u);
@@ -588,7 +588,7 @@
   }
 
   {
-    ir::Loop& loop = *ld[36];
+    opt::Loop& loop = *ld[36];
     EXPECT_FALSE(loop.HasNestedLoops());
     EXPECT_TRUE(loop.IsNested());
     EXPECT_EQ(loop.GetDepth(), 3u);
@@ -596,7 +596,7 @@
   }
 
   {
-    ir::Loop& loop = *ld[47];
+    opt::Loop& loop = *ld[47];
     EXPECT_FALSE(loop.HasNestedLoops());
     EXPECT_TRUE(loop.IsNested());
     EXPECT_EQ(loop.GetDepth(), 2u);
@@ -701,21 +701,21 @@
                OpFunctionEnd
   )";
   // clang-format on
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  const ir::Function* f = spvtest::GetFunction(module, 2);
-  ir::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
+  const opt::Function* f = spvtest::GetFunction(module, 2);
+  opt::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
   // No invalidation of the cfg should occur during this test.
-  ir::CFG* cfg = context->cfg();
+  opt::CFG* cfg = context->cfg();
 
   EXPECT_EQ(ld.NumLoops(), 3u);
 
   {
-    ir::Loop& loop = *ld[16];
+    opt::Loop& loop = *ld[16];
     EXPECT_TRUE(loop.HasNestedLoops());
     EXPECT_FALSE(loop.IsNested());
     EXPECT_EQ(loop.GetDepth(), 1u);
@@ -723,7 +723,7 @@
   }
 
   {
-    ir::Loop& loop = *ld[33];
+    opt::Loop& loop = *ld[33];
     EXPECT_EQ(loop.GetPreHeaderBlock(), nullptr);
     EXPECT_NE(loop.GetOrCreatePreHeaderBlock(), nullptr);
     // Make sure the loop descriptor was properly updated.
@@ -737,7 +737,7 @@
       EXPECT_TRUE(pred_set.count(31));
       // Check the phi instructions.
       loop.GetPreHeaderBlock()->ForEachPhiInst(
-          [&pred_set](ir::Instruction* phi) {
+          [&pred_set](opt::Instruction* phi) {
             for (uint32_t i = 1; i < phi->NumInOperands(); i += 2) {
               EXPECT_TRUE(pred_set.count(phi->GetSingleWordInOperand(i)));
             }
@@ -751,7 +751,7 @@
       EXPECT_TRUE(pred_set.count(loop.GetPreHeaderBlock()->id()));
       EXPECT_TRUE(pred_set.count(35));
       // Check the phi instructions.
-      loop.GetHeaderBlock()->ForEachPhiInst([&pred_set](ir::Instruction* phi) {
+      loop.GetHeaderBlock()->ForEachPhiInst([&pred_set](opt::Instruction* phi) {
         for (uint32_t i = 1; i < phi->NumInOperands(); i += 2) {
           EXPECT_TRUE(pred_set.count(phi->GetSingleWordInOperand(i)));
         }
@@ -760,14 +760,14 @@
   }
 
   {
-    ir::Loop& loop = *ld[41];
+    opt::Loop& loop = *ld[41];
     EXPECT_EQ(loop.GetPreHeaderBlock(), nullptr);
     EXPECT_NE(loop.GetOrCreatePreHeaderBlock(), nullptr);
     EXPECT_EQ(ld[loop.GetPreHeaderBlock()], nullptr);
     EXPECT_EQ(cfg->preds(loop.GetPreHeaderBlock()->id()).size(), 1u);
     EXPECT_EQ(cfg->preds(loop.GetPreHeaderBlock()->id())[0], 25u);
     // Check the phi instructions.
-    loop.GetPreHeaderBlock()->ForEachPhiInst([](ir::Instruction* phi) {
+    loop.GetPreHeaderBlock()->ForEachPhiInst([](opt::Instruction* phi) {
       EXPECT_EQ(phi->NumInOperands(), 2u);
       EXPECT_EQ(phi->GetSingleWordInOperand(1), 25u);
     });
@@ -779,7 +779,7 @@
       EXPECT_TRUE(pred_set.count(loop.GetPreHeaderBlock()->id()));
       EXPECT_TRUE(pred_set.count(44));
       // Check the phi instructions.
-      loop.GetHeaderBlock()->ForEachPhiInst([&pred_set](ir::Instruction* phi) {
+      loop.GetHeaderBlock()->ForEachPhiInst([&pred_set](opt::Instruction* phi) {
         for (uint32_t i = 1; i < phi->NumInOperands(); i += 2) {
           EXPECT_TRUE(pred_set.count(phi->GetSingleWordInOperand(i)));
         }
diff --git a/test/opt/loop_optimizations/peeling.cpp b/test/opt/loop_optimizations/peeling.cpp
index e7ee3e8..223b108 100644
--- a/test/opt/loop_optimizations/peeling.cpp
+++ b/test/opt/loop_optimizations/peeling.cpp
@@ -41,7 +41,7 @@
   return error == 0;
 }
 
-void Match(const std::string& checks, ir::IRContext* context) {
+void Match(const std::string& checks, opt::IRContext* context) {
   // Silence unused warnings with !defined(SPIRV_EFFCE)
   (void)checks;
 
@@ -117,18 +117,18 @@
   // representing the loop count, if equals to 0, then the function build a 10
   // constant as loop count.
   auto test_cannot_peel = [](const std::string& text, uint32_t loop_count_id) {
-    std::unique_ptr<ir::IRContext> context =
+    std::unique_ptr<opt::IRContext> context =
         BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                     SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-    ir::Module* module = context->module();
+    opt::Module* module = context->module();
     EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                                << text << std::endl;
-    ir::Function& f = *module->begin();
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+    opt::Function& f = *module->begin();
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
 
     EXPECT_EQ(ld.NumLoops(), 1u);
 
-    ir::Instruction* loop_count = nullptr;
+    opt::Instruction* loop_count = nullptr;
     if (loop_count_id) {
       loop_count = context->get_def_use_mgr()->GetDef(loop_count_id);
     } else {
@@ -483,20 +483,20 @@
   {
     SCOPED_TRACE("Peel before");
 
-    std::unique_ptr<ir::IRContext> context =
+    std::unique_ptr<opt::IRContext> context =
         BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                     SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-    ir::Module* module = context->module();
+    opt::Module* module = context->module();
     EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                                << text << std::endl;
-    ir::Function& f = *module->begin();
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+    opt::Function& f = *module->begin();
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
 
     EXPECT_EQ(ld.NumLoops(), 1u);
 
     opt::InstructionBuilder builder(context.get(), &*f.begin());
     // Exit condition.
-    ir::Instruction* ten_cst = builder.Add32BitSignedIntegerConstant(10);
+    opt::Instruction* ten_cst = builder.Add32BitSignedIntegerConstant(10);
 
     opt::LoopPeeling peel(&*ld.begin(), ten_cst);
     EXPECT_TRUE(peel.CanPeelLoop());
@@ -537,20 +537,20 @@
   {
     SCOPED_TRACE("Peel after");
 
-    std::unique_ptr<ir::IRContext> context =
+    std::unique_ptr<opt::IRContext> context =
         BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                     SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-    ir::Module* module = context->module();
+    opt::Module* module = context->module();
     EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                                << text << std::endl;
-    ir::Function& f = *module->begin();
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+    opt::Function& f = *module->begin();
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
 
     EXPECT_EQ(ld.NumLoops(), 1u);
 
     opt::InstructionBuilder builder(context.get(), &*f.begin());
     // Exit condition.
-    ir::Instruction* ten_cst = builder.Add32BitSignedIntegerConstant(10);
+    opt::Instruction* ten_cst = builder.Add32BitSignedIntegerConstant(10);
 
     opt::LoopPeeling peel(&*ld.begin(), ten_cst);
     EXPECT_TRUE(peel.CanPeelLoop());
@@ -593,20 +593,20 @@
   {
     SCOPED_TRACE("Peel before with IV reuse");
 
-    std::unique_ptr<ir::IRContext> context =
+    std::unique_ptr<opt::IRContext> context =
         BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                     SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-    ir::Module* module = context->module();
+    opt::Module* module = context->module();
     EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                                << text << std::endl;
-    ir::Function& f = *module->begin();
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+    opt::Function& f = *module->begin();
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
 
     EXPECT_EQ(ld.NumLoops(), 1u);
 
     opt::InstructionBuilder builder(context.get(), &*f.begin());
     // Exit condition.
-    ir::Instruction* ten_cst = builder.Add32BitSignedIntegerConstant(10);
+    opt::Instruction* ten_cst = builder.Add32BitSignedIntegerConstant(10);
 
     opt::LoopPeeling peel(&*ld.begin(), ten_cst,
                           context->get_def_use_mgr()->GetDef(22));
@@ -646,20 +646,20 @@
   {
     SCOPED_TRACE("Peel after IV reuse");
 
-    std::unique_ptr<ir::IRContext> context =
+    std::unique_ptr<opt::IRContext> context =
         BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                     SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-    ir::Module* module = context->module();
+    opt::Module* module = context->module();
     EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                                << text << std::endl;
-    ir::Function& f = *module->begin();
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+    opt::Function& f = *module->begin();
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
 
     EXPECT_EQ(ld.NumLoops(), 1u);
 
     opt::InstructionBuilder builder(context.get(), &*f.begin());
     // Exit condition.
-    ir::Instruction* ten_cst = builder.Add32BitSignedIntegerConstant(10);
+    opt::Instruction* ten_cst = builder.Add32BitSignedIntegerConstant(10);
 
     opt::LoopPeeling peel(&*ld.begin(), ten_cst,
                           context->get_def_use_mgr()->GetDef(22));
@@ -755,18 +755,18 @@
   {
     SCOPED_TRACE("Peel before");
 
-    std::unique_ptr<ir::IRContext> context =
+    std::unique_ptr<opt::IRContext> context =
         BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                     SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-    ir::Module* module = context->module();
+    opt::Module* module = context->module();
     EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                                << text << std::endl;
-    ir::Function& f = *module->begin();
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+    opt::Function& f = *module->begin();
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
 
     EXPECT_EQ(ld.NumLoops(), 1u);
 
-    ir::Instruction* loop_count = context->get_def_use_mgr()->GetDef(16);
+    opt::Instruction* loop_count = context->get_def_use_mgr()->GetDef(16);
     EXPECT_EQ(loop_count->opcode(), SpvOpLoad);
 
     opt::LoopPeeling peel(&*ld.begin(), loop_count);
@@ -807,18 +807,18 @@
   {
     SCOPED_TRACE("Peel after");
 
-    std::unique_ptr<ir::IRContext> context =
+    std::unique_ptr<opt::IRContext> context =
         BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                     SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-    ir::Module* module = context->module();
+    opt::Module* module = context->module();
     EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                                << text << std::endl;
-    ir::Function& f = *module->begin();
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+    opt::Function& f = *module->begin();
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
 
     EXPECT_EQ(ld.NumLoops(), 1u);
 
-    ir::Instruction* loop_count = context->get_def_use_mgr()->GetDef(16);
+    opt::Instruction* loop_count = context->get_def_use_mgr()->GetDef(16);
     EXPECT_EQ(loop_count->opcode(), SpvOpLoad);
 
     opt::LoopPeeling peel(&*ld.begin(), loop_count);
@@ -908,19 +908,19 @@
   {
     SCOPED_TRACE("Peel before");
 
-    std::unique_ptr<ir::IRContext> context =
+    std::unique_ptr<opt::IRContext> context =
         BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                     SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-    ir::Module* module = context->module();
+    opt::Module* module = context->module();
     EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                                << text << std::endl;
-    ir::Function& f = *module->begin();
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+    opt::Function& f = *module->begin();
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
 
     EXPECT_EQ(ld.NumLoops(), 1u);
     opt::InstructionBuilder builder(context.get(), &*f.begin());
     // Exit condition.
-    ir::Instruction* ten_cst = builder.Add32BitUnsignedIntegerConstant(10);
+    opt::Instruction* ten_cst = builder.Add32BitUnsignedIntegerConstant(10);
 
     opt::LoopPeeling peel(&*ld.begin(), ten_cst);
     EXPECT_TRUE(peel.CanPeelLoop());
@@ -957,20 +957,20 @@
   {
     SCOPED_TRACE("Peel after");
 
-    std::unique_ptr<ir::IRContext> context =
+    std::unique_ptr<opt::IRContext> context =
         BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                     SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-    ir::Module* module = context->module();
+    opt::Module* module = context->module();
     EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                                << text << std::endl;
-    ir::Function& f = *module->begin();
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+    opt::Function& f = *module->begin();
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
 
     EXPECT_EQ(ld.NumLoops(), 1u);
 
     opt::InstructionBuilder builder(context.get(), &*f.begin());
     // Exit condition.
-    ir::Instruction* ten_cst = builder.Add32BitUnsignedIntegerConstant(10);
+    opt::Instruction* ten_cst = builder.Add32BitUnsignedIntegerConstant(10);
 
     opt::LoopPeeling peel(&*ld.begin(), ten_cst);
     EXPECT_TRUE(peel.CanPeelLoop());
@@ -1080,18 +1080,18 @@
   {
     SCOPED_TRACE("Peel before");
 
-    std::unique_ptr<ir::IRContext> context =
+    std::unique_ptr<opt::IRContext> context =
         BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                     SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-    ir::Module* module = context->module();
+    opt::Module* module = context->module();
     EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                                << text << std::endl;
-    ir::Function& f = *module->begin();
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+    opt::Function& f = *module->begin();
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
 
     EXPECT_EQ(ld.NumLoops(), 1u);
 
-    ir::Instruction* loop_count = context->get_def_use_mgr()->GetDef(15);
+    opt::Instruction* loop_count = context->get_def_use_mgr()->GetDef(15);
     EXPECT_EQ(loop_count->opcode(), SpvOpLoad);
 
     opt::LoopPeeling peel(&*ld.begin(), loop_count);
@@ -1132,18 +1132,18 @@
   {
     SCOPED_TRACE("Peel after");
 
-    std::unique_ptr<ir::IRContext> context =
+    std::unique_ptr<opt::IRContext> context =
         BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                     SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-    ir::Module* module = context->module();
+    opt::Module* module = context->module();
     EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                                << text << std::endl;
-    ir::Function& f = *module->begin();
-    ir::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
+    opt::Function& f = *module->begin();
+    opt::LoopDescriptor& ld = *context->GetLoopDescriptor(&f);
 
     EXPECT_EQ(ld.NumLoops(), 1u);
 
-    ir::Instruction* loop_count = context->get_def_use_mgr()->GetDef(15);
+    opt::Instruction* loop_count = context->get_def_use_mgr()->GetDef(15);
     EXPECT_EQ(loop_count->opcode(), SpvOpLoad);
 
     opt::LoopPeeling peel(&*ld.begin(), loop_count);
diff --git a/test/opt/loop_optimizations/peeling_pass.cpp b/test/opt/loop_optimizations/peeling_pass.cpp
index 6163176..adac0b7 100644
--- a/test/opt/loop_optimizations/peeling_pass.cpp
+++ b/test/opt/loop_optimizations/peeling_pass.cpp
@@ -72,8 +72,8 @@
     opt::LoopPeelingPass::LoopPeelingStats stats = AssembleAndRunPeelingTest(
         text_head, text_tail, opcode, res_id, op1, op2);
 
-    ir::Function& f = *context()->module()->begin();
-    ir::LoopDescriptor& ld = *context()->GetLoopDescriptor(&f);
+    opt::Function& f = *context()->module()->begin();
+    opt::LoopDescriptor& ld = *context()->GetLoopDescriptor(&f);
     EXPECT_EQ(ld.NumLoops(), nb_of_loops);
 
     return stats;
diff --git a/test/opt/loop_optimizations/unroll_assumptions.cpp b/test/opt/loop_optimizations/unroll_assumptions.cpp
index 3a991c7..da18b09 100644
--- a/test/opt/loop_optimizations/unroll_assumptions.cpp
+++ b/test/opt/loop_optimizations/unroll_assumptions.cpp
@@ -37,10 +37,10 @@
 
   const char* name() const override { return "Loop unroller"; }
 
-  Status Process(ir::IRContext* context) override {
+  Status Process(opt::IRContext* context) override {
     bool changed = false;
-    for (ir::Function& f : *context->module()) {
-      ir::LoopDescriptor& loop_descriptor = *context->GetLoopDescriptor(&f);
+    for (opt::Function& f : *context->module()) {
+      opt::LoopDescriptor& loop_descriptor = *context->GetLoopDescriptor(&f);
       for (auto& loop : loop_descriptor) {
         opt::LoopUtils loop_utils{context, &loop};
         if (loop_utils.PartiallyUnroll(factor)) {
@@ -120,10 +120,10 @@
 OpFunctionEnd
 )";
   // clang-format on
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
 
@@ -220,10 +220,10 @@
 OpFunctionEnd
 )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
 
@@ -301,16 +301,16 @@
 OpFunctionEnd
 )";
   // clang-format on
-  std::unique_ptr<ir::IRContext> context =
-      BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
-                  SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
-  EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
-                             << text << std::endl;
+std::unique_ptr<opt::IRContext> context =
+    BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
+                SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
+opt::Module* module = context->module();
+EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
+                           << text << std::endl;
 
-  opt::LoopUnroller loop_unroller;
-  SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
-  SinglePassRunAndCheck<opt::LoopUnroller>(text, text, false);
+opt::LoopUnroller loop_unroller;
+SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
+SinglePassRunAndCheck<opt::LoopUnroller>(text, text, false);
 }
 
 /*
@@ -382,16 +382,16 @@
 OpFunctionEnd
 )";
   // clang-format on
-  std::unique_ptr<ir::IRContext> context =
-      BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
-                  SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
-  EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
-                             << text << std::endl;
+std::unique_ptr<opt::IRContext> context =
+    BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
+                SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
+opt::Module* module = context->module();
+EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
+                           << text << std::endl;
 
-  opt::LoopUnroller loop_unroller;
-  SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
-  SinglePassRunAndCheck<opt::LoopUnroller>(text, text, false);
+opt::LoopUnroller loop_unroller;
+SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
+SinglePassRunAndCheck<opt::LoopUnroller>(text, text, false);
 }
 
 /*
@@ -519,10 +519,10 @@
 OpFunctionEnd
 )";
   // clang-format on
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
 
@@ -591,10 +591,10 @@
 OpFunctionEnd
 )";
   // clang-format on
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
 
@@ -662,10 +662,10 @@
 OpFunctionEnd
 )";
   // clang-format on
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
 
@@ -739,10 +739,10 @@
 OpFunctionEnd
 )";
   // clang-format on
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
 
@@ -957,10 +957,10 @@
 OpFunctionEnd
 )";
   // clang-format on
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
 
@@ -1031,10 +1031,10 @@
 OpFunctionEnd
 )";
   // clang-format on
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
 
@@ -1111,20 +1111,20 @@
 OpFunctionEnd
 )";
   // clang-format on
-  std::unique_ptr<ir::IRContext> context =
-      BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
-                  SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
-  EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
-                             << text << std::endl;
+std::unique_ptr<opt::IRContext> context =
+    BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
+                SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
+opt::Module* module = context->module();
+EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
+                           << text << std::endl;
 
-  opt::LoopUnroller loop_unroller;
-  SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
+opt::LoopUnroller loop_unroller;
+SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
 
-  // Make sure the pass doesn't run
-  SinglePassRunAndCheck<opt::LoopUnroller>(text, text, false);
-  SinglePassRunAndCheck<PartialUnrollerTestPass<1>>(text, text, false);
-  SinglePassRunAndCheck<PartialUnrollerTestPass<2>>(text, text, false);
+// Make sure the pass doesn't run
+SinglePassRunAndCheck<opt::LoopUnroller>(text, text, false);
+SinglePassRunAndCheck<PartialUnrollerTestPass<1>>(text, text, false);
+SinglePassRunAndCheck<PartialUnrollerTestPass<2>>(text, text, false);
 }
 
 /*
@@ -1190,20 +1190,20 @@
 OpFunctionEnd
 )";
   // clang-format on
-  std::unique_ptr<ir::IRContext> context =
-      BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
-                  SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
-  EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
-                             << text << std::endl;
+std::unique_ptr<opt::IRContext> context =
+    BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
+                SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
+opt::Module* module = context->module();
+EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
+                           << text << std::endl;
 
-  opt::LoopUnroller loop_unroller;
-  SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
+opt::LoopUnroller loop_unroller;
+SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
 
-  // Make sure the pass doesn't run
-  SinglePassRunAndCheck<opt::LoopUnroller>(text, text, false);
-  SinglePassRunAndCheck<PartialUnrollerTestPass<1>>(text, text, false);
-  SinglePassRunAndCheck<PartialUnrollerTestPass<2>>(text, text, false);
+// Make sure the pass doesn't run
+SinglePassRunAndCheck<opt::LoopUnroller>(text, text, false);
+SinglePassRunAndCheck<PartialUnrollerTestPass<1>>(text, text, false);
+SinglePassRunAndCheck<PartialUnrollerTestPass<2>>(text, text, false);
 }
 
 /*
@@ -1269,20 +1269,20 @@
 )";
 
   // clang-format on
-  std::unique_ptr<ir::IRContext> context =
-      BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
-                  SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
-  EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
-                             << text << std::endl;
+std::unique_ptr<opt::IRContext> context =
+    BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
+                SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
+opt::Module* module = context->module();
+EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
+                           << text << std::endl;
 
-  opt::LoopUnroller loop_unroller;
-  SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
+opt::LoopUnroller loop_unroller;
+SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
 
-  // Make sure the pass doesn't run
-  SinglePassRunAndCheck<opt::LoopUnroller>(text, text, false);
-  SinglePassRunAndCheck<PartialUnrollerTestPass<1>>(text, text, false);
-  SinglePassRunAndCheck<PartialUnrollerTestPass<2>>(text, text, false);
+// Make sure the pass doesn't run
+SinglePassRunAndCheck<opt::LoopUnroller>(text, text, false);
+SinglePassRunAndCheck<PartialUnrollerTestPass<1>>(text, text, false);
+SinglePassRunAndCheck<PartialUnrollerTestPass<2>>(text, text, false);
 }
 
 /*
@@ -1348,20 +1348,20 @@
 )";
 
   // clang-format on
-  std::unique_ptr<ir::IRContext> context =
-      BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
-                  SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
-  EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
-                             << text << std::endl;
+std::unique_ptr<opt::IRContext> context =
+    BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
+                SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
+opt::Module* module = context->module();
+EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
+                           << text << std::endl;
 
-  opt::LoopUnroller loop_unroller;
-  SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
+opt::LoopUnroller loop_unroller;
+SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
 
-  // Make sure the pass doesn't run
-  SinglePassRunAndCheck<opt::LoopUnroller>(text, text, false);
-  SinglePassRunAndCheck<PartialUnrollerTestPass<1>>(text, text, false);
-  SinglePassRunAndCheck<PartialUnrollerTestPass<2>>(text, text, false);
+// Make sure the pass doesn't run
+SinglePassRunAndCheck<opt::LoopUnroller>(text, text, false);
+SinglePassRunAndCheck<PartialUnrollerTestPass<1>>(text, text, false);
+SinglePassRunAndCheck<PartialUnrollerTestPass<2>>(text, text, false);
 }
 
 /*
@@ -1427,20 +1427,20 @@
 )";
 
   // clang-format on
-  std::unique_ptr<ir::IRContext> context =
-      BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
-                  SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
-  EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
-                             << text << std::endl;
+std::unique_ptr<opt::IRContext> context =
+    BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
+                SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
+opt::Module* module = context->module();
+EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
+                           << text << std::endl;
 
-  opt::LoopUnroller loop_unroller;
-  SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
+opt::LoopUnroller loop_unroller;
+SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
 
-  // Make sure the pass doesn't run
-  SinglePassRunAndCheck<opt::LoopUnroller>(text, text, false);
-  SinglePassRunAndCheck<PartialUnrollerTestPass<1>>(text, text, false);
-  SinglePassRunAndCheck<PartialUnrollerTestPass<2>>(text, text, false);
+// Make sure the pass doesn't run
+SinglePassRunAndCheck<opt::LoopUnroller>(text, text, false);
+SinglePassRunAndCheck<PartialUnrollerTestPass<1>>(text, text, false);
+SinglePassRunAndCheck<PartialUnrollerTestPass<2>>(text, text, false);
 }
 
 }  // namespace
diff --git a/test/opt/loop_optimizations/unroll_simple.cpp b/test/opt/loop_optimizations/unroll_simple.cpp
index bf310fc..7f985de 100644
--- a/test/opt/loop_optimizations/unroll_simple.cpp
+++ b/test/opt/loop_optimizations/unroll_simple.cpp
@@ -184,16 +184,16 @@
 OpFunctionEnd
 )";
   // clang-format on
-  std::unique_ptr<ir::IRContext> context =
-      BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
-                  SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
-  EXPECT_NE(nullptr, module) << "Assembling failed for ushader:\n"
-                             << text << std::endl;
+std::unique_ptr<opt::IRContext> context =
+    BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
+                SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
+opt::Module* module = context->module();
+EXPECT_NE(nullptr, module) << "Assembling failed for ushader:\n"
+                           << text << std::endl;
 
-  opt::LoopUnroller loop_unroller;
-  SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
-  SinglePassRunAndCheck<opt::LoopUnroller>(text, output, false);
+opt::LoopUnroller loop_unroller;
+SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
+SinglePassRunAndCheck<opt::LoopUnroller>(text, output, false);
 }
 
 template <int factor>
@@ -203,9 +203,9 @@
 
   const char* name() const override { return "Loop unroller"; }
 
-  Status Process(ir::IRContext* context) override {
-    for (ir::Function& f : *context->module()) {
-      ir::LoopDescriptor& loop_descriptor = *context->GetLoopDescriptor(&f);
+  Status Process(opt::IRContext* context) override {
+    for (opt::Function& f : *context->module()) {
+      opt::LoopDescriptor& loop_descriptor = *context->GetLoopDescriptor(&f);
       for (auto& loop : loop_descriptor) {
         opt::LoopUtils loop_utils{context, &loop};
         loop_utils.PartiallyUnroll(factor);
@@ -345,10 +345,10 @@
 OpFunctionEnd
 )";
   // clang-format on
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for ushader:\n"
                              << text << std::endl;
 
@@ -518,19 +518,19 @@
 OpFunctionEnd
 )";
   // clang-format on
-  std::unique_ptr<ir::IRContext> context =
-      BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
-                  SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
-  EXPECT_NE(nullptr, module) << "Assembling failed for ushader:\n"
-                             << text << std::endl;
+std::unique_ptr<opt::IRContext> context =
+    BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
+                SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
+opt::Module* module = context->module();
+EXPECT_NE(nullptr, module) << "Assembling failed for ushader:\n"
+                           << text << std::endl;
 
-  opt::LoopUnroller loop_unroller;
-  SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
-  // By unrolling by a factor that doesn't divide evenly into the number of loop
-  // iterations we perfom an additional transform when partially unrolling to
-  // account for the remainder.
-  SinglePassRunAndCheck<PartialUnrollerTestPass<3>>(text, output, false);
+opt::LoopUnroller loop_unroller;
+SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
+// By unrolling by a factor that doesn't divide evenly into the number of loop
+// iterations we perfom an additional transform when partially unrolling to
+// account for the remainder.
+SinglePassRunAndCheck<PartialUnrollerTestPass<3>>(text, output, false);
 }
 
 /* Generated from
@@ -598,26 +598,26 @@
 )";
   // clang-format on
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for ushader:\n"
                              << text << std::endl;
 
-  ir::Function* f = spvtest::GetFunction(module, 2);
+  opt::Function* f = spvtest::GetFunction(module, 2);
 
-  ir::LoopDescriptor& loop_descriptor = *context->GetLoopDescriptor(f);
+  opt::LoopDescriptor& loop_descriptor = *context->GetLoopDescriptor(f);
   EXPECT_EQ(loop_descriptor.NumLoops(), 1u);
 
-  ir::Loop& loop = loop_descriptor.GetLoopByIndex(0);
+  opt::Loop& loop = loop_descriptor.GetLoopByIndex(0);
 
   EXPECT_TRUE(loop.HasUnrollLoopControl());
 
-  ir::BasicBlock* condition = loop.FindConditionBlock();
+  opt::BasicBlock* condition = loop.FindConditionBlock();
   EXPECT_EQ(condition->id(), 24u);
 
-  ir::Instruction* induction = loop.FindConditionVariable(condition);
+  opt::Instruction* induction = loop.FindConditionVariable(condition);
   EXPECT_EQ(induction->result_id(), 34u);
 
   opt::LoopUtils loop_utils{context.get(), &loop};
@@ -694,27 +694,27 @@
 )";
   // clang-format on
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for ushader:\n"
                              << text << std::endl;
 
-  ir::Function* f = spvtest::GetFunction(module, 2);
+  opt::Function* f = spvtest::GetFunction(module, 2);
 
-  ir::LoopDescriptor& loop_descriptor = *context->GetLoopDescriptor(f);
+  opt::LoopDescriptor& loop_descriptor = *context->GetLoopDescriptor(f);
 
   EXPECT_EQ(loop_descriptor.NumLoops(), 1u);
 
-  ir::Loop& loop = loop_descriptor.GetLoopByIndex(0);
+  opt::Loop& loop = loop_descriptor.GetLoopByIndex(0);
 
   EXPECT_FALSE(loop.HasUnrollLoopControl());
 
-  ir::BasicBlock* condition = loop.FindConditionBlock();
+  opt::BasicBlock* condition = loop.FindConditionBlock();
   EXPECT_EQ(condition->id(), 25u);
 
-  ir::Instruction* induction = loop.FindConditionVariable(condition);
+  opt::Instruction* induction = loop.FindConditionVariable(condition);
   EXPECT_EQ(induction->result_id(), 35u);
 
   opt::LoopUtils loop_utils{context.get(), &loop};
@@ -965,15 +965,15 @@
 OpFunctionEnd
 )";
   // clang-format on
-  std::unique_ptr<ir::IRContext> context =
-      BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
-                  SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
-  EXPECT_NE(nullptr, module) << "Assembling failed for ushader:\n"
-                             << text << std::endl;
-  opt::LoopUnroller loop_unroller;
-  SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
-  SinglePassRunAndCheck<opt::LoopUnroller>(text, output, false);
+std::unique_ptr<opt::IRContext> context =
+    BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
+                SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
+opt::Module* module = context->module();
+EXPECT_NE(nullptr, module) << "Assembling failed for ushader:\n"
+                           << text << std::endl;
+opt::LoopUnroller loop_unroller;
+SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
+SinglePassRunAndCheck<opt::LoopUnroller>(text, output, false);
 }
 
 /*
@@ -1092,40 +1092,40 @@
 )";
   // clang-format on
 
-  std::unique_ptr<ir::IRContext> context =
-      BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
-                  SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
-  EXPECT_NE(nullptr, module) << "Assembling failed for ushader:\n"
-                             << text << std::endl;
+std::unique_ptr<opt::IRContext> context =
+    BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
+                SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
+opt::Module* module = context->module();
+EXPECT_NE(nullptr, module) << "Assembling failed for ushader:\n"
+                           << text << std::endl;
 
-  opt::LoopUnroller loop_unroller;
-  SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
-  // SinglePassRunAndCheck<opt::LoopUnroller>(text, expected, false);
+opt::LoopUnroller loop_unroller;
+SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
+// SinglePassRunAndCheck<opt::LoopUnroller>(text, expected, false);
 
-  ir::Function* f = spvtest::GetFunction(module, 4);
+opt::Function* f = spvtest::GetFunction(module, 4);
 
-  ir::LoopDescriptor& loop_descriptor = *context->GetLoopDescriptor(f);
-  EXPECT_EQ(loop_descriptor.NumLoops(), 1u);
+opt::LoopDescriptor& loop_descriptor = *context->GetLoopDescriptor(f);
+EXPECT_EQ(loop_descriptor.NumLoops(), 1u);
 
-  ir::Loop& loop = loop_descriptor.GetLoopByIndex(0);
+opt::Loop& loop = loop_descriptor.GetLoopByIndex(0);
 
-  EXPECT_TRUE(loop.HasUnrollLoopControl());
+EXPECT_TRUE(loop.HasUnrollLoopControl());
 
-  ir::BasicBlock* condition = loop.FindConditionBlock();
-  EXPECT_EQ(condition->id(), 14u);
+opt::BasicBlock* condition = loop.FindConditionBlock();
+EXPECT_EQ(condition->id(), 14u);
 
-  ir::Instruction* induction = loop.FindConditionVariable(condition);
-  EXPECT_EQ(induction->result_id(), 32u);
+opt::Instruction* induction = loop.FindConditionVariable(condition);
+EXPECT_EQ(induction->result_id(), 32u);
 
-  opt::LoopUtils loop_utils{context.get(), &loop};
-  EXPECT_TRUE(loop_utils.CanPerformUnroll());
+opt::LoopUtils loop_utils{context.get(), &loop};
+EXPECT_TRUE(loop_utils.CanPerformUnroll());
 
-  size_t iterations = 0;
-  EXPECT_TRUE(loop.FindNumberOfIterations(induction, &*condition->ctail(),
-                                          &iterations));
-  EXPECT_EQ(iterations, 2u);
-  SinglePassRunAndCheck<opt::LoopUnroller>(text, expected, false);
+size_t iterations = 0;
+EXPECT_TRUE(
+    loop.FindNumberOfIterations(induction, &*condition->ctail(), &iterations));
+EXPECT_EQ(iterations, 2u);
+SinglePassRunAndCheck<opt::LoopUnroller>(text, expected, false);
 }
 
 /*
@@ -1265,29 +1265,29 @@
 OpFunctionEnd
 )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for ushader:\n"
                              << text << std::endl;
 
   opt::LoopUnroller loop_unroller;
   SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
 
-  ir::Function* f = spvtest::GetFunction(module, 4);
+  opt::Function* f = spvtest::GetFunction(module, 4);
 
-  ir::LoopDescriptor& loop_descriptor = *context->GetLoopDescriptor(f);
+  opt::LoopDescriptor& loop_descriptor = *context->GetLoopDescriptor(f);
   EXPECT_EQ(loop_descriptor.NumLoops(), 1u);
 
-  ir::Loop& loop = loop_descriptor.GetLoopByIndex(0);
+  opt::Loop& loop = loop_descriptor.GetLoopByIndex(0);
 
   EXPECT_TRUE(loop.HasUnrollLoopControl());
 
-  ir::BasicBlock* condition = loop.FindConditionBlock();
+  opt::BasicBlock* condition = loop.FindConditionBlock();
   EXPECT_EQ(condition->id(), 14u);
 
-  ir::Instruction* induction = loop.FindConditionVariable(condition);
+  opt::Instruction* induction = loop.FindConditionVariable(condition);
   EXPECT_EQ(induction->result_id(), 32u);
 
   opt::LoopUtils loop_utils{context.get(), &loop};
@@ -1386,23 +1386,23 @@
   // clang-format on
 
   {  // Test fully unroll
-    std::unique_ptr<ir::IRContext> context =
+    std::unique_ptr<opt::IRContext> context =
         BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                     SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-    ir::Module* module = context->module();
+    opt::Module* module = context->module();
     EXPECT_NE(nullptr, module) << "Assembling failed for ushader:\n"
                                << text << std::endl;
     SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
 
-    ir::Function* f = spvtest::GetFunction(module, 4);
-    ir::LoopDescriptor& loop_descriptor = *context->GetLoopDescriptor(f);
+    opt::Function* f = spvtest::GetFunction(module, 4);
+    opt::LoopDescriptor& loop_descriptor = *context->GetLoopDescriptor(f);
     EXPECT_EQ(loop_descriptor.NumLoops(), 2u);
 
-    ir::Loop& outer_loop = loop_descriptor.GetLoopByIndex(1);
+    opt::Loop& outer_loop = loop_descriptor.GetLoopByIndex(1);
 
     EXPECT_TRUE(outer_loop.HasUnrollLoopControl());
 
-    ir::Loop& inner_loop = loop_descriptor.GetLoopByIndex(0);
+    opt::Loop& inner_loop = loop_descriptor.GetLoopByIndex(0);
 
     EXPECT_TRUE(inner_loop.HasUnrollLoopControl());
 
@@ -1430,23 +1430,23 @@
   }
 
   {  // Test partially unroll
-    std::unique_ptr<ir::IRContext> context =
+    std::unique_ptr<opt::IRContext> context =
         BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                     SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-    ir::Module* module = context->module();
+    opt::Module* module = context->module();
     EXPECT_NE(nullptr, module) << "Assembling failed for ushader:\n"
                                << text << std::endl;
     SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
 
-    ir::Function* f = spvtest::GetFunction(module, 4);
-    ir::LoopDescriptor& loop_descriptor = *context->GetLoopDescriptor(f);
+    opt::Function* f = spvtest::GetFunction(module, 4);
+    opt::LoopDescriptor& loop_descriptor = *context->GetLoopDescriptor(f);
     EXPECT_EQ(loop_descriptor.NumLoops(), 2u);
 
-    ir::Loop& outer_loop = loop_descriptor.GetLoopByIndex(1);
+    opt::Loop& outer_loop = loop_descriptor.GetLoopByIndex(1);
 
     EXPECT_TRUE(outer_loop.HasUnrollLoopControl());
 
-    ir::Loop& inner_loop = loop_descriptor.GetLoopByIndex(0);
+    opt::Loop& inner_loop = loop_descriptor.GetLoopByIndex(0);
 
     EXPECT_TRUE(inner_loop.HasUnrollLoopControl());
 
@@ -1599,16 +1599,16 @@
 OpFunctionEnd
 )";
   // clang-format on
-  std::unique_ptr<ir::IRContext> context =
-      BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
-                  SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
-  EXPECT_NE(nullptr, module) << "Assembling failed for ushader:\n"
-                             << text << std::endl;
+std::unique_ptr<opt::IRContext> context =
+    BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
+                SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
+opt::Module* module = context->module();
+EXPECT_NE(nullptr, module) << "Assembling failed for ushader:\n"
+                           << text << std::endl;
 
-  opt::LoopUnroller loop_unroller;
-  SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
-  SinglePassRunAndCheck<opt::LoopUnroller>(text, output, false);
+opt::LoopUnroller loop_unroller;
+SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
+SinglePassRunAndCheck<opt::LoopUnroller>(text, output, false);
 }
 
 /*
@@ -1742,16 +1742,16 @@
 OpFunctionEnd
 )";
   // clang-format on
-  std::unique_ptr<ir::IRContext> context =
-      BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
-                  SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
-  EXPECT_NE(nullptr, module) << "Assembling failed for ushader:\n"
-                             << text << std::endl;
+std::unique_ptr<opt::IRContext> context =
+    BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
+                SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
+opt::Module* module = context->module();
+EXPECT_NE(nullptr, module) << "Assembling failed for ushader:\n"
+                           << text << std::endl;
 
-  opt::LoopUnroller loop_unroller;
-  SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
-  SinglePassRunAndCheck<opt::LoopUnroller>(text, output, false);
+opt::LoopUnroller loop_unroller;
+SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
+SinglePassRunAndCheck<opt::LoopUnroller>(text, output, false);
 }
 
 /*
@@ -1884,16 +1884,16 @@
 OpFunctionEnd
 )";
   // clang-format on
-  std::unique_ptr<ir::IRContext> context =
-      BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
-                  SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
-  EXPECT_NE(nullptr, module) << "Assembling failed for ushader:\n"
-                             << text << std::endl;
+std::unique_ptr<opt::IRContext> context =
+    BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
+                SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
+opt::Module* module = context->module();
+EXPECT_NE(nullptr, module) << "Assembling failed for ushader:\n"
+                           << text << std::endl;
 
-  opt::LoopUnroller loop_unroller;
-  SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
-  SinglePassRunAndCheck<opt::LoopUnroller>(text, output, false);
+opt::LoopUnroller loop_unroller;
+SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
+SinglePassRunAndCheck<opt::LoopUnroller>(text, output, false);
 }
 
 /*
@@ -2039,16 +2039,16 @@
 OpFunctionEnd
 )";
   // clang-format on
-  std::unique_ptr<ir::IRContext> context =
-      BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
-                  SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
-  EXPECT_NE(nullptr, module) << "Assembling failed for ushader:\n"
-                             << text << std::endl;
+std::unique_ptr<opt::IRContext> context =
+    BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
+                SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
+opt::Module* module = context->module();
+EXPECT_NE(nullptr, module) << "Assembling failed for ushader:\n"
+                           << text << std::endl;
 
-  opt::LoopUnroller loop_unroller;
-  SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
-  SinglePassRunAndCheck<opt::LoopUnroller>(text, output, false);
+opt::LoopUnroller loop_unroller;
+SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
+SinglePassRunAndCheck<opt::LoopUnroller>(text, output, false);
 }
 
 // clang-format off
@@ -2219,17 +2219,17 @@
 OpFunctionEnd
 )";
   // clang-format on
-  std::unique_ptr<ir::IRContext> context =
-      BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, multiple_phi_shader,
-                  SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
-  EXPECT_NE(nullptr, module) << "Assembling failed for ushader:\n"
-                             << multiple_phi_shader << std::endl;
+std::unique_ptr<opt::IRContext> context =
+    BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, multiple_phi_shader,
+                SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
+opt::Module* module = context->module();
+EXPECT_NE(nullptr, module) << "Assembling failed for ushader:\n"
+                           << multiple_phi_shader << std::endl;
 
-  opt::LoopUnroller loop_unroller;
-  SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
-  SinglePassRunAndCheck<PartialUnrollerTestPass<4>>(multiple_phi_shader, output,
-                                                    false);
+opt::LoopUnroller loop_unroller;
+SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
+SinglePassRunAndCheck<PartialUnrollerTestPass<4>>(multiple_phi_shader, output,
+                                                  false);
 }
 
 TEST_F(PassClassTest, PartiallyUnrollMultipleInductionVariables) {
@@ -2297,17 +2297,17 @@
 OpFunctionEnd
 )";
   // clang-format on
-  std::unique_ptr<ir::IRContext> context =
-      BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, multiple_phi_shader,
-                  SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
-  EXPECT_NE(nullptr, module) << "Assembling failed for ushader:\n"
-                             << multiple_phi_shader << std::endl;
+std::unique_ptr<opt::IRContext> context =
+    BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, multiple_phi_shader,
+                SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
+opt::Module* module = context->module();
+EXPECT_NE(nullptr, module) << "Assembling failed for ushader:\n"
+                           << multiple_phi_shader << std::endl;
 
-  opt::LoopUnroller loop_unroller;
-  SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
-  SinglePassRunAndCheck<PartialUnrollerTestPass<2>>(multiple_phi_shader, output,
-                                                    false);
+opt::LoopUnroller loop_unroller;
+SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
+SinglePassRunAndCheck<PartialUnrollerTestPass<2>>(multiple_phi_shader, output,
+                                                  false);
 }
 
 TEST_F(PassClassTest, FullyUnrollMultipleInductionVariables) {
@@ -2423,16 +2423,16 @@
 OpFunctionEnd
 )";
   // clang-format on
-  std::unique_ptr<ir::IRContext> context =
-      BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, multiple_phi_shader,
-                  SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
-  EXPECT_NE(nullptr, module) << "Assembling failed for ushader:\n"
-                             << multiple_phi_shader << std::endl;
+std::unique_ptr<opt::IRContext> context =
+    BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, multiple_phi_shader,
+                SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
+opt::Module* module = context->module();
+EXPECT_NE(nullptr, module) << "Assembling failed for ushader:\n"
+                           << multiple_phi_shader << std::endl;
 
-  opt::LoopUnroller loop_unroller;
-  SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
-  SinglePassRunAndCheck<opt::LoopUnroller>(multiple_phi_shader, output, false);
+opt::LoopUnroller loop_unroller;
+SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
+SinglePassRunAndCheck<opt::LoopUnroller>(multiple_phi_shader, output, false);
 }
 
 /*
@@ -2586,16 +2586,16 @@
 OpFunctionEnd
 )";
   // clang-format on
-  std::unique_ptr<ir::IRContext> context =
-      BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
-                  SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
-  EXPECT_NE(nullptr, module) << "Assembling failed for ushader:\n"
-                             << text << std::endl;
+std::unique_ptr<opt::IRContext> context =
+    BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
+                SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
+opt::Module* module = context->module();
+EXPECT_NE(nullptr, module) << "Assembling failed for ushader:\n"
+                           << text << std::endl;
 
-  opt::LoopUnroller loop_unroller;
-  SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
-  SinglePassRunAndCheck<opt::LoopUnroller>(text, output, false);
+opt::LoopUnroller loop_unroller;
+SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
+SinglePassRunAndCheck<opt::LoopUnroller>(text, output, false);
 }
 
 // clang-format off
@@ -2701,16 +2701,16 @@
 OpFunctionEnd
 )";
   // clang-format on
-  std::unique_ptr<ir::IRContext> context =
-      BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, condition_in_header,
-                  SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
-  EXPECT_NE(nullptr, module) << "Assembling failed for ushader:\n"
-                             << condition_in_header << std::endl;
+std::unique_ptr<opt::IRContext> context =
+    BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, condition_in_header,
+                SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
+opt::Module* module = context->module();
+EXPECT_NE(nullptr, module) << "Assembling failed for ushader:\n"
+                           << condition_in_header << std::endl;
 
-  opt::LoopUnroller loop_unroller;
-  SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
-  SinglePassRunAndCheck<opt::LoopUnroller>(condition_in_header, output, false);
+opt::LoopUnroller loop_unroller;
+SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
+SinglePassRunAndCheck<opt::LoopUnroller>(condition_in_header, output, false);
 }
 
 TEST_F(PassClassTest, PartiallyUnrollResidualConditionIsInHeaderBlock) {
@@ -2783,17 +2783,17 @@
 OpFunctionEnd
 )";
   // clang-format on
-  std::unique_ptr<ir::IRContext> context =
-      BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, condition_in_header,
-                  SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
-  EXPECT_NE(nullptr, module) << "Assembling failed for ushader:\n"
-                             << condition_in_header << std::endl;
+std::unique_ptr<opt::IRContext> context =
+    BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, condition_in_header,
+                SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
+opt::Module* module = context->module();
+EXPECT_NE(nullptr, module) << "Assembling failed for ushader:\n"
+                           << condition_in_header << std::endl;
 
-  opt::LoopUnroller loop_unroller;
-  SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
-  SinglePassRunAndCheck<PartialUnrollerTestPass<2>>(condition_in_header, output,
-                                                    false);
+opt::LoopUnroller loop_unroller;
+SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
+SinglePassRunAndCheck<PartialUnrollerTestPass<2>>(condition_in_header, output,
+                                                  false);
 }
 
 /*
@@ -2973,25 +2973,25 @@
 
   // Make sure the latch block information is preserved and propagated correctly
   // by the pass.
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
 
   PartialUnrollerTestPass<3> unroller;
   unroller.Process(context.get());
 
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  const ir::Function* f = spvtest::GetFunction(module, 2);
-  ir::LoopDescriptor ld{f};
+  const opt::Function* f = spvtest::GetFunction(module, 2);
+  opt::LoopDescriptor ld{f};
 
   EXPECT_EQ(ld.NumLoops(), 2u);
 
-  ir::Loop& loop_1 = ld.GetLoopByIndex(0u);
+  opt::Loop& loop_1 = ld.GetLoopByIndex(0u);
   EXPECT_NE(loop_1.GetLatchBlock(), loop_1.GetContinueBlock());
 
-  ir::Loop& loop_2 = ld.GetLoopByIndex(1u);
+  opt::Loop& loop_2 = ld.GetLoopByIndex(1u);
   EXPECT_NE(loop_2.GetLatchBlock(), loop_2.GetContinueBlock());
 }
 
diff --git a/test/opt/module_test.cpp b/test/opt/module_test.cpp
index 177b45b..9c3324e 100644
--- a/test/opt/module_test.cpp
+++ b/test/opt/module_test.cpp
@@ -29,8 +29,8 @@
 
 using ::testing::Eq;
 using spvtest::GetIdBound;
-using spvtools::ir::IRContext;
-using spvtools::ir::Module;
+using spvtools::opt::IRContext;
+using spvtools::opt::Module;
 
 TEST(ModuleTest, SetIdBound) {
   Module m;
diff --git a/test/opt/module_utils.h b/test/opt/module_utils.h
index ad59058..5a3a1da 100644
--- a/test/opt/module_utils.h
+++ b/test/opt/module_utils.h
@@ -20,7 +20,7 @@
 
 namespace spvtest {
 
-inline uint32_t GetIdBound(const spvtools::ir::Module& m) {
+inline uint32_t GetIdBound(const spvtools::opt::Module& m) {
   std::vector<uint32_t> binary;
   m.ToBinary(&binary, false);
   // The 5-word header must always exist.
diff --git a/test/opt/pass_fixture.h b/test/opt/pass_fixture.h
index d935231..cbf7f6f 100644
--- a/test/opt/pass_fixture.h
+++ b/test/opt/pass_fixture.h
@@ -224,7 +224,7 @@
   }
 
   MessageConsumer consumer() { return consumer_; }
-  ir::IRContext* context() { return context_.get(); }
+  opt::IRContext* context() { return context_.get(); }
 
   void SetMessageConsumer(MessageConsumer msg_consumer) {
     consumer_ = msg_consumer;
@@ -232,7 +232,7 @@
 
  private:
   MessageConsumer consumer_;                // Message consumer.
-  std::unique_ptr<ir::IRContext> context_;  // IR context
+  std::unique_ptr<opt::IRContext> context_;  // IR context
   SpirvTools tools_;  // An instance for calling SPIRV-Tools functionalities.
   std::unique_ptr<opt::PassManager> manager_;  // The pass manager.
   uint32_t assemble_options_;
diff --git a/test/opt/pass_manager_test.cpp b/test/opt/pass_manager_test.cpp
index 2066eff..9aa31b8 100644
--- a/test/opt/pass_manager_test.cpp
+++ b/test/opt/pass_manager_test.cpp
@@ -74,8 +74,8 @@
 class AppendOpNopPass : public opt::Pass {
  public:
   const char* name() const override { return "AppendOpNop"; }
-  Status Process(ir::IRContext* irContext) override {
-    irContext->AddDebug1Inst(MakeUnique<ir::Instruction>(irContext));
+  Status Process(opt::IRContext* irContext) override {
+    irContext->AddDebug1Inst(MakeUnique<opt::Instruction>(irContext));
     return Status::SuccessWithChange;
   }
 };
@@ -87,9 +87,9 @@
   explicit AppendMultipleOpNopPass(uint32_t num_nop) : num_nop_(num_nop) {}
 
   const char* name() const override { return "AppendOpNop"; }
-  Status Process(ir::IRContext* irContext) override {
+  Status Process(opt::IRContext* irContext) override {
     for (uint32_t i = 0; i < num_nop_; i++) {
-      irContext->AddDebug1Inst(MakeUnique<ir::Instruction>(irContext));
+      irContext->AddDebug1Inst(MakeUnique<opt::Instruction>(irContext));
     }
     return Status::SuccessWithChange;
   }
@@ -102,8 +102,8 @@
 class DuplicateInstPass : public opt::Pass {
  public:
   const char* name() const override { return "DuplicateInst"; }
-  Status Process(ir::IRContext* irContext) override {
-    auto inst = MakeUnique<ir::Instruction>(
+  Status Process(opt::IRContext* irContext) override {
+    auto inst = MakeUnique<opt::Instruction>(
         *(--irContext->debug1_end())->Clone(irContext));
     irContext->AddDebug1Inst(std::move(inst));
     return Status::SuccessWithChange;
@@ -140,9 +140,9 @@
   explicit AppendTypeVoidInstPass(uint32_t result_id) : result_id_(result_id) {}
 
   const char* name() const override { return "AppendTypeVoidInstPass"; }
-  Status Process(ir::IRContext* irContext) override {
-    auto inst = MakeUnique<ir::Instruction>(
-        irContext, SpvOpTypeVoid, 0, result_id_, std::vector<ir::Operand>{});
+  Status Process(opt::IRContext* irContext) override {
+    auto inst = MakeUnique<opt::Instruction>(
+        irContext, SpvOpTypeVoid, 0, result_id_, std::vector<opt::Operand>{});
     irContext->AddType(std::move(inst));
     return Status::SuccessWithChange;
   }
@@ -153,9 +153,9 @@
 
 TEST(PassManager, RecomputeIdBoundAutomatically) {
   opt::PassManager manager;
-  std::unique_ptr<ir::Module> module(new ir::Module());
-  ir::IRContext context(SPV_ENV_UNIVERSAL_1_2, std::move(module),
-                        manager.consumer());
+  std::unique_ptr<opt::Module> module(new opt::Module());
+  opt::IRContext context(SPV_ENV_UNIVERSAL_1_2, std::move(module),
+                         manager.consumer());
   EXPECT_THAT(GetIdBound(*context.module()), Eq(0u));
 
   manager.Run(&context);
diff --git a/test/opt/pass_remove_duplicates_test.cpp b/test/opt/pass_remove_duplicates_test.cpp
index 84aa9f8..c8b9bb7 100644
--- a/test/opt/pass_remove_duplicates_test.cpp
+++ b/test/opt/pass_remove_duplicates_test.cpp
@@ -25,8 +25,8 @@
 
 namespace {
 
-using spvtools::ir::Instruction;
-using spvtools::ir::IRContext;
+using spvtools::opt::IRContext;
+using spvtools::opt::Instruction;
 using spvtools::opt::PassManager;
 using spvtools::opt::RemoveDuplicatesPass;
 
diff --git a/test/opt/pass_test.cpp b/test/opt/pass_test.cpp
index 5ff1a12..da5e01c 100644
--- a/test/opt/pass_test.cpp
+++ b/test/opt/pass_test.cpp
@@ -27,7 +27,7 @@
 class DummyPass : public opt::Pass {
  public:
   const char* name() const override { return "dummy-pass"; }
-  Status Process(ir::IRContext* irContext) override {
+  Status Process(opt::IRContext* irContext) override {
     return irContext ? Status::SuccessWithoutChange : Status::Failure;
   }
 };
@@ -76,14 +76,14 @@
 )";
   // clang-format on
 
-  std::unique_ptr<ir::IRContext> localContext =
+  std::unique_ptr<opt::IRContext> localContext =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   EXPECT_NE(nullptr, localContext) << "Assembling failed for shader:\n"
                                    << text << std::endl;
   DummyPass testPass;
   std::vector<uint32_t> processed;
-  opt::Pass::ProcessFunction mark_visited = [&processed](ir::Function* fp) {
+  opt::Pass::ProcessFunction mark_visited = [&processed](opt::Function* fp) {
     processed.push_back(fp->result_id());
     return false;
   };
@@ -132,7 +132,7 @@
 )";
   // clang-format on
 
-  std::unique_ptr<ir::IRContext> localContext =
+  std::unique_ptr<opt::IRContext> localContext =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   EXPECT_NE(nullptr, localContext) << "Assembling failed for shader:\n"
@@ -140,7 +140,7 @@
 
   DummyPass testPass;
   std::vector<uint32_t> processed;
-  opt::Pass::ProcessFunction mark_visited = [&processed](ir::Function* fp) {
+  opt::Pass::ProcessFunction mark_visited = [&processed](opt::Function* fp) {
     processed.push_back(fp->result_id());
     return false;
   };
@@ -184,7 +184,7 @@
 )";
   // clang-format on
 
-  std::unique_ptr<ir::IRContext> localContext =
+  std::unique_ptr<opt::IRContext> localContext =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   EXPECT_NE(nullptr, localContext) << "Assembling failed for shader:\n"
@@ -192,7 +192,7 @@
 
   DummyPass testPass;
   std::vector<uint32_t> processed;
-  opt::Pass::ProcessFunction mark_visited = [&processed](ir::Function* fp) {
+  opt::Pass::ProcessFunction mark_visited = [&processed](opt::Function* fp) {
     processed.push_back(fp->result_id());
     return false;
   };
@@ -226,7 +226,7 @@
 )";
   // clang-format on
 
-  std::unique_ptr<ir::IRContext> localContext =
+  std::unique_ptr<opt::IRContext> localContext =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   EXPECT_NE(nullptr, localContext) << "Assembling failed for shader:\n"
@@ -234,7 +234,7 @@
 
   DummyPass testPass;
   std::vector<uint32_t> processed;
-  opt::Pass::ProcessFunction mark_visited = [&processed](ir::Function* fp) {
+  opt::Pass::ProcessFunction mark_visited = [&processed](opt::Function* fp) {
     processed.push_back(fp->result_id());
     return false;
   };
diff --git a/test/opt/propagator_test.cpp b/test/opt/propagator_test.cpp
index b6cd2c4..2ff6dda 100644
--- a/test/opt/propagator_test.cpp
+++ b/test/opt/propagator_test.cpp
@@ -58,7 +58,7 @@
     return values_vec_;
   }
 
-  std::unique_ptr<ir::IRContext> ctx_;
+  std::unique_ptr<opt::IRContext> ctx_;
   std::map<uint32_t, uint32_t> values_;
   std::vector<uint32_t> values_vec_;
 };
@@ -101,13 +101,13 @@
                )";
   Assemble(spv_asm);
 
-  const auto visit_fn = [this](ir::Instruction* instr,
-                               ir::BasicBlock** dest_bb) {
+  const auto visit_fn = [this](opt::Instruction* instr,
+                               opt::BasicBlock** dest_bb) {
     *dest_bb = nullptr;
     if (instr->opcode() == SpvOpStore) {
       uint32_t lhs_id = instr->GetSingleWordOperand(0);
       uint32_t rhs_id = instr->GetSingleWordOperand(1);
-      ir::Instruction* rhs_def = ctx_->get_def_use_mgr()->GetDef(rhs_id);
+      opt::Instruction* rhs_def = ctx_->get_def_use_mgr()->GetDef(rhs_id);
       if (rhs_def->opcode() == SpvOpConstant) {
         uint32_t val = rhs_def->GetSingleWordOperand(2);
         values_[lhs_id] = val;
@@ -168,13 +168,13 @@
 
   Assemble(spv_asm);
 
-  ir::Instruction *phi_instr = nullptr;
-  const auto visit_fn = [this, &phi_instr](ir::Instruction* instr,
-                                           ir::BasicBlock** dest_bb) {
+  opt::Instruction* phi_instr = nullptr;
+  const auto visit_fn = [this, &phi_instr](opt::Instruction* instr,
+                                           opt::BasicBlock** dest_bb) {
     *dest_bb = nullptr;
     if (instr->opcode() == SpvOpLoad) {
       uint32_t rhs_id = instr->GetSingleWordOperand(2);
-      ir::Instruction* rhs_def = ctx_->get_def_use_mgr()->GetDef(rhs_id);
+      opt::Instruction* rhs_def = ctx_->get_def_use_mgr()->GetDef(rhs_id);
       if (rhs_def->opcode() == SpvOpConstant) {
         uint32_t val = rhs_def->GetSingleWordOperand(2);
         values_[instr->result_id()] = val;
diff --git a/test/opt/register_liveness.cpp b/test/opt/register_liveness.cpp
index 1425cf9..0f0f7b6 100644
--- a/test/opt/register_liveness.cpp
+++ b/test/opt/register_liveness.cpp
@@ -31,9 +31,9 @@
 
 using PassClassTest = PassTest<::testing::Test>;
 
-static void CompareSets(const std::unordered_set<ir::Instruction*>& computed,
+static void CompareSets(const std::unordered_set<opt::Instruction*>& computed,
                         const std::unordered_set<uint32_t>& expected) {
-  for (ir::Instruction* insn : computed) {
+  for (opt::Instruction* insn : computed) {
     EXPECT_TRUE(expected.count(insn->result_id()))
         << "Unexpected instruction in live set: " << *insn;
   }
@@ -111,13 +111,13 @@
                OpReturn
                OpFunctionEnd
   )";
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  ir::Function* f = &*module->begin();
+  opt::Function* f = &*module->begin();
   opt::LivenessAnalysis* liveness_analysis = context->GetLivenessAnalysis();
   const opt::RegisterLiveness* register_liveness = liveness_analysis->Get(f);
   {
@@ -411,16 +411,16 @@
                OpReturn
                OpFunctionEnd
   )";
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  ir::Function* f = &*module->begin();
+  opt::Function* f = &*module->begin();
   opt::LivenessAnalysis* liveness_analysis = context->GetLivenessAnalysis();
   const opt::RegisterLiveness* register_liveness = liveness_analysis->Get(f);
-  ir::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
+  opt::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
 
   {
     SCOPED_TRACE("Block 5");
@@ -1211,25 +1211,25 @@
                OpReturn
                OpFunctionEnd
     )";
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, source,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << source << std::endl;
-  ir::Function* f = &*module->begin();
+  opt::Function* f = &*module->begin();
   opt::LivenessAnalysis* liveness_analysis = context->GetLivenessAnalysis();
   const opt::RegisterLiveness* register_liveness = liveness_analysis->Get(f);
-  ir::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
+  opt::LoopDescriptor& ld = *context->GetLoopDescriptor(f);
   opt::analysis::DefUseManager& def_use_mgr = *context->get_def_use_mgr();
 
   {
     opt::RegisterLiveness::RegionRegisterLiveness l1_sim_resut;
     opt::RegisterLiveness::RegionRegisterLiveness l2_sim_resut;
-    std::unordered_set<ir::Instruction*> moved_instructions{
+    std::unordered_set<opt::Instruction*> moved_instructions{
         def_use_mgr.GetDef(29), def_use_mgr.GetDef(30), def_use_mgr.GetDef(31),
         def_use_mgr.GetDef(31)->NextNode()};
-    std::unordered_set<ir::Instruction*> copied_instructions{
+    std::unordered_set<opt::Instruction*> copied_instructions{
         def_use_mgr.GetDef(22), def_use_mgr.GetDef(27),
         def_use_mgr.GetDef(27)->NextNode(), def_use_mgr.GetDef(23)};
 
diff --git a/test/opt/scalar_analysis.cpp b/test/opt/scalar_analysis.cpp
index a73953e..dc53842 100644
--- a/test/opt/scalar_analysis.cpp
+++ b/test/opt/scalar_analysis.cpp
@@ -99,18 +99,18 @@
                OpFunctionEnd
   )";
   // clang-format on
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  const ir::Function* f = spvtest::GetFunction(module, 4);
+  const opt::Function* f = spvtest::GetFunction(module, 4);
   opt::ScalarEvolutionAnalysis analysis{context.get()};
 
-  const ir::Instruction* store = nullptr;
-  const ir::Instruction* load = nullptr;
-  for (const ir::Instruction& inst : *spvtest::GetBasicBlock(f, 11)) {
+  const opt::Instruction* store = nullptr;
+  const opt::Instruction* load = nullptr;
+  for (const opt::Instruction& inst : *spvtest::GetBasicBlock(f, 11)) {
     if (inst.opcode() == SpvOp::SpvOpStore) {
       store = &inst;
     }
@@ -122,10 +122,10 @@
   EXPECT_NE(load, nullptr);
   EXPECT_NE(store, nullptr);
 
-  ir::Instruction* access_chain =
+  opt::Instruction* access_chain =
       context->get_def_use_mgr()->GetDef(load->GetSingleWordInOperand(0));
 
-  ir::Instruction* child = context->get_def_use_mgr()->GetDef(
+  opt::Instruction* child = context->get_def_use_mgr()->GetDef(
       access_chain->GetSingleWordInOperand(1));
   const opt::SENode* node = analysis.AnalyzeInstruction(child);
 
@@ -228,17 +228,17 @@
                OpFunctionEnd
 )";
   // clang-format on
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  const ir::Function* f = spvtest::GetFunction(module, 2);
+  const opt::Function* f = spvtest::GetFunction(module, 2);
   opt::ScalarEvolutionAnalysis analysis{context.get()};
 
-  const ir::Instruction* load = nullptr;
-  for (const ir::Instruction& inst : *spvtest::GetBasicBlock(f, 28)) {
+  const opt::Instruction* load = nullptr;
+  for (const opt::Instruction& inst : *spvtest::GetBasicBlock(f, 28)) {
     if (inst.opcode() == SpvOp::SpvOpLoad) {
       load = &inst;
     }
@@ -246,10 +246,10 @@
 
   EXPECT_NE(load, nullptr);
 
-  ir::Instruction* access_chain =
+  opt::Instruction* access_chain =
       context->get_def_use_mgr()->GetDef(load->GetSingleWordInOperand(0));
 
-  ir::Instruction* child = context->get_def_use_mgr()->GetDef(
+  opt::Instruction* child = context->get_def_use_mgr()->GetDef(
       access_chain->GetSingleWordInOperand(1));
   //  const opt::SENode* node =
   //  analysis.GetNodeFromInstruction(child->unique_id());
@@ -345,17 +345,17 @@
                OpFunctionEnd
     )";
   // clang-format on
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  const ir::Function* f = spvtest::GetFunction(module, 2);
+  const opt::Function* f = spvtest::GetFunction(module, 2);
   opt::ScalarEvolutionAnalysis analysis{context.get()};
 
-  const ir::Instruction* load = nullptr;
-  for (const ir::Instruction& inst : *spvtest::GetBasicBlock(f, 21)) {
+  const opt::Instruction* load = nullptr;
+  for (const opt::Instruction& inst : *spvtest::GetBasicBlock(f, 21)) {
     if (inst.opcode() == SpvOp::SpvOpLoad && inst.result_id() == 33) {
       load = &inst;
     }
@@ -363,10 +363,10 @@
 
   EXPECT_NE(load, nullptr);
 
-  ir::Instruction* access_chain =
+  opt::Instruction* access_chain =
       context->get_def_use_mgr()->GetDef(load->GetSingleWordInOperand(0));
 
-  ir::Instruction* child = context->get_def_use_mgr()->GetDef(
+  opt::Instruction* child = context->get_def_use_mgr()->GetDef(
       access_chain->GetSingleWordInOperand(1));
 
   const opt::SENode* node = analysis.AnalyzeInstruction(child);
@@ -496,21 +496,21 @@
                OpFunctionEnd
 )";
   // clang-format on
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  const ir::Function* f = spvtest::GetFunction(module, 4);
+  const opt::Function* f = spvtest::GetFunction(module, 4);
   opt::ScalarEvolutionAnalysis analysis{context.get()};
 
-  const ir::Instruction* loads[6];
-  const ir::Instruction* stores[6];
+  const opt::Instruction* loads[6];
+  const opt::Instruction* stores[6];
   int load_count = 0;
   int store_count = 0;
 
-  for (const ir::Instruction& inst : *spvtest::GetBasicBlock(f, 22)) {
+  for (const opt::Instruction& inst : *spvtest::GetBasicBlock(f, 22)) {
     if (inst.opcode() == SpvOp::SpvOpLoad) {
       loads[load_count] = &inst;
       ++load_count;
@@ -524,10 +524,10 @@
   EXPECT_EQ(load_count, 6);
   EXPECT_EQ(store_count, 6);
 
-  ir::Instruction* load_access_chain;
-  ir::Instruction* store_access_chain;
-  ir::Instruction* load_child;
-  ir::Instruction* store_child;
+  opt::Instruction* load_access_chain;
+  opt::Instruction* store_access_chain;
+  opt::Instruction* load_child;
+  opt::Instruction* store_child;
   opt::SENode* load_node;
   opt::SENode* store_node;
   opt::SENode* subtract_node;
@@ -735,21 +735,21 @@
                OpReturn
                OpFunctionEnd
     )";
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  const ir::Function* f = spvtest::GetFunction(module, 2);
+  const opt::Function* f = spvtest::GetFunction(module, 2);
   opt::ScalarEvolutionAnalysis analysis{context.get()};
 
-  const ir::Instruction* loads[2] = {nullptr, nullptr};
-  const ir::Instruction* stores[2] = {nullptr, nullptr};
+  const opt::Instruction* loads[2] = {nullptr, nullptr};
+  const opt::Instruction* stores[2] = {nullptr, nullptr};
   int load_count = 0;
   int store_count = 0;
 
-  for (const ir::Instruction& inst : *spvtest::GetBasicBlock(f, 31)) {
+  for (const opt::Instruction& inst : *spvtest::GetBasicBlock(f, 31)) {
     if (inst.opcode() == SpvOp::SpvOpLoad) {
       loads[load_count] = &inst;
       ++load_count;
@@ -763,14 +763,14 @@
   EXPECT_EQ(load_count, 2);
   EXPECT_EQ(store_count, 2);
 
-  ir::Instruction* load_access_chain =
+  opt::Instruction* load_access_chain =
       context->get_def_use_mgr()->GetDef(loads[0]->GetSingleWordInOperand(0));
-  ir::Instruction* store_access_chain =
+  opt::Instruction* store_access_chain =
       context->get_def_use_mgr()->GetDef(stores[0]->GetSingleWordInOperand(0));
 
-  ir::Instruction* load_child = context->get_def_use_mgr()->GetDef(
+  opt::Instruction* load_child = context->get_def_use_mgr()->GetDef(
       load_access_chain->GetSingleWordInOperand(1));
-  ir::Instruction* store_child = context->get_def_use_mgr()->GetDef(
+  opt::Instruction* store_child = context->get_def_use_mgr()->GetDef(
       store_access_chain->GetSingleWordInOperand(1));
 
   opt::SENode* store_node = analysis.AnalyzeInstruction(store_child);
@@ -872,19 +872,19 @@
                OpReturn
                OpFunctionEnd
     )";
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  const ir::Function* f = spvtest::GetFunction(module, 2);
+  const opt::Function* f = spvtest::GetFunction(module, 2);
   opt::ScalarEvolutionAnalysis analysis{context.get()};
 
-  const ir::Instruction* loads[1] = {nullptr};
+  const opt::Instruction* loads[1] = {nullptr};
   int load_count = 0;
 
-  for (const ir::Instruction& inst : *spvtest::GetBasicBlock(f, 29)) {
+  for (const opt::Instruction& inst : *spvtest::GetBasicBlock(f, 29)) {
     if (inst.opcode() == SpvOp::SpvOpLoad) {
       loads[load_count] = &inst;
       ++load_count;
@@ -893,9 +893,9 @@
 
   EXPECT_EQ(load_count, 1);
 
-  ir::Instruction* load_access_chain =
+  opt::Instruction* load_access_chain =
       context->get_def_use_mgr()->GetDef(loads[0]->GetSingleWordInOperand(0));
-  ir::Instruction* load_child = context->get_def_use_mgr()->GetDef(
+  opt::Instruction* load_child = context->get_def_use_mgr()->GetDef(
       load_access_chain->GetSingleWordInOperand(1));
 
   opt::SENode* load_node = analysis.AnalyzeInstruction(load_child);
@@ -1017,19 +1017,19 @@
                OpReturn
                OpFunctionEnd
     )";
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  const ir::Function* f = spvtest::GetFunction(module, 2);
+  const opt::Function* f = spvtest::GetFunction(module, 2);
   opt::ScalarEvolutionAnalysis analysis{context.get()};
 
-  std::vector<const ir::Instruction*> loads{};
-  std::vector<const ir::Instruction*> stores{};
+  std::vector<const opt::Instruction*> loads{};
+  std::vector<const opt::Instruction*> stores{};
 
-  for (const ir::Instruction& inst : *spvtest::GetBasicBlock(f, 30)) {
+  for (const opt::Instruction& inst : *spvtest::GetBasicBlock(f, 30)) {
     if (inst.opcode() == SpvOp::SpvOpLoad) {
       loads.push_back(&inst);
     }
@@ -1041,20 +1041,20 @@
   EXPECT_EQ(loads.size(), 3u);
   EXPECT_EQ(stores.size(), 2u);
   {
-    ir::Instruction* store_access_chain = context->get_def_use_mgr()->GetDef(
+    opt::Instruction* store_access_chain = context->get_def_use_mgr()->GetDef(
         stores[0]->GetSingleWordInOperand(0));
 
-    ir::Instruction* store_child = context->get_def_use_mgr()->GetDef(
+    opt::Instruction* store_child = context->get_def_use_mgr()->GetDef(
         store_access_chain->GetSingleWordInOperand(1));
 
     opt::SENode* store_node = analysis.AnalyzeInstruction(store_child);
 
     opt::SENode* store_simplified = analysis.SimplifyExpression(store_node);
 
-    ir::Instruction* load_access_chain =
+    opt::Instruction* load_access_chain =
         context->get_def_use_mgr()->GetDef(loads[1]->GetSingleWordInOperand(0));
 
-    ir::Instruction* load_child = context->get_def_use_mgr()->GetDef(
+    opt::Instruction* load_child = context->get_def_use_mgr()->GetDef(
         load_access_chain->GetSingleWordInOperand(1));
 
     opt::SENode* load_node = analysis.AnalyzeInstruction(load_child);
@@ -1082,18 +1082,18 @@
   }
 
   {
-    ir::Instruction* store_access_chain = context->get_def_use_mgr()->GetDef(
+    opt::Instruction* store_access_chain = context->get_def_use_mgr()->GetDef(
         stores[1]->GetSingleWordInOperand(0));
 
-    ir::Instruction* store_child = context->get_def_use_mgr()->GetDef(
+    opt::Instruction* store_child = context->get_def_use_mgr()->GetDef(
         store_access_chain->GetSingleWordInOperand(1));
     opt::SENode* store_node = analysis.AnalyzeInstruction(store_child);
     opt::SENode* store_simplified = analysis.SimplifyExpression(store_node);
 
-    ir::Instruction* load_access_chain =
+    opt::Instruction* load_access_chain =
         context->get_def_use_mgr()->GetDef(loads[2]->GetSingleWordInOperand(0));
 
-    ir::Instruction* load_child = context->get_def_use_mgr()->GetDef(
+    opt::Instruction* load_child = context->get_def_use_mgr()->GetDef(
         load_access_chain->GetSingleWordInOperand(1));
 
     opt::SENode* load_node = analysis.AnalyzeInstruction(load_child);
@@ -1191,18 +1191,18 @@
                OpReturn
                OpFunctionEnd
   )";
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-  ir::Module* module = context->module();
+  opt::Module* module = context->module();
   EXPECT_NE(nullptr, module) << "Assembling failed for shader:\n"
                              << text << std::endl;
-  const ir::Function* f = spvtest::GetFunction(module, 2);
+  const opt::Function* f = spvtest::GetFunction(module, 2);
   opt::ScalarEvolutionAnalysis analysis{context.get()};
 
-  std::vector<const ir::Instruction*> phis{};
+  std::vector<const opt::Instruction*> phis{};
 
-  for (const ir::Instruction& inst : *spvtest::GetBasicBlock(f, 21)) {
+  for (const opt::Instruction& inst : *spvtest::GetBasicBlock(f, 21)) {
     if (inst.opcode() == SpvOp::SpvOpPhi) {
       phis.push_back(&inst);
     }
diff --git a/test/opt/type_manager_test.cpp b/test/opt/type_manager_test.cpp
index 7d86e14..3655873 100644
--- a/test/opt/type_manager_test.cpp
+++ b/test/opt/type_manager_test.cpp
@@ -43,7 +43,7 @@
   return error == 0;
 }
 
-void Match(const std::string& original, ir::IRContext* context,
+void Match(const std::string& original, opt::IRContext* context,
            bool do_validation = true) {
   std::vector<uint32_t> bin;
   context->module()->ToBinary(&bin, true);
@@ -235,7 +235,7 @@
       {28, "named_barrier"},
   };
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text);
   opt::analysis::TypeManager manager(nullptr, context.get());
 
@@ -271,7 +271,7 @@
                OpFunctionEnd
   )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   opt::analysis::TypeManager manager(nullptr, context.get());
@@ -315,7 +315,7 @@
                OpFunctionEnd
   )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   opt::analysis::TypeManager manager(nullptr, context.get());
@@ -365,7 +365,7 @@
                OpFunctionEnd
   )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   opt::analysis::TypeManager manager(nullptr, context.get());
@@ -408,7 +408,7 @@
                OpFunctionEnd
   )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   opt::analysis::TypeManager manager(nullptr, context.get());
@@ -457,7 +457,7 @@
                OpFunctionEnd
   )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   opt::analysis::TypeManager manager(nullptr, context.get());
@@ -483,7 +483,7 @@
     %struct4 = OpTypeStruct %u32 %f32 ; the same
     %struct7 = OpTypeStruct %f32      ; no decoration
   )";
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text);
   opt::analysis::TypeManager manager(nullptr, context.get());
 
@@ -532,7 +532,7 @@
     %struct7  = OpTypeStruct %u32 %f32 ; extra decoration on the struct
     %struct10 = OpTypeStruct %u32 %f32 ; no member decoration
   )";
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text);
   opt::analysis::TypeManager manager(nullptr, context.get());
 
@@ -569,7 +569,7 @@
     %struct2  = OpTypeStruct %f32 %u32
     %struct5  = OpTypeStruct %f32
   )";
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text);
   opt::analysis::TypeManager manager(nullptr, context.get());
 
@@ -590,7 +590,7 @@
 
 TEST(TypeManager, BeginEndForEmptyModule) {
   const std::string text = "";
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text);
   opt::analysis::TypeManager manager(nullptr, context.get());
   ASSERT_EQ(0u, manager.NumTypes());
@@ -606,7 +606,7 @@
     %u32     = OpTypeInt 32 0
     %f64     = OpTypeFloat 64
   )";
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text);
   opt::analysis::TypeManager manager(nullptr, context.get());
   ASSERT_EQ(5u, manager.NumTypes());
@@ -642,7 +642,7 @@
 %vec2 = OpTypeVector %int 2
 )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
   EXPECT_NE(context, nullptr);
   TypeManager manager(nullptr, context.get());
@@ -670,7 +670,7 @@
 %2 = OpTypeInt 32 1
   )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   EXPECT_NE(context, nullptr);
@@ -693,7 +693,7 @@
 %2 = OpTypeStruct %1
   )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   EXPECT_NE(context, nullptr);
@@ -716,7 +716,7 @@
 %3 = OpTypeStruct %1
   )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   EXPECT_NE(context, nullptr);
@@ -741,7 +741,7 @@
 %3 = OpTypeStruct %1
   )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   EXPECT_NE(context, nullptr);
@@ -768,7 +768,7 @@
 %2 = OpTypeStruct %1
   )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   EXPECT_NE(context, nullptr);
@@ -802,7 +802,7 @@
 %2 = OpTypeInt 32 0
   )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   EXPECT_NE(context, nullptr);
@@ -824,7 +824,7 @@
 %3 = OpTypeStruct %1
   )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   EXPECT_NE(context, nullptr);
@@ -844,7 +844,7 @@
 %2 = OpTypeStruct %1
   )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   EXPECT_NE(context, nullptr);
@@ -864,7 +864,7 @@
 %1 = OpTypeInt 32 0
 )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   EXPECT_NE(context, nullptr);
@@ -887,7 +887,7 @@
 OpMemoryModel Logical GLSL450
 )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   EXPECT_NE(context, nullptr);
@@ -913,7 +913,7 @@
 %1 = OpTypeInt 32 0
 )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   EXPECT_NE(context, nullptr);
@@ -946,7 +946,7 @@
 OpMemoryModel Logical GLSL450
   )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
   EXPECT_NE(context, nullptr);
 
@@ -968,7 +968,7 @@
 OpMemoryModel Logical GLSL450
   )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
   EXPECT_NE(context, nullptr);
 
@@ -1051,7 +1051,7 @@
 %100 = OpConstant %uint 100
   )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   EXPECT_NE(context, nullptr);
@@ -1077,7 +1077,7 @@
 %uint = OpTypeInt 32 0
   )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   EXPECT_NE(context, nullptr);
@@ -1108,7 +1108,7 @@
 %3 = OpTypePointer Function %2
   )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   EXPECT_NE(context, nullptr);
@@ -1133,7 +1133,7 @@
 %3 = OpTypePointer Function %1
   )";
 
-  std::unique_ptr<ir::IRContext> context =
+  std::unique_ptr<opt::IRContext> context =
       BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text,
                   SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
   EXPECT_NE(context, nullptr);
diff --git a/test/opt/value_table_test.cpp b/test/opt/value_table_test.cpp
index 4f42c81..1390e56 100644
--- a/test/opt/value_table_test.cpp
+++ b/test/opt/value_table_test.cpp
@@ -50,7 +50,7 @@
   )";
   auto context = BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
   opt::ValueNumberTable vtable(context.get());
-  ir::Instruction* inst = context->get_def_use_mgr()->GetDef(10);
+  opt::Instruction* inst = context->get_def_use_mgr()->GetDef(10);
   EXPECT_EQ(vtable.GetValueNumber(inst), vtable.GetValueNumber(inst));
 }
 
@@ -77,8 +77,8 @@
   )";
   auto context = BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
   opt::ValueNumberTable vtable(context.get());
-  ir::Instruction* inst1 = context->get_def_use_mgr()->GetDef(10);
-  ir::Instruction* inst2 = context->get_def_use_mgr()->GetDef(11);
+  opt::Instruction* inst1 = context->get_def_use_mgr()->GetDef(10);
+  opt::Instruction* inst2 = context->get_def_use_mgr()->GetDef(11);
   EXPECT_EQ(vtable.GetValueNumber(inst1), vtable.GetValueNumber(inst2));
 }
 
@@ -107,8 +107,8 @@
   )";
   auto context = BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
   opt::ValueNumberTable vtable(context.get());
-  ir::Instruction* inst1 = context->get_def_use_mgr()->GetDef(10);
-  ir::Instruction* inst2 = context->get_def_use_mgr()->GetDef(12);
+  opt::Instruction* inst1 = context->get_def_use_mgr()->GetDef(10);
+  opt::Instruction* inst2 = context->get_def_use_mgr()->GetDef(12);
   EXPECT_EQ(vtable.GetValueNumber(inst1), vtable.GetValueNumber(inst2));
 }
 
@@ -135,8 +135,8 @@
   )";
   auto context = BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
   opt::ValueNumberTable vtable(context.get());
-  ir::Instruction* inst1 = context->get_def_use_mgr()->GetDef(10);
-  ir::Instruction* inst2 = context->get_def_use_mgr()->GetDef(11);
+  opt::Instruction* inst1 = context->get_def_use_mgr()->GetDef(10);
+  opt::Instruction* inst2 = context->get_def_use_mgr()->GetDef(11);
   EXPECT_NE(vtable.GetValueNumber(inst1), vtable.GetValueNumber(inst2));
 }
 
@@ -165,8 +165,8 @@
   )";
   auto context = BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
   opt::ValueNumberTable vtable(context.get());
-  ir::Instruction* inst1 = context->get_def_use_mgr()->GetDef(10);
-  ir::Instruction* inst2 = context->get_def_use_mgr()->GetDef(12);
+  opt::Instruction* inst1 = context->get_def_use_mgr()->GetDef(10);
+  opt::Instruction* inst2 = context->get_def_use_mgr()->GetDef(12);
   EXPECT_NE(vtable.GetValueNumber(inst1), vtable.GetValueNumber(inst2));
 }
 
@@ -191,7 +191,7 @@
   )";
   auto context = BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
   opt::ValueNumberTable vtable(context.get());
-  ir::Instruction* inst = context->get_def_use_mgr()->GetDef(9);
+  opt::Instruction* inst = context->get_def_use_mgr()->GetDef(9);
   EXPECT_EQ(vtable.GetValueNumber(inst), vtable.GetValueNumber(inst));
 }
 
@@ -219,8 +219,8 @@
   )";
   auto context = BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
   opt::ValueNumberTable vtable(context.get());
-  ir::Instruction* inst1 = context->get_def_use_mgr()->GetDef(9);
-  ir::Instruction* inst2 = context->get_def_use_mgr()->GetDef(10);
+  opt::Instruction* inst1 = context->get_def_use_mgr()->GetDef(9);
+  opt::Instruction* inst2 = context->get_def_use_mgr()->GetDef(10);
   EXPECT_NE(vtable.GetValueNumber(inst1), vtable.GetValueNumber(inst2));
 }
 
@@ -246,8 +246,8 @@
   )";
   auto context = BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
   opt::ValueNumberTable vtable(context.get());
-  ir::Instruction* inst1 = context->get_def_use_mgr()->GetDef(9);
-  ir::Instruction* inst2 = context->get_def_use_mgr()->GetDef(10);
+  opt::Instruction* inst1 = context->get_def_use_mgr()->GetDef(9);
+  opt::Instruction* inst2 = context->get_def_use_mgr()->GetDef(10);
   EXPECT_EQ(vtable.GetValueNumber(inst1), vtable.GetValueNumber(inst2));
 }
 
@@ -273,8 +273,8 @@
   )";
   auto context = BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
   opt::ValueNumberTable vtable(context.get());
-  ir::Instruction* inst1 = context->get_def_use_mgr()->GetDef(9);
-  ir::Instruction* inst2 = context->get_def_use_mgr()->GetDef(10);
+  opt::Instruction* inst1 = context->get_def_use_mgr()->GetDef(9);
+  opt::Instruction* inst2 = context->get_def_use_mgr()->GetDef(10);
   EXPECT_EQ(vtable.GetValueNumber(inst1), vtable.GetValueNumber(inst2));
 }
 
@@ -300,8 +300,8 @@
   )";
   auto context = BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
   opt::ValueNumberTable vtable(context.get());
-  ir::Instruction* inst1 = context->get_def_use_mgr()->GetDef(9);
-  ir::Instruction* inst2 = context->get_def_use_mgr()->GetDef(10);
+  opt::Instruction* inst1 = context->get_def_use_mgr()->GetDef(9);
+  opt::Instruction* inst2 = context->get_def_use_mgr()->GetDef(10);
   EXPECT_EQ(vtable.GetValueNumber(inst1), vtable.GetValueNumber(inst2));
 }
 
@@ -327,8 +327,8 @@
   )";
   auto context = BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
   opt::ValueNumberTable vtable(context.get());
-  ir::Instruction* inst1 = context->get_def_use_mgr()->GetDef(9);
-  ir::Instruction* inst2 = context->get_def_use_mgr()->GetDef(10);
+  opt::Instruction* inst1 = context->get_def_use_mgr()->GetDef(9);
+  opt::Instruction* inst2 = context->get_def_use_mgr()->GetDef(10);
   EXPECT_EQ(vtable.GetValueNumber(inst1), vtable.GetValueNumber(inst2));
 }
 
@@ -359,7 +359,7 @@
   )";
   auto context = BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
   opt::ValueNumberTable vtable(context.get());
-  ir::Instruction* inst = context->get_def_use_mgr()->GetDef(10);
+  opt::Instruction* inst = context->get_def_use_mgr()->GetDef(10);
   EXPECT_EQ(vtable.GetValueNumber(inst), vtable.GetValueNumber(inst));
 }
 
@@ -392,8 +392,8 @@
   )";
   auto context = BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
   opt::ValueNumberTable vtable(context.get());
-  ir::Instruction* inst1 = context->get_def_use_mgr()->GetDef(10);
-  ir::Instruction* inst2 = context->get_def_use_mgr()->GetDef(12);
+  opt::Instruction* inst1 = context->get_def_use_mgr()->GetDef(10);
+  opt::Instruction* inst2 = context->get_def_use_mgr()->GetDef(12);
   EXPECT_NE(vtable.GetValueNumber(inst1), vtable.GetValueNumber(inst2));
 }
 
@@ -423,8 +423,8 @@
   )";
   auto context = BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
   opt::ValueNumberTable vtable(context.get());
-  ir::Instruction* inst1 = context->get_def_use_mgr()->GetDef(11);
-  ir::Instruction* inst2 = context->get_def_use_mgr()->GetDef(12);
+  opt::Instruction* inst1 = context->get_def_use_mgr()->GetDef(11);
+  opt::Instruction* inst2 = context->get_def_use_mgr()->GetDef(12);
   EXPECT_NE(vtable.GetValueNumber(inst1), vtable.GetValueNumber(inst2));
 }
 
@@ -450,8 +450,8 @@
   )";
   auto context = BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
   opt::ValueNumberTable vtable(context.get());
-  ir::Instruction* inst1 = context->get_def_use_mgr()->GetDef(9);
-  ir::Instruction* inst2 = context->get_def_use_mgr()->GetDef(10);
+  opt::Instruction* inst1 = context->get_def_use_mgr()->GetDef(9);
+  opt::Instruction* inst2 = context->get_def_use_mgr()->GetDef(10);
   EXPECT_EQ(vtable.GetValueNumber(inst1), vtable.GetValueNumber(inst2));
 }
 
@@ -488,9 +488,9 @@
   )";
   auto context = BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
   opt::ValueNumberTable vtable(context.get());
-  ir::Instruction* inst1 = context->get_def_use_mgr()->GetDef(13);
-  ir::Instruction* inst2 = context->get_def_use_mgr()->GetDef(15);
-  ir::Instruction* phi = context->get_def_use_mgr()->GetDef(16);
+  opt::Instruction* inst1 = context->get_def_use_mgr()->GetDef(13);
+  opt::Instruction* inst2 = context->get_def_use_mgr()->GetDef(15);
+  opt::Instruction* phi = context->get_def_use_mgr()->GetDef(16);
   EXPECT_EQ(vtable.GetValueNumber(inst1), vtable.GetValueNumber(inst2));
   EXPECT_EQ(vtable.GetValueNumber(inst1), vtable.GetValueNumber(phi));
 }
@@ -529,9 +529,9 @@
   )";
   auto context = BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
   opt::ValueNumberTable vtable(context.get());
-  ir::Instruction* inst1 = context->get_def_use_mgr()->GetDef(14);
-  ir::Instruction* inst2 = context->get_def_use_mgr()->GetDef(16);
-  ir::Instruction* phi = context->get_def_use_mgr()->GetDef(17);
+  opt::Instruction* inst1 = context->get_def_use_mgr()->GetDef(14);
+  opt::Instruction* inst2 = context->get_def_use_mgr()->GetDef(16);
+  opt::Instruction* phi = context->get_def_use_mgr()->GetDef(17);
   EXPECT_NE(vtable.GetValueNumber(inst1), vtable.GetValueNumber(inst2));
   EXPECT_NE(vtable.GetValueNumber(inst1), vtable.GetValueNumber(phi));
   EXPECT_NE(vtable.GetValueNumber(inst2), vtable.GetValueNumber(phi));
@@ -574,14 +574,14 @@
   )";
   auto context = BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
   opt::ValueNumberTable vtable(context.get());
-  ir::Instruction* inst1 = context->get_def_use_mgr()->GetDef(12);
-  ir::Instruction* inst2 = context->get_def_use_mgr()->GetDef(16);
+  opt::Instruction* inst1 = context->get_def_use_mgr()->GetDef(12);
+  opt::Instruction* inst2 = context->get_def_use_mgr()->GetDef(16);
   EXPECT_EQ(vtable.GetValueNumber(inst1), vtable.GetValueNumber(inst2));
 
-  ir::Instruction* phi1 = context->get_def_use_mgr()->GetDef(15);
+  opt::Instruction* phi1 = context->get_def_use_mgr()->GetDef(15);
   EXPECT_NE(vtable.GetValueNumber(inst1), vtable.GetValueNumber(phi1));
 
-  ir::Instruction* phi2 = context->get_def_use_mgr()->GetDef(18);
+  opt::Instruction* phi2 = context->get_def_use_mgr()->GetDef(18);
   EXPECT_EQ(vtable.GetValueNumber(inst1), vtable.GetValueNumber(phi2));
   EXPECT_NE(vtable.GetValueNumber(phi1), vtable.GetValueNumber(phi2));
 }