xref: /freebsd/contrib/llvm-project/llvm/lib/Transforms/Utils/CanonicalizeAliases.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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