// Copyright (c) 2017 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "source/opt/ir_context.h"

#include <cstring>

#include "OpenCLDebugInfo100.h"
#include "source/latest_version_glsl_std_450_header.h"
#include "source/opt/log.h"
#include "source/opt/reflect.h"

namespace spvtools {
namespace opt {
namespace {
constexpr int kSpvDecorateTargetIdInIdx = 0;
constexpr int kSpvDecorateDecorationInIdx = 1;
constexpr int kSpvDecorateBuiltinInIdx = 2;
constexpr int kEntryPointInterfaceInIdx = 3;
constexpr int kEntryPointFunctionIdInIdx = 1;
constexpr int kEntryPointExecutionModelInIdx = 0;

// Constants for OpenCL.DebugInfo.100 / NonSemantic.Shader.DebugInfo.100
// extension instructions.
constexpr uint32_t kDebugFunctionOperandFunctionIndex = 13;
constexpr uint32_t kDebugGlobalVariableOperandVariableIndex = 11;
}  // namespace

void IRContext::BuildInvalidAnalyses(IRContext::Analysis set) {
  set = Analysis(set & ~valid_analyses_);

  if (set & kAnalysisDefUse) {
    BuildDefUseManager();
  }
  if (set & kAnalysisInstrToBlockMapping) {
    BuildInstrToBlockMapping();
  }
  if (set & kAnalysisDecorations) {
    BuildDecorationManager();
  }
  if (set & kAnalysisCFG) {
    BuildCFG();
  }
  if (set & kAnalysisDominatorAnalysis) {
    ResetDominatorAnalysis();
  }
  if (set & kAnalysisLoopAnalysis) {
    ResetLoopAnalysis();
  }
  if (set & kAnalysisBuiltinVarId) {
    ResetBuiltinAnalysis();
  }
  if (set & kAnalysisNameMap) {
    BuildIdToNameMap();
  }
  if (set & kAnalysisScalarEvolution) {
    BuildScalarEvolutionAnalysis();
  }
  if (set & kAnalysisRegisterPressure) {
    BuildRegPressureAnalysis();
  }
  if (set & kAnalysisValueNumberTable) {
    BuildValueNumberTable();
  }
  if (set & kAnalysisStructuredCFG) {
    BuildStructuredCFGAnalysis();
  }
  if (set & kAnalysisIdToFuncMapping) {
    BuildIdToFuncMapping();
  }
  if (set & kAnalysisConstants) {
    BuildConstantManager();
  }
  if (set & kAnalysisTypes) {
    BuildTypeManager();
  }
  if (set & kAnalysisDebugInfo) {
    BuildDebugInfoManager();
  }
}

void IRContext::InvalidateAnalysesExceptFor(
    IRContext::Analysis preserved_analyses) {
  uint32_t analyses_to_invalidate = valid_analyses_ & (~preserved_analyses);
  InvalidateAnalyses(static_cast<IRContext::Analysis>(analyses_to_invalidate));
}

void IRContext::InvalidateAnalyses(IRContext::Analysis analyses_to_invalidate) {
  // The ConstantManager and DebugInfoManager contain Type pointers. If the
  // TypeManager goes away, the ConstantManager and DebugInfoManager have to
  // go away.
  if (analyses_to_invalidate & kAnalysisTypes) {
    analyses_to_invalidate |= kAnalysisConstants;
    analyses_to_invalidate |= kAnalysisDebugInfo;
  }

  // The dominator analysis hold the pseudo entry and exit nodes from the CFG.
  // Also if the CFG change the dominators many changed as well, so the
  // dominator analysis should be invalidated as well.
  if (analyses_to_invalidate & kAnalysisCFG) {
    analyses_to_invalidate |= kAnalysisDominatorAnalysis;
  }

  if (analyses_to_invalidate & kAnalysisDefUse) {
    def_use_mgr_.reset(nullptr);
  }
  if (analyses_to_invalidate & kAnalysisInstrToBlockMapping) {
    instr_to_block_.clear();
  }
  if (analyses_to_invalidate & kAnalysisDecorations) {
    decoration_mgr_.reset(nullptr);
  }
  if (analyses_to_invalidate & kAnalysisCombinators) {
    combinator_ops_.clear();
  }
  if (analyses_to_invalidate & kAnalysisBuiltinVarId) {
    builtin_var_id_map_.clear();
  }
  if (analyses_to_invalidate & kAnalysisCFG) {
    cfg_.reset(nullptr);
  }
  if (analyses_to_invalidate & kAnalysisDominatorAnalysis) {
    dominator_trees_.clear();
    post_dominator_trees_.clear();
  }
  if (analyses_to_invalidate & kAnalysisNameMap) {
    id_to_name_.reset(nullptr);
  }
  if (analyses_to_invalidate & kAnalysisValueNumberTable) {
    vn_table_.reset(nullptr);
  }
  if (analyses_to_invalidate & kAnalysisStructuredCFG) {
    struct_cfg_analysis_.reset(nullptr);
  }
  if (analyses_to_invalidate & kAnalysisIdToFuncMapping) {
    id_to_func_.clear();
  }
  if (analyses_to_invalidate & kAnalysisConstants) {
    constant_mgr_.reset(nullptr);
  }
  if (analyses_to_invalidate & kAnalysisLiveness) {
    liveness_mgr_.reset(nullptr);
  }
  if (analyses_to_invalidate & kAnalysisTypes) {
    type_mgr_.reset(nullptr);
  }

  if (analyses_to_invalidate & kAnalysisDebugInfo) {
    debug_info_mgr_.reset(nullptr);
  }

  valid_analyses_ = Analysis(valid_analyses_ & ~analyses_to_invalidate);
}

Instruction* IRContext::KillInst(Instruction* inst) {
  if (!inst) {
    return nullptr;
  }

  KillNamesAndDecorates(inst);

  KillOperandFromDebugInstructions(inst);

  if (AreAnalysesValid(kAnalysisDefUse)) {
    analysis::DefUseManager* def_use_mgr = get_def_use_mgr();
    def_use_mgr->ClearInst(inst);
    for (auto& l_inst : inst->dbg_line_insts()) def_use_mgr->ClearInst(&l_inst);
  }
  if (AreAnalysesValid(kAnalysisInstrToBlockMapping)) {
    instr_to_block_.erase(inst);
  }
  if (AreAnalysesValid(kAnalysisDecorations)) {
    if (inst->IsDecoration()) {
      decoration_mgr_->RemoveDecoration(inst);
    }
  }
  if (AreAnalysesValid(kAnalysisDebugInfo)) {
    get_debug_info_mgr()->ClearDebugScopeAndInlinedAtUses(inst);
    get_debug_info_mgr()->ClearDebugInfo(inst);
  }
  if (type_mgr_ && IsTypeInst(inst->opcode())) {
    type_mgr_->RemoveId(inst->result_id());
  }
  if (constant_mgr_ && IsConstantInst(inst->opcode())) {
    constant_mgr_->RemoveId(inst->result_id());
  }
  if (inst->opcode() == spv::Op::OpCapability ||
      inst->opcode() == spv::Op::OpExtension) {
    // We reset the feature manager, instead of updating it, because it is just
    // as much work.  We would have to remove all capabilities implied by this
    // capability that are not also implied by the remaining OpCapability
    // instructions. We could update extensions, but we will see if it is
    // needed.
    ResetFeatureManager();
  }

  RemoveFromIdToName(inst);

  Instruction* next_instruction = nullptr;
  if (inst->IsInAList()) {
    next_instruction = inst->NextNode();
    inst->RemoveFromList();
    delete inst;
  } else {
    // Needed for instructions that are not part of a list like OpLabels,
    // OpFunction, OpFunctionEnd, etc..
    inst->ToNop();
  }
  return next_instruction;
}

bool IRContext::KillInstructionIf(Module::inst_iterator begin,
                                  Module::inst_iterator end,
                                  std::function<bool(Instruction*)> condition) {
  bool removed = false;
  for (auto it = begin; it != end;) {
    if (!condition(&*it)) {
      ++it;
      continue;
    }

    removed = true;
    // `it` is an iterator on an intrusive list. Next is invalidated on the
    // current node when an instruction is killed. The iterator must be moved
    // forward before deleting the node.
    auto instruction = &*it;
    ++it;
    KillInst(instruction);
  }

  return removed;
}

void IRContext::CollectNonSemanticTree(
    Instruction* inst, std::unordered_set<Instruction*>* to_kill) {
  if (!inst->HasResultId()) return;
  // Debug[No]Line result id is not used, so we are done
  if (inst->IsDebugLineInst()) return;
  std::vector<Instruction*> work_list;
  std::unordered_set<Instruction*> seen;
  work_list.push_back(inst);

  while (!work_list.empty()) {
    auto* i = work_list.back();
    work_list.pop_back();
    get_def_use_mgr()->ForEachUser(
        i, [&work_list, to_kill, &seen](Instruction* user) {
          if (user->IsNonSemanticInstruction() && seen.insert(user).second) {
            work_list.push_back(user);
            to_kill->insert(user);
          }
        });
  }
}

bool IRContext::KillDef(uint32_t id) {
  Instruction* def = get_def_use_mgr()->GetDef(id);
  if (def != nullptr) {
    KillInst(def);
    return true;
  }
  return false;
}

bool IRContext::RemoveCapability(spv::Capability capability) {
  const bool removed = KillInstructionIf(
      module()->capability_begin(), module()->capability_end(),
      [capability](Instruction* inst) {
        return static_cast<spv::Capability>(inst->GetSingleWordOperand(0)) ==
               capability;
      });

  if (removed && feature_mgr_ != nullptr) {
    feature_mgr_->RemoveCapability(capability);
  }

  return removed;
}

bool IRContext::RemoveExtension(Extension extension) {
  const std::string_view extensionName = ExtensionToString(extension);
  const bool removed = KillInstructionIf(
      module()->extension_begin(), module()->extension_end(),
      [&extensionName](Instruction* inst) {
        return inst->GetOperand(0).AsString() == extensionName;
      });

  if (removed && feature_mgr_ != nullptr) {
    feature_mgr_->RemoveExtension(extension);
  }

  return removed;
}

bool IRContext::ReplaceAllUsesWith(uint32_t before, uint32_t after) {
  return ReplaceAllUsesWithPredicate(before, after,
                                     [](Instruction*) { return true; });
}

bool IRContext::ReplaceAllUsesWithPredicate(
    uint32_t before, uint32_t after,
    const std::function<bool(Instruction*)>& predicate) {
  if (before == after) return false;

  if (AreAnalysesValid(kAnalysisDebugInfo)) {
    get_debug_info_mgr()->ReplaceAllUsesInDebugScopeWithPredicate(before, after,
                                                                  predicate);
  }

  // Ensure that |after| has been registered as def.
  assert(get_def_use_mgr()->GetDef(after) &&
         "'after' is not a registered def.");

  std::vector<std::pair<Instruction*, uint32_t>> uses_to_update;
  get_def_use_mgr()->ForEachUse(
      before, [&predicate, &uses_to_update](Instruction* user, uint32_t index) {
        if (predicate(user)) {
          uses_to_update.emplace_back(user, index);
        }
      });

  Instruction* prev = nullptr;
  for (auto p : uses_to_update) {
    Instruction* user = p.first;
    uint32_t index = p.second;
    if (prev == nullptr || prev != user) {
      ForgetUses(user);
      prev = user;
    }
    const uint32_t type_result_id_count =
        (user->result_id() != 0) + (user->type_id() != 0);

    if (index < type_result_id_count) {
      // Update the type_id. Note that result id is immutable so it should
      // never be updated.
      if (user->type_id() != 0 && index == 0) {
        user->SetResultType(after);
      } else if (user->type_id() == 0) {
        SPIRV_ASSERT(consumer_, false,
                     "Result type id considered as use while the instruction "
                     "doesn't have a result type id.");
        (void)consumer_;  // Makes the compiler happy for release build.
      } else {
        SPIRV_ASSERT(consumer_, false,
                     "Trying setting the immutable result id.");
      }
    } else {
      // Update an in-operand.
      uint32_t in_operand_pos = index - type_result_id_count;
      // Make the modification in the instruction.
      user->SetInOperand(in_operand_pos, {after});
    }
    AnalyzeUses(user);
  }
  return true;
}

bool IRContext::IsConsistent() {
#ifndef SPIRV_CHECK_CONTEXT
  return true;
#else
  if (AreAnalysesValid(kAnalysisDefUse)) {
    analysis::DefUseManager new_def_use(module());
    if (!CompareAndPrintDifferences(*get_def_use_mgr(), new_def_use)) {
      return false;
    }
  }

  if (AreAnalysesValid(kAnalysisIdToFuncMapping)) {
    for (auto& fn : *module_) {
      if (id_to_func_[fn.result_id()] != &fn) {
        return false;
      }
    }
  }

  if (AreAnalysesValid(kAnalysisInstrToBlockMapping)) {
    for (auto& func : *module()) {
      for (auto& block : func) {
        if (!block.WhileEachInst([this, &block](Instruction* inst) {
              if (get_instr_block(inst) != &block) {
                return false;
              }
              return true;
            }))
          return false;
      }
    }
  }

  if (!CheckCFG()) {
    return false;
  }

  if (AreAnalysesValid(kAnalysisDecorations)) {
    analysis::DecorationManager* dec_mgr = get_decoration_mgr();
    analysis::DecorationManager current(module());

    if (*dec_mgr != current) {
      return false;
    }
  }

  if (feature_mgr_ != nullptr) {
    FeatureManager current(grammar_);
    current.Analyze(module());

    if (current != *feature_mgr_) {
      return false;
    }
  }
  return true;
#endif
}

void IRContext::ForgetUses(Instruction* inst) {
  if (AreAnalysesValid(kAnalysisDefUse)) {
    get_def_use_mgr()->EraseUseRecordsOfOperandIds(inst);
  }
  if (AreAnalysesValid(kAnalysisDecorations)) {
    if (inst->IsDecoration()) {
      get_decoration_mgr()->RemoveDecoration(inst);
    }
  }
  if (AreAnalysesValid(kAnalysisDebugInfo)) {
    get_debug_info_mgr()->ClearDebugInfo(inst);
  }
  RemoveFromIdToName(inst);
}

void IRContext::AnalyzeUses(Instruction* inst) {
  if (AreAnalysesValid(kAnalysisDefUse)) {
    get_def_use_mgr()->AnalyzeInstUse(inst);
  }
  if (AreAnalysesValid(kAnalysisDecorations)) {
    if (inst->IsDecoration()) {
      get_decoration_mgr()->AddDecoration(inst);
    }
  }
  if (AreAnalysesValid(kAnalysisDebugInfo)) {
    get_debug_info_mgr()->AnalyzeDebugInst(inst);
  }
  if (id_to_name_ && (inst->opcode() == spv::Op::OpName ||
                      inst->opcode() == spv::Op::OpMemberName)) {
    id_to_name_->insert({inst->GetSingleWordInOperand(0), inst});
  }
}

void IRContext::KillNamesAndDecorates(uint32_t id) {
  analysis::DecorationManager* dec_mgr = get_decoration_mgr();
  dec_mgr->RemoveDecorationsFrom(id);

  std::vector<Instruction*> name_to_kill;
  for (auto name : GetNames(id)) {
    name_to_kill.push_back(name.second);
  }
  for (Instruction* name_inst : name_to_kill) {
    KillInst(name_inst);
  }
}

void IRContext::KillNamesAndDecorates(Instruction* inst) {
  const uint32_t rId = inst->result_id();
  if (rId == 0) return;
  KillNamesAndDecorates(rId);
}

void IRContext::KillOperandFromDebugInstructions(Instruction* inst) {
  const auto opcode = inst->opcode();
  const uint32_t id = inst->result_id();
  // Kill id of OpFunction from DebugFunction.
  if (opcode == spv::Op::OpFunction) {
    for (auto it = module()->ext_inst_debuginfo_begin();
         it != module()->ext_inst_debuginfo_end(); ++it) {
      if (it->GetOpenCL100DebugOpcode() != OpenCLDebugInfo100DebugFunction)
        continue;
      auto& operand = it->GetOperand(kDebugFunctionOperandFunctionIndex);
      if (operand.words[0] == id) {
        operand.words[0] =
            get_debug_info_mgr()->GetDebugInfoNone()->result_id();
        get_def_use_mgr()->AnalyzeInstUse(&*it);
      }
    }
  }
  // Kill id of OpVariable for global variable from DebugGlobalVariable.
  if (opcode == spv::Op::OpVariable || IsConstantInst(opcode)) {
    for (auto it = module()->ext_inst_debuginfo_begin();
         it != module()->ext_inst_debuginfo_end(); ++it) {
      if (it->GetCommonDebugOpcode() != CommonDebugInfoDebugGlobalVariable)
        continue;
      auto& operand = it->GetOperand(kDebugGlobalVariableOperandVariableIndex);
      if (operand.words[0] == id) {
        operand.words[0] =
            get_debug_info_mgr()->GetDebugInfoNone()->result_id();
        get_def_use_mgr()->AnalyzeInstUse(&*it);
      }
    }
  }
}

void IRContext::AddCombinatorsForCapability(uint32_t capability) {
  spv::Capability cap = spv::Capability(capability);
  if (cap == spv::Capability::Shader) {
    combinator_ops_[0].insert(
        {(uint32_t)spv::Op::OpNop,
         (uint32_t)spv::Op::OpUndef,
         (uint32_t)spv::Op::OpConstant,
         (uint32_t)spv::Op::OpConstantTrue,
         (uint32_t)spv::Op::OpConstantFalse,
         (uint32_t)spv::Op::OpConstantComposite,
         (uint32_t)spv::Op::OpConstantSampler,
         (uint32_t)spv::Op::OpConstantNull,
         (uint32_t)spv::Op::OpTypeVoid,
         (uint32_t)spv::Op::OpTypeBool,
         (uint32_t)spv::Op::OpTypeInt,
         (uint32_t)spv::Op::OpTypeFloat,
         (uint32_t)spv::Op::OpTypeVector,
         (uint32_t)spv::Op::OpTypeMatrix,
         (uint32_t)spv::Op::OpTypeImage,
         (uint32_t)spv::Op::OpTypeSampler,
         (uint32_t)spv::Op::OpTypeSampledImage,
         (uint32_t)spv::Op::OpTypeAccelerationStructureNV,
         (uint32_t)spv::Op::OpTypeAccelerationStructureKHR,
         (uint32_t)spv::Op::OpTypeRayQueryKHR,
         (uint32_t)spv::Op::OpTypeHitObjectNV,
         (uint32_t)spv::Op::OpTypeArray,
         (uint32_t)spv::Op::OpTypeRuntimeArray,
         (uint32_t)spv::Op::OpTypeStruct,
         (uint32_t)spv::Op::OpTypeOpaque,
         (uint32_t)spv::Op::OpTypePointer,
         (uint32_t)spv::Op::OpTypeFunction,
         (uint32_t)spv::Op::OpTypeEvent,
         (uint32_t)spv::Op::OpTypeDeviceEvent,
         (uint32_t)spv::Op::OpTypeReserveId,
         (uint32_t)spv::Op::OpTypeQueue,
         (uint32_t)spv::Op::OpTypePipe,
         (uint32_t)spv::Op::OpTypeForwardPointer,
         (uint32_t)spv::Op::OpVariable,
         (uint32_t)spv::Op::OpImageTexelPointer,
         (uint32_t)spv::Op::OpLoad,
         (uint32_t)spv::Op::OpAccessChain,
         (uint32_t)spv::Op::OpInBoundsAccessChain,
         (uint32_t)spv::Op::OpArrayLength,
         (uint32_t)spv::Op::OpVectorExtractDynamic,
         (uint32_t)spv::Op::OpVectorInsertDynamic,
         (uint32_t)spv::Op::OpVectorShuffle,
         (uint32_t)spv::Op::OpCompositeConstruct,
         (uint32_t)spv::Op::OpCompositeExtract,
         (uint32_t)spv::Op::OpCompositeInsert,
         (uint32_t)spv::Op::OpCopyObject,
         (uint32_t)spv::Op::OpTranspose,
         (uint32_t)spv::Op::OpSampledImage,
         (uint32_t)spv::Op::OpImageSampleImplicitLod,
         (uint32_t)spv::Op::OpImageSampleExplicitLod,
         (uint32_t)spv::Op::OpImageSampleDrefImplicitLod,
         (uint32_t)spv::Op::OpImageSampleDrefExplicitLod,
         (uint32_t)spv::Op::OpImageSampleProjImplicitLod,
         (uint32_t)spv::Op::OpImageSampleProjExplicitLod,
         (uint32_t)spv::Op::OpImageSampleProjDrefImplicitLod,
         (uint32_t)spv::Op::OpImageSampleProjDrefExplicitLod,
         (uint32_t)spv::Op::OpImageFetch,
         (uint32_t)spv::Op::OpImageGather,
         (uint32_t)spv::Op::OpImageDrefGather,
         (uint32_t)spv::Op::OpImageRead,
         (uint32_t)spv::Op::OpImage,
         (uint32_t)spv::Op::OpImageQueryFormat,
         (uint32_t)spv::Op::OpImageQueryOrder,
         (uint32_t)spv::Op::OpImageQuerySizeLod,
         (uint32_t)spv::Op::OpImageQuerySize,
         (uint32_t)spv::Op::OpImageQueryLevels,
         (uint32_t)spv::Op::OpImageQuerySamples,
         (uint32_t)spv::Op::OpConvertFToU,
         (uint32_t)spv::Op::OpConvertFToS,
         (uint32_t)spv::Op::OpConvertSToF,
         (uint32_t)spv::Op::OpConvertUToF,
         (uint32_t)spv::Op::OpUConvert,
         (uint32_t)spv::Op::OpSConvert,
         (uint32_t)spv::Op::OpFConvert,
         (uint32_t)spv::Op::OpQuantizeToF16,
         (uint32_t)spv::Op::OpBitcast,
         (uint32_t)spv::Op::OpSNegate,
         (uint32_t)spv::Op::OpFNegate,
         (uint32_t)spv::Op::OpIAdd,
         (uint32_t)spv::Op::OpFAdd,
         (uint32_t)spv::Op::OpISub,
         (uint32_t)spv::Op::OpFSub,
         (uint32_t)spv::Op::OpIMul,
         (uint32_t)spv::Op::OpFMul,
         (uint32_t)spv::Op::OpUDiv,
         (uint32_t)spv::Op::OpSDiv,
         (uint32_t)spv::Op::OpFDiv,
         (uint32_t)spv::Op::OpUMod,
         (uint32_t)spv::Op::OpSRem,
         (uint32_t)spv::Op::OpSMod,
         (uint32_t)spv::Op::OpFRem,
         (uint32_t)spv::Op::OpFMod,
         (uint32_t)spv::Op::OpVectorTimesScalar,
         (uint32_t)spv::Op::OpMatrixTimesScalar,
         (uint32_t)spv::Op::OpVectorTimesMatrix,
         (uint32_t)spv::Op::OpMatrixTimesVector,
         (uint32_t)spv::Op::OpMatrixTimesMatrix,
         (uint32_t)spv::Op::OpOuterProduct,
         (uint32_t)spv::Op::OpDot,
         (uint32_t)spv::Op::OpIAddCarry,
         (uint32_t)spv::Op::OpISubBorrow,
         (uint32_t)spv::Op::OpUMulExtended,
         (uint32_t)spv::Op::OpSMulExtended,
         (uint32_t)spv::Op::OpAny,
         (uint32_t)spv::Op::OpAll,
         (uint32_t)spv::Op::OpIsNan,
         (uint32_t)spv::Op::OpIsInf,
         (uint32_t)spv::Op::OpLogicalEqual,
         (uint32_t)spv::Op::OpLogicalNotEqual,
         (uint32_t)spv::Op::OpLogicalOr,
         (uint32_t)spv::Op::OpLogicalAnd,
         (uint32_t)spv::Op::OpLogicalNot,
         (uint32_t)spv::Op::OpSelect,
         (uint32_t)spv::Op::OpIEqual,
         (uint32_t)spv::Op::OpINotEqual,
         (uint32_t)spv::Op::OpUGreaterThan,
         (uint32_t)spv::Op::OpSGreaterThan,
         (uint32_t)spv::Op::OpUGreaterThanEqual,
         (uint32_t)spv::Op::OpSGreaterThanEqual,
         (uint32_t)spv::Op::OpULessThan,
         (uint32_t)spv::Op::OpSLessThan,
         (uint32_t)spv::Op::OpULessThanEqual,
         (uint32_t)spv::Op::OpSLessThanEqual,
         (uint32_t)spv::Op::OpFOrdEqual,
         (uint32_t)spv::Op::OpFUnordEqual,
         (uint32_t)spv::Op::OpFOrdNotEqual,
         (uint32_t)spv::Op::OpFUnordNotEqual,
         (uint32_t)spv::Op::OpFOrdLessThan,
         (uint32_t)spv::Op::OpFUnordLessThan,
         (uint32_t)spv::Op::OpFOrdGreaterThan,
         (uint32_t)spv::Op::OpFUnordGreaterThan,
         (uint32_t)spv::Op::OpFOrdLessThanEqual,
         (uint32_t)spv::Op::OpFUnordLessThanEqual,
         (uint32_t)spv::Op::OpFOrdGreaterThanEqual,
         (uint32_t)spv::Op::OpFUnordGreaterThanEqual,
         (uint32_t)spv::Op::OpShiftRightLogical,
         (uint32_t)spv::Op::OpShiftRightArithmetic,
         (uint32_t)spv::Op::OpShiftLeftLogical,
         (uint32_t)spv::Op::OpBitwiseOr,
         (uint32_t)spv::Op::OpBitwiseXor,
         (uint32_t)spv::Op::OpBitwiseAnd,
         (uint32_t)spv::Op::OpNot,
         (uint32_t)spv::Op::OpBitFieldInsert,
         (uint32_t)spv::Op::OpBitFieldSExtract,
         (uint32_t)spv::Op::OpBitFieldUExtract,
         (uint32_t)spv::Op::OpBitReverse,
         (uint32_t)spv::Op::OpBitCount,
         (uint32_t)spv::Op::OpPhi,
         (uint32_t)spv::Op::OpImageSparseSampleImplicitLod,
         (uint32_t)spv::Op::OpImageSparseSampleExplicitLod,
         (uint32_t)spv::Op::OpImageSparseSampleDrefImplicitLod,
         (uint32_t)spv::Op::OpImageSparseSampleDrefExplicitLod,
         (uint32_t)spv::Op::OpImageSparseSampleProjImplicitLod,
         (uint32_t)spv::Op::OpImageSparseSampleProjExplicitLod,
         (uint32_t)spv::Op::OpImageSparseSampleProjDrefImplicitLod,
         (uint32_t)spv::Op::OpImageSparseSampleProjDrefExplicitLod,
         (uint32_t)spv::Op::OpImageSparseFetch,
         (uint32_t)spv::Op::OpImageSparseGather,
         (uint32_t)spv::Op::OpImageSparseDrefGather,
         (uint32_t)spv::Op::OpImageSparseTexelsResident,
         (uint32_t)spv::Op::OpImageSparseRead,
         (uint32_t)spv::Op::OpSizeOf});
  }
}

void IRContext::AddCombinatorsForExtension(Instruction* extension) {
  assert(extension->opcode() == spv::Op::OpExtInstImport &&
         "Expecting an import of an extension's instruction set.");
  const std::string extension_name = extension->GetInOperand(0).AsString();
  if (extension_name == "GLSL.std.450") {
    combinator_ops_[extension->result_id()] = {
        (uint32_t)GLSLstd450Round,
        (uint32_t)GLSLstd450RoundEven,
        (uint32_t)GLSLstd450Trunc,
        (uint32_t)GLSLstd450FAbs,
        (uint32_t)GLSLstd450SAbs,
        (uint32_t)GLSLstd450FSign,
        (uint32_t)GLSLstd450SSign,
        (uint32_t)GLSLstd450Floor,
        (uint32_t)GLSLstd450Ceil,
        (uint32_t)GLSLstd450Fract,
        (uint32_t)GLSLstd450Radians,
        (uint32_t)GLSLstd450Degrees,
        (uint32_t)GLSLstd450Sin,
        (uint32_t)GLSLstd450Cos,
        (uint32_t)GLSLstd450Tan,
        (uint32_t)GLSLstd450Asin,
        (uint32_t)GLSLstd450Acos,
        (uint32_t)GLSLstd450Atan,
        (uint32_t)GLSLstd450Sinh,
        (uint32_t)GLSLstd450Cosh,
        (uint32_t)GLSLstd450Tanh,
        (uint32_t)GLSLstd450Asinh,
        (uint32_t)GLSLstd450Acosh,
        (uint32_t)GLSLstd450Atanh,
        (uint32_t)GLSLstd450Atan2,
        (uint32_t)GLSLstd450Pow,
        (uint32_t)GLSLstd450Exp,
        (uint32_t)GLSLstd450Log,
        (uint32_t)GLSLstd450Exp2,
        (uint32_t)GLSLstd450Log2,
        (uint32_t)GLSLstd450Sqrt,
        (uint32_t)GLSLstd450InverseSqrt,
        (uint32_t)GLSLstd450Determinant,
        (uint32_t)GLSLstd450MatrixInverse,
        (uint32_t)GLSLstd450ModfStruct,
        (uint32_t)GLSLstd450FMin,
        (uint32_t)GLSLstd450UMin,
        (uint32_t)GLSLstd450SMin,
        (uint32_t)GLSLstd450FMax,
        (uint32_t)GLSLstd450UMax,
        (uint32_t)GLSLstd450SMax,
        (uint32_t)GLSLstd450FClamp,
        (uint32_t)GLSLstd450UClamp,
        (uint32_t)GLSLstd450SClamp,
        (uint32_t)GLSLstd450FMix,
        (uint32_t)GLSLstd450IMix,
        (uint32_t)GLSLstd450Step,
        (uint32_t)GLSLstd450SmoothStep,
        (uint32_t)GLSLstd450Fma,
        (uint32_t)GLSLstd450FrexpStruct,
        (uint32_t)GLSLstd450Ldexp,
        (uint32_t)GLSLstd450PackSnorm4x8,
        (uint32_t)GLSLstd450PackUnorm4x8,
        (uint32_t)GLSLstd450PackSnorm2x16,
        (uint32_t)GLSLstd450PackUnorm2x16,
        (uint32_t)GLSLstd450PackHalf2x16,
        (uint32_t)GLSLstd450PackDouble2x32,
        (uint32_t)GLSLstd450UnpackSnorm2x16,
        (uint32_t)GLSLstd450UnpackUnorm2x16,
        (uint32_t)GLSLstd450UnpackHalf2x16,
        (uint32_t)GLSLstd450UnpackSnorm4x8,
        (uint32_t)GLSLstd450UnpackUnorm4x8,
        (uint32_t)GLSLstd450UnpackDouble2x32,
        (uint32_t)GLSLstd450Length,
        (uint32_t)GLSLstd450Distance,
        (uint32_t)GLSLstd450Cross,
        (uint32_t)GLSLstd450Normalize,
        (uint32_t)GLSLstd450FaceForward,
        (uint32_t)GLSLstd450Reflect,
        (uint32_t)GLSLstd450Refract,
        (uint32_t)GLSLstd450FindILsb,
        (uint32_t)GLSLstd450FindSMsb,
        (uint32_t)GLSLstd450FindUMsb,
        (uint32_t)GLSLstd450InterpolateAtCentroid,
        (uint32_t)GLSLstd450InterpolateAtSample,
        (uint32_t)GLSLstd450InterpolateAtOffset,
        (uint32_t)GLSLstd450NMin,
        (uint32_t)GLSLstd450NMax,
        (uint32_t)GLSLstd450NClamp};
  } else {
    // Map the result id to the empty set.
    combinator_ops_[extension->result_id()];
  }
}

void IRContext::InitializeCombinators() {
  for (auto capability : get_feature_mgr()->GetCapabilities()) {
    AddCombinatorsForCapability(uint32_t(capability));
  }

  for (auto& extension : module()->ext_inst_imports()) {
    AddCombinatorsForExtension(&extension);
  }

  valid_analyses_ |= kAnalysisCombinators;
}

void IRContext::RemoveFromIdToName(const Instruction* inst) {
  if (id_to_name_ && (inst->opcode() == spv::Op::OpName ||
                      inst->opcode() == spv::Op::OpMemberName)) {
    auto range = id_to_name_->equal_range(inst->GetSingleWordInOperand(0));
    for (auto it = range.first; it != range.second; ++it) {
      if (it->second == inst) {
        id_to_name_->erase(it);
        break;
      }
    }
  }
}

LoopDescriptor* IRContext::GetLoopDescriptor(const Function* f) {
  if (!AreAnalysesValid(kAnalysisLoopAnalysis)) {
    ResetLoopAnalysis();
  }

  std::unordered_map<const Function*, LoopDescriptor>::iterator it =
      loop_descriptors_.find(f);
  if (it == loop_descriptors_.end()) {
    return &loop_descriptors_
                .emplace(std::make_pair(f, LoopDescriptor(this, f)))
                .first->second;
  }

  return &it->second;
}

uint32_t IRContext::FindBuiltinInputVar(uint32_t builtin) {
  for (auto& a : module_->annotations()) {
    if (spv::Op(a.opcode()) != spv::Op::OpDecorate) continue;
    if (spv::Decoration(a.GetSingleWordInOperand(
            kSpvDecorateDecorationInIdx)) != spv::Decoration::BuiltIn)
      continue;
    if (a.GetSingleWordInOperand(kSpvDecorateBuiltinInIdx) != builtin) continue;
    uint32_t target_id = a.GetSingleWordInOperand(kSpvDecorateTargetIdInIdx);
    Instruction* b_var = get_def_use_mgr()->GetDef(target_id);
    if (b_var->opcode() != spv::Op::OpVariable) continue;
    if (spv::StorageClass(b_var->GetSingleWordInOperand(0)) !=
        spv::StorageClass::Input)
      continue;
    return target_id;
  }
  return 0;
}

void IRContext::AddVarToEntryPoints(uint32_t var_id) {
  uint32_t ocnt = 0;
  for (auto& e : module()->entry_points()) {
    bool found = false;
    e.ForEachInOperand([&ocnt, &found, &var_id](const uint32_t* idp) {
      if (ocnt >= kEntryPointInterfaceInIdx) {
        if (*idp == var_id) found = true;
      }
      ++ocnt;
    });
    if (!found) {
      e.AddOperand({SPV_OPERAND_TYPE_ID, {var_id}});
      get_def_use_mgr()->AnalyzeInstDefUse(&e);
    }
  }
}

uint32_t IRContext::GetBuiltinInputVarId(uint32_t builtin) {
  if (!AreAnalysesValid(kAnalysisBuiltinVarId)) ResetBuiltinAnalysis();
  // If cached, return it.
  std::unordered_map<uint32_t, uint32_t>::iterator it =
      builtin_var_id_map_.find(builtin);
  if (it != builtin_var_id_map_.end()) return it->second;
  // Look for one in shader
  uint32_t var_id = FindBuiltinInputVar(builtin);
  if (var_id == 0) {
    // If not found, create it
    // TODO(greg-lunarg): Add support for all builtins
    analysis::TypeManager* type_mgr = get_type_mgr();
    analysis::Type* reg_type;
    switch (spv::BuiltIn(builtin)) {
      case spv::BuiltIn::FragCoord: {
        analysis::Float float_ty(32);
        analysis::Type* reg_float_ty = type_mgr->GetRegisteredType(&float_ty);
        analysis::Vector v4float_ty(reg_float_ty, 4);
        reg_type = type_mgr->GetRegisteredType(&v4float_ty);
        break;
      }
      case spv::BuiltIn::VertexIndex:
      case spv::BuiltIn::InstanceIndex:
      case spv::BuiltIn::PrimitiveId:
      case spv::BuiltIn::InvocationId:
      case spv::BuiltIn::SubgroupLocalInvocationId: {
        analysis::Integer uint_ty(32, false);
        reg_type = type_mgr->GetRegisteredType(&uint_ty);
        break;
      }
      case spv::BuiltIn::GlobalInvocationId:
      case spv::BuiltIn::LaunchIdNV: {
        analysis::Integer uint_ty(32, false);
        analysis::Type* reg_uint_ty = type_mgr->GetRegisteredType(&uint_ty);
        analysis::Vector v3uint_ty(reg_uint_ty, 3);
        reg_type = type_mgr->GetRegisteredType(&v3uint_ty);
        break;
      }
      case spv::BuiltIn::TessCoord: {
        analysis::Float float_ty(32);
        analysis::Type* reg_float_ty = type_mgr->GetRegisteredType(&float_ty);
        analysis::Vector v3float_ty(reg_float_ty, 3);
        reg_type = type_mgr->GetRegisteredType(&v3float_ty);
        break;
      }
      case spv::BuiltIn::SubgroupLtMask: {
        analysis::Integer uint_ty(32, false);
        analysis::Type* reg_uint_ty = type_mgr->GetRegisteredType(&uint_ty);
        analysis::Vector v4uint_ty(reg_uint_ty, 4);
        reg_type = type_mgr->GetRegisteredType(&v4uint_ty);
        break;
      }
      default: {
        assert(false && "unhandled builtin");
        return 0;
      }
    }
    uint32_t type_id = type_mgr->GetTypeInstruction(reg_type);
    uint32_t varTyPtrId =
        type_mgr->FindPointerToType(type_id, spv::StorageClass::Input);
    // TODO(1841): Handle id overflow.
    var_id = TakeNextId();
    std::unique_ptr<Instruction> newVarOp(
        new Instruction(this, spv::Op::OpVariable, varTyPtrId, var_id,
                        {{spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER,
                          {uint32_t(spv::StorageClass::Input)}}}));
    get_def_use_mgr()->AnalyzeInstDefUse(&*newVarOp);
    module()->AddGlobalValue(std::move(newVarOp));
    get_decoration_mgr()->AddDecorationVal(
        var_id, uint32_t(spv::Decoration::BuiltIn), builtin);
    AddVarToEntryPoints(var_id);
  }
  builtin_var_id_map_[builtin] = var_id;
  return var_id;
}

void IRContext::AddCalls(const 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() == spv::Op::OpFunctionCall)
        todo->push(ii->GetSingleWordInOperand(0));
}

bool IRContext::ProcessEntryPointCallTree(ProcessFunction& pfn) {
  // Collect all of the entry points as the roots.
  std::queue<uint32_t> roots;
  for (auto& e : module()->entry_points()) {
    roots.push(e.GetSingleWordInOperand(kEntryPointFunctionIdInIdx));
  }
  return ProcessCallTreeFromRoots(pfn, &roots);
}

bool IRContext::ProcessReachableCallTree(ProcessFunction& pfn) {
  std::queue<uint32_t> roots;

  // Add all entry points since they can be reached from outside the module.
  for (auto& e : module()->entry_points())
    roots.push(e.GetSingleWordInOperand(kEntryPointFunctionIdInIdx));

  // Add all exported functions since they can be reached from outside the
  // module.
  for (auto& a : annotations()) {
    // TODO: Handle group decorations as well.  Currently not generate by any
    // front-end, but could be coming.
    if (a.opcode() == spv::Op::OpDecorate) {
      if (spv::Decoration(a.GetSingleWordOperand(1)) ==
          spv::Decoration::LinkageAttributes) {
        uint32_t lastOperand = a.NumOperands() - 1;
        if (spv::LinkageType(a.GetSingleWordOperand(lastOperand)) ==
            spv::LinkageType::Export) {
          uint32_t id = a.GetSingleWordOperand(0);
          if (GetFunction(id)) {
            roots.push(id);
          }
        }
      }
    }
  }

  return ProcessCallTreeFromRoots(pfn, &roots);
}

bool IRContext::ProcessCallTreeFromRoots(ProcessFunction& pfn,
                                         std::queue<uint32_t>* roots) {
  // Process call tree
  bool modified = false;
  std::unordered_set<uint32_t> done;

  while (!roots->empty()) {
    const uint32_t fi = roots->front();
    roots->pop();
    if (done.insert(fi).second) {
      Function* fn = GetFunction(fi);
      assert(fn && "Trying to process a function that does not exist.");
      modified = pfn(fn) || modified;
      AddCalls(fn, roots);
    }
  }
  return modified;
}

void IRContext::CollectCallTreeFromRoots(unsigned entryId,
                                         std::unordered_set<uint32_t>* funcs) {
  std::queue<uint32_t> roots;
  roots.push(entryId);
  while (!roots.empty()) {
    const uint32_t fi = roots.front();
    roots.pop();
    funcs->insert(fi);
    Function* fn = GetFunction(fi);
    AddCalls(fn, &roots);
  }
}

void IRContext::EmitErrorMessage(std::string message, Instruction* inst) {
  if (!consumer()) {
    return;
  }

  Instruction* line_inst = inst;
  while (line_inst != nullptr) {  // Stop at the beginning of the basic block.
    if (!line_inst->dbg_line_insts().empty()) {
      line_inst = &line_inst->dbg_line_insts().back();
      if (line_inst->IsNoLine()) {
        line_inst = nullptr;
      }
      break;
    }
    line_inst = line_inst->PreviousNode();
  }

  uint32_t line_number = 0;
  uint32_t col_number = 0;
  std::string source;
  if (line_inst != nullptr) {
    Instruction* file_name =
        get_def_use_mgr()->GetDef(line_inst->GetSingleWordInOperand(0));
    source = file_name->GetInOperand(0).AsString();

    // Get the line number and column number.
    line_number = line_inst->GetSingleWordInOperand(1);
    col_number = line_inst->GetSingleWordInOperand(2);
  }

  message +=
      "\n  " + inst->PrettyPrint(SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES);
  consumer()(SPV_MSG_ERROR, source.c_str(), {line_number, col_number, 0},
             message.c_str());
}

// Gets the dominator analysis for function |f|.
DominatorAnalysis* IRContext::GetDominatorAnalysis(const Function* f) {
  if (!AreAnalysesValid(kAnalysisDominatorAnalysis)) {
    ResetDominatorAnalysis();
  }

  if (dominator_trees_.find(f) == dominator_trees_.end()) {
    dominator_trees_[f].InitializeTree(*cfg(), f);
  }

  return &dominator_trees_[f];
}

// Gets the postdominator analysis for function |f|.
PostDominatorAnalysis* IRContext::GetPostDominatorAnalysis(const Function* f) {
  if (!AreAnalysesValid(kAnalysisDominatorAnalysis)) {
    ResetDominatorAnalysis();
  }

  if (post_dominator_trees_.find(f) == post_dominator_trees_.end()) {
    post_dominator_trees_[f].InitializeTree(*cfg(), f);
  }

  return &post_dominator_trees_[f];
}

bool IRContext::CheckCFG() {
  std::unordered_map<uint32_t, std::vector<uint32_t>> real_preds;
  if (!AreAnalysesValid(kAnalysisCFG)) {
    return true;
  }

  for (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());
      });
    }

    for (auto& bb : function) {
      std::vector<uint32_t> preds = cfg()->preds(bb.id());
      std::vector<uint32_t> real = real_preds[bb.id()];
      std::sort(preds.begin(), preds.end());
      std::sort(real.begin(), real.end());

      bool same = true;
      if (preds.size() != real.size()) {
        same = false;
      }

      for (size_t i = 0; i < real.size() && same; i++) {
        if (preds[i] != real[i]) {
          same = false;
        }
      }

      if (!same) {
        std::cerr << "Predecessors for " << bb.id() << " are different:\n";

        std::cerr << "Real:";
        for (uint32_t i : real) {
          std::cerr << ' ' << i;
        }
        std::cerr << std::endl;

        std::cerr << "Recorded:";
        for (uint32_t i : preds) {
          std::cerr << ' ' << i;
        }
        std::cerr << std::endl;
      }
      if (!same) return false;
    }
  }

  return true;
}

bool IRContext::IsReachable(const opt::BasicBlock& bb) {
  auto enclosing_function = bb.GetParent();
  return GetDominatorAnalysis(enclosing_function)
      ->Dominates(enclosing_function->entry().get(), &bb);
}

spv::ExecutionModel IRContext::GetStage() {
  const auto& entry_points = module()->entry_points();
  if (entry_points.empty()) {
    return spv::ExecutionModel::Max;
  }

  uint32_t stage = entry_points.begin()->GetSingleWordInOperand(
      kEntryPointExecutionModelInIdx);
  auto it = std::find_if(
      entry_points.begin(), entry_points.end(), [stage](const Instruction& x) {
        return x.GetSingleWordInOperand(kEntryPointExecutionModelInIdx) !=
               stage;
      });
  if (it != entry_points.end()) {
    EmitErrorMessage("Mixed stage shader module not supported", &(*it));
  }

  return static_cast<spv::ExecutionModel>(stage);
}

}  // namespace opt
}  // namespace spvtools
