ReplaceConstant.cpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. //===- ReplaceConstant.cpp - Replace LLVM constant expression--------------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // This file implements a utility function for replacing LLVM constant
  10. // expressions by instructions.
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #include "llvm/IR/ReplaceConstant.h"
  14. #include "llvm/ADT/SmallPtrSet.h"
  15. #include "llvm/IR/Constants.h"
  16. #include "llvm/IR/Instructions.h"
  17. #include "llvm/IR/ValueMap.h"
  18. namespace llvm {
  19. void convertConstantExprsToInstructions(Instruction *I, ConstantExpr *CE,
  20. SmallPtrSetImpl<Instruction *> *Insts) {
  21. // Collect all reachable paths to CE from constant exprssion operands of I.
  22. std::map<Use *, std::vector<std::vector<ConstantExpr *>>> CEPaths;
  23. collectConstantExprPaths(I, CE, CEPaths);
  24. // Convert all constant expressions to instructions which are collected at
  25. // CEPaths.
  26. convertConstantExprsToInstructions(I, CEPaths, Insts);
  27. }
  28. void convertConstantExprsToInstructions(
  29. Instruction *I,
  30. std::map<Use *, std::vector<std::vector<ConstantExpr *>>> &CEPaths,
  31. SmallPtrSetImpl<Instruction *> *Insts) {
  32. ValueMap<ConstantExpr *, Instruction *> Visited;
  33. for (Use &U : I->operands()) {
  34. // The operand U is either not a constant expression operand or the
  35. // constant expression paths do not belong to U, ignore U.
  36. if (!CEPaths.count(&U))
  37. continue;
  38. // If the instruction I is a PHI instruction, then fix the instruction
  39. // insertion point to the entry of the incoming basic block for operand U.
  40. auto *BI = I;
  41. if (auto *Phi = dyn_cast<PHINode>(I)) {
  42. BasicBlock *BB = Phi->getIncomingBlock(U);
  43. BI = &(*(BB->getFirstInsertionPt()));
  44. }
  45. // Go through all the paths associated with operand U, and convert all the
  46. // constant expressions along all the paths to corresponding instructions.
  47. auto *II = I;
  48. auto &Paths = CEPaths[&U];
  49. for (auto &Path : Paths) {
  50. for (auto *CE : Path) {
  51. // Instruction which is equivalent to CE.
  52. Instruction *NI = nullptr;
  53. if (!Visited.count(CE)) {
  54. // CE is encountered first time, convert it into a corresponding
  55. // instruction NI, and appropriately insert NI before the parent
  56. // instruction.
  57. NI = CE->getAsInstruction(BI);
  58. // Mark CE as visited by mapping CE to NI.
  59. Visited[CE] = NI;
  60. // If required collect NI.
  61. if (Insts)
  62. Insts->insert(NI);
  63. } else {
  64. // We had already encountered CE, the correponding instruction already
  65. // exist, use it to replace CE.
  66. NI = Visited[CE];
  67. }
  68. assert(NI && "Expected an instruction corresponding to constant "
  69. "expression.");
  70. // Replace all uses of constant expression CE by the corresponding
  71. // instruction NI within the current parent instruction.
  72. II->replaceUsesOfWith(CE, NI);
  73. BI = II = NI;
  74. }
  75. }
  76. }
  77. // Remove all converted constant expressions which are dead by now.
  78. for (auto Item : Visited)
  79. Item.first->removeDeadConstantUsers();
  80. }
  81. void collectConstantExprPaths(
  82. Instruction *I, ConstantExpr *CE,
  83. std::map<Use *, std::vector<std::vector<ConstantExpr *>>> &CEPaths) {
  84. for (Use &U : I->operands()) {
  85. // If the operand U is not a constant expression operand, then ignore it.
  86. auto *CE2 = dyn_cast<ConstantExpr>(U.get());
  87. if (!CE2)
  88. continue;
  89. // Holds all reachable paths from CE2 to CE.
  90. std::vector<std::vector<ConstantExpr *>> Paths;
  91. // Collect all reachable paths from CE2 to CE.
  92. std::vector<ConstantExpr *> Path{CE2};
  93. std::vector<std::vector<ConstantExpr *>> Stack{Path};
  94. while (!Stack.empty()) {
  95. std::vector<ConstantExpr *> TPath = Stack.back();
  96. Stack.pop_back();
  97. auto *CE3 = TPath.back();
  98. if (CE3 == CE) {
  99. Paths.push_back(TPath);
  100. continue;
  101. }
  102. for (auto &UU : CE3->operands()) {
  103. if (auto *CE4 = dyn_cast<ConstantExpr>(UU.get())) {
  104. std::vector<ConstantExpr *> NPath(TPath.begin(), TPath.end());
  105. NPath.push_back(CE4);
  106. Stack.push_back(NPath);
  107. }
  108. }
  109. }
  110. // Associate all the collected paths with U, and save it.
  111. if (!Paths.empty())
  112. CEPaths[&U] = Paths;
  113. }
  114. }
  115. } // namespace llvm