// Copyright (c) 2017 The Khronos Group Inc.
// Copyright (c) 2017 Valve Corporation
// Copyright (c) 2017 LunarG 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 "pass.h"

#include "iterator.h"

namespace spvtools {
namespace opt {

namespace {

const uint32_t kEntryPointFunctionIdInIdx = 1;

}  // namespace

void Pass::AddCalls(ir::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) {
  // Map from function's result id to function
  std::unordered_map<uint32_t, ir::Function*> id2function;
  for (auto& fn : *module) id2function[fn.result_id()] = &fn;

  // 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, id2function, &roots);
}

bool Pass::ProcessReachableCallTree(ProcessFunction& pfn, ir::Module* module) {
  // Map from function's result id to function
  std::unordered_map<uint32_t, ir::Function*> id2function;
  for (auto& fn : *module) id2function[fn.result_id()] = &fn;

  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 : module->annotations()) {
    // TODO: Handle group decorations as well.  Currently not generate by any
    // front-end, but could be coming.
    if (a.opcode() == SpvOp::SpvOpDecorate) {
      if (a.GetSingleWordOperand(1) ==
          SpvDecoration::SpvDecorationLinkageAttributes) {
        uint32_t lastOperand = a.NumOperands() - 1;
        if (a.GetSingleWordOperand(lastOperand) ==
            SpvLinkageType::SpvLinkageTypeExport) {
          uint32_t id = a.GetSingleWordOperand(0);
          if (id2function.count(id) != 0) roots.push(id);
        }
      }
    }
  }

  return ProcessCallTreeFromRoots(pfn, id2function, &roots);
}

bool Pass::ProcessCallTreeFromRoots(
    ProcessFunction& pfn,
    const std::unordered_map<uint32_t, ir::Function*>& id2function,
    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) {
      ir::Function* fn = id2function.at(fi);
      modified = pfn(fn) || modified;
      AddCalls(fn, roots);
    }
  }
  return modified;
}
}  // namespace opt
}  // namespace spvtools

