10b57cec5SDimitry Andric //===- CanonicalizeAliases.cpp - ThinLTO Support: Canonicalize Aliases ----===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // Currently this file implements partial alias canonicalization, to
100b57cec5SDimitry Andric // flatten chains of aliases (also done by GlobalOpt, but not on for
110b57cec5SDimitry Andric // O0 compiles). E.g.
120b57cec5SDimitry Andric // @a = alias i8, i8 *@b
130b57cec5SDimitry Andric // @b = alias i8, i8 *@g
140b57cec5SDimitry Andric //
150b57cec5SDimitry Andric // will be converted to:
160b57cec5SDimitry Andric // @a = alias i8, i8 *@g <-- @a is now an alias to base object @g
170b57cec5SDimitry Andric // @b = alias i8, i8 *@g
180b57cec5SDimitry Andric //
19bdd1243dSDimitry Andric // Eventually this file will implement full alias canonicalization, so that
200b57cec5SDimitry Andric // all aliasees are private anonymous values. E.g.
210b57cec5SDimitry Andric // @a = alias i8, i8 *@g
220b57cec5SDimitry Andric // @g = global i8 0
230b57cec5SDimitry Andric //
240b57cec5SDimitry Andric // will be converted to:
250b57cec5SDimitry Andric // @0 = private global
260b57cec5SDimitry Andric // @a = alias i8, i8* @0
270b57cec5SDimitry Andric // @g = alias i8, i8* @0
280b57cec5SDimitry Andric //
290b57cec5SDimitry Andric // This simplifies optimization and ThinLTO linking of the original symbols.
300b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
310b57cec5SDimitry Andric
320b57cec5SDimitry Andric #include "llvm/Transforms/Utils/CanonicalizeAliases.h"
3381ad6265SDimitry Andric #include "llvm/IR/Constants.h"
34*0fca6ea1SDimitry Andric #include "llvm/IR/Module.h"
350b57cec5SDimitry Andric
360b57cec5SDimitry Andric using namespace llvm;
370b57cec5SDimitry Andric
380b57cec5SDimitry Andric namespace {
390b57cec5SDimitry Andric
canonicalizeAlias(Constant * C,bool & Changed)400b57cec5SDimitry Andric static Constant *canonicalizeAlias(Constant *C, bool &Changed) {
410b57cec5SDimitry Andric if (auto *GA = dyn_cast<GlobalAlias>(C)) {
420b57cec5SDimitry Andric auto *NewAliasee = canonicalizeAlias(GA->getAliasee(), Changed);
430b57cec5SDimitry Andric if (NewAliasee != GA->getAliasee()) {
440b57cec5SDimitry Andric GA->setAliasee(NewAliasee);
450b57cec5SDimitry Andric Changed = true;
460b57cec5SDimitry Andric }
470b57cec5SDimitry Andric return NewAliasee;
480b57cec5SDimitry Andric }
490b57cec5SDimitry Andric
500b57cec5SDimitry Andric auto *CE = dyn_cast<ConstantExpr>(C);
510b57cec5SDimitry Andric if (!CE)
520b57cec5SDimitry Andric return C;
530b57cec5SDimitry Andric
540b57cec5SDimitry Andric std::vector<Constant *> Ops;
550b57cec5SDimitry Andric for (Use &U : CE->operands())
560b57cec5SDimitry Andric Ops.push_back(canonicalizeAlias(cast<Constant>(U), Changed));
570b57cec5SDimitry Andric return CE->getWithOperands(Ops);
580b57cec5SDimitry Andric }
590b57cec5SDimitry Andric
600b57cec5SDimitry Andric /// Convert aliases to canonical form.
canonicalizeAliases(Module & M)610b57cec5SDimitry Andric static bool canonicalizeAliases(Module &M) {
620b57cec5SDimitry Andric bool Changed = false;
630b57cec5SDimitry Andric for (auto &GA : M.aliases())
640b57cec5SDimitry Andric canonicalizeAlias(&GA, Changed);
650b57cec5SDimitry Andric return Changed;
660b57cec5SDimitry Andric }
670b57cec5SDimitry Andric } // anonymous namespace
680b57cec5SDimitry Andric
run(Module & M,ModuleAnalysisManager & AM)690b57cec5SDimitry Andric PreservedAnalyses CanonicalizeAliasesPass::run(Module &M,
700b57cec5SDimitry Andric ModuleAnalysisManager &AM) {
710b57cec5SDimitry Andric if (!canonicalizeAliases(M))
720b57cec5SDimitry Andric return PreservedAnalyses::all();
730b57cec5SDimitry Andric
740b57cec5SDimitry Andric return PreservedAnalyses::none();
750b57cec5SDimitry Andric }
76