//===- CanonicalizeAliases.cpp - ThinLTO Support: Canonicalize Aliases ----===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// Currently this file implements partial alias canonicalization, to
// flatten chains of aliases (also done by GlobalOpt, but not on for
// O0 compiles). E.g.
//  @a = alias i8, i8 *@b
//  @b = alias i8, i8 *@g
//
// will be converted to:
//  @a = alias i8, i8 *@g  <-- @a is now an alias to base object @g
//  @b = alias i8, i8 *@g
//
// Eventually this file will implement full alias canonicalation, so that
// all aliasees are private anonymous values. E.g.
//  @a = alias i8, i8 *@g
//  @g = global i8 0
//
// will be converted to:
//  @0 = private global
//  @a = alias i8, i8* @0
//  @g = alias i8, i8* @0
//
// This simplifies optimization and ThinLTO linking of the original symbols.
//===----------------------------------------------------------------------===//

#include "llvm/Transforms/Utils/CanonicalizeAliases.h"

#include "llvm/IR/Operator.h"
#include "llvm/IR/ValueHandle.h"
#include "llvm/Pass.h"

using namespace llvm;

namespace {

static Constant *canonicalizeAlias(Constant *C, bool &Changed) {
  if (auto *GA = dyn_cast<GlobalAlias>(C)) {
    auto *NewAliasee = canonicalizeAlias(GA->getAliasee(), Changed);
    if (NewAliasee != GA->getAliasee()) {
      GA->setAliasee(NewAliasee);
      Changed = true;
    }
    return NewAliasee;
  }

  auto *CE = dyn_cast<ConstantExpr>(C);
  if (!CE)
    return C;

  std::vector<Constant *> Ops;
  for (Use &U : CE->operands())
    Ops.push_back(canonicalizeAlias(cast<Constant>(U), Changed));
  return CE->getWithOperands(Ops);
}

/// Convert aliases to canonical form.
static bool canonicalizeAliases(Module &M) {
  bool Changed = false;
  for (auto &GA : M.aliases())
    canonicalizeAlias(&GA, Changed);
  return Changed;
}

// Legacy pass that canonicalizes aliases.
class CanonicalizeAliasesLegacyPass : public ModulePass {

public:
  /// Pass identification, replacement for typeid
  static char ID;

  /// Specify pass name for debug output
  StringRef getPassName() const override { return "Canonicalize Aliases"; }

  explicit CanonicalizeAliasesLegacyPass() : ModulePass(ID) {}

  bool runOnModule(Module &M) override { return canonicalizeAliases(M); }
};
char CanonicalizeAliasesLegacyPass::ID = 0;

} // anonymous namespace

PreservedAnalyses CanonicalizeAliasesPass::run(Module &M,
                                               ModuleAnalysisManager &AM) {
  if (!canonicalizeAliases(M))
    return PreservedAnalyses::all();

  return PreservedAnalyses::none();
}

INITIALIZE_PASS_BEGIN(CanonicalizeAliasesLegacyPass, "canonicalize-aliases",
                      "Canonicalize aliases", false, false)
INITIALIZE_PASS_END(CanonicalizeAliasesLegacyPass, "canonicalize-aliases",
                    "Canonicalize aliases", false, false)

namespace llvm {
ModulePass *createCanonicalizeAliasesPass() {
  return new CanonicalizeAliasesLegacyPass();
}
} // namespace llvm
