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

#include <vector>

#include "llvm/ADT/SmallVector.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Module.h"
#include "llvm/Pass.h"
#include "llvm/Support/raw_ostream.h"

#include "clspv/Option.h"

#include "Passes.h"

using namespace llvm;

namespace {
class ScalarizePass : public ModulePass {
public:
  static char ID;
  ScalarizePass() : ModulePass(ID) {}

  bool runOnModule(Module &M) override;

private:
  // Breaks a struct type phi down into its constituent elements. It does this
  // recursively in the event the subtypes are also structs. Returns the
  // replacement value. Returns the replacment value for the phi.
  Value *ScalarizePhi(PHINode *phi);

  // Phi nodes that need to be deleted.
  std::vector<PHINode *> to_delete_;
};
} // namespace

namespace clspv {
ModulePass *createScalarizePass() { return new ScalarizePass(); }
} // namespace clspv

char ScalarizePass::ID = 0;
INITIALIZE_PASS(ScalarizePass, "Scalarize",
                "Scalarizes some instructions with composite returns", false,
                false)

bool ScalarizePass::runOnModule(Module &M) {
  bool Changed = false;
  for (auto &F : M) {
    for (auto &BB : F) {
      for (auto &I : BB) {
        if (auto *phi = dyn_cast<PHINode>(&I)) {
          if (clspv::Option::HackPhis() && phi->getType()->isStructTy()) {
            ScalarizePhi(phi);
            Changed = true;
          }
        }
      }
    }
  }

  for (auto *phi : to_delete_)
    phi->eraseFromParent();

  return Changed;
}

Value *ScalarizePass::ScalarizePhi(PHINode *phi) {
  // Break down all the struct elements of the phi into individual elements and
  // create new phis for them. Recombine the new phis into a single struct
  // after the phi instructions.
  if (!phi->getType()->isStructTy())
    return phi;

  // Cache the insertion location now. If we break down subtypes, we don't want
  // to insert uses before definitions.
  Instruction *where = phi->getParent()->getFirstNonPHI();
  const auto num_incoming_values = phi->getNumIncomingValues();
  unsigned type_index = 0;
  SmallVector<Value *, 16> replacements;
  for (auto *subtype : phi->getType()->subtypes()) {
    PHINode *replacement =
        PHINode::Create(subtype, num_incoming_values, "", phi);
    for (unsigned i = 0; i != num_incoming_values; ++i) {
      auto *incoming_block = phi->getIncomingBlock(i);
      auto *incoming_value = phi->getIncomingValue(i);

      Value *extracted_value = nullptr;
      if (auto *constant = dyn_cast<Constant>(incoming_value)) {
        extracted_value = constant->getAggregateElement(type_index);
      } else {
        // Extract the value just before the incoming block's branch.
        extracted_value = ExtractValueInst::Create(
            incoming_value, {type_index}, "", incoming_block->getTerminator());
      }
      replacement->addIncoming(extracted_value, incoming_block);
    }
    // Recursively break down subtype structs.
    replacements.push_back(ScalarizePhi(replacement));
    ++type_index;
  }

  // Regenerate the struct just after the phi instructions. Update the
  // insertion location to aid RewriteInsertsPass.
  Value *prev = Constant::getNullValue(phi->getType());
  for (unsigned i = 0; i != replacements.size(); ++i) {
    auto insert =
        InsertValueInst::Create(prev, replacements[i], {i}, "", where);
    prev = insert;
  }

  // Replace the struct phi
  phi->replaceAllUsesWith(prev);
  to_delete_.push_back(phi);

  return prev;
}
