aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/llvm14/lib/IR/ReplaceConstant.cpp
diff options
context:
space:
mode:
authorvitalyisaev <vitalyisaev@yandex-team.com>2023-06-29 10:00:50 +0300
committervitalyisaev <vitalyisaev@yandex-team.com>2023-06-29 10:00:50 +0300
commit6ffe9e53658409f212834330e13564e4952558f6 (patch)
tree85b1e00183517648b228aafa7c8fb07f5276f419 /contrib/libs/llvm14/lib/IR/ReplaceConstant.cpp
parent726057070f9c5a91fc10fde0d5024913d10f1ab9 (diff)
downloadydb-6ffe9e53658409f212834330e13564e4952558f6.tar.gz
YQ Connector: support managed ClickHouse
Со стороны dqrun можно обратиться к инстансу коннектора, который работает на streaming стенде, и извлечь данные из облачного CH.
Diffstat (limited to 'contrib/libs/llvm14/lib/IR/ReplaceConstant.cpp')
-rw-r--r--contrib/libs/llvm14/lib/IR/ReplaceConstant.cpp135
1 files changed, 135 insertions, 0 deletions
diff --git a/contrib/libs/llvm14/lib/IR/ReplaceConstant.cpp b/contrib/libs/llvm14/lib/IR/ReplaceConstant.cpp
new file mode 100644
index 0000000000..d2f676192e
--- /dev/null
+++ b/contrib/libs/llvm14/lib/IR/ReplaceConstant.cpp
@@ -0,0 +1,135 @@
+//===- ReplaceConstant.cpp - Replace LLVM constant expression--------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements a utility function for replacing LLVM constant
+// expressions by instructions.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/IR/ReplaceConstant.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/ValueMap.h"
+
+namespace llvm {
+
+void convertConstantExprsToInstructions(Instruction *I, ConstantExpr *CE,
+ SmallPtrSetImpl<Instruction *> *Insts) {
+ // Collect all reachable paths to CE from constant exprssion operands of I.
+ std::map<Use *, std::vector<std::vector<ConstantExpr *>>> CEPaths;
+ collectConstantExprPaths(I, CE, CEPaths);
+
+ // Convert all constant expressions to instructions which are collected at
+ // CEPaths.
+ convertConstantExprsToInstructions(I, CEPaths, Insts);
+}
+
+void convertConstantExprsToInstructions(
+ Instruction *I,
+ std::map<Use *, std::vector<std::vector<ConstantExpr *>>> &CEPaths,
+ SmallPtrSetImpl<Instruction *> *Insts) {
+ ValueMap<ConstantExpr *, Instruction *> Visited;
+
+ for (Use &U : I->operands()) {
+ // The operand U is either not a constant expression operand or the
+ // constant expression paths do not belong to U, ignore U.
+ if (!CEPaths.count(&U))
+ continue;
+
+ // If the instruction I is a PHI instruction, then fix the instruction
+ // insertion point to the entry of the incoming basic block for operand U.
+ auto *BI = I;
+ if (auto *Phi = dyn_cast<PHINode>(I)) {
+ BasicBlock *BB = Phi->getIncomingBlock(U);
+ BI = &(*(BB->getFirstInsertionPt()));
+ }
+
+ // Go through all the paths associated with operand U, and convert all the
+ // constant expressions along all the paths to corresponding instructions.
+ auto *II = I;
+ auto &Paths = CEPaths[&U];
+ for (auto &Path : Paths) {
+ for (auto *CE : Path) {
+ // Instruction which is equivalent to CE.
+ Instruction *NI = nullptr;
+
+ if (!Visited.count(CE)) {
+ // CE is encountered first time, convert it into a corresponding
+ // instruction NI, and appropriately insert NI before the parent
+ // instruction.
+ NI = CE->getAsInstruction(BI);
+
+ // Mark CE as visited by mapping CE to NI.
+ Visited[CE] = NI;
+
+ // If required collect NI.
+ if (Insts)
+ Insts->insert(NI);
+ } else {
+ // We had already encountered CE, the correponding instruction already
+ // exist, use it to replace CE.
+ NI = Visited[CE];
+ }
+
+ assert(NI && "Expected an instruction corresponding to constant "
+ "expression.");
+
+ // Replace all uses of constant expression CE by the corresponding
+ // instruction NI within the current parent instruction.
+ II->replaceUsesOfWith(CE, NI);
+ BI = II = NI;
+ }
+ }
+ }
+
+ // Remove all converted constant expressions which are dead by now.
+ for (auto Item : Visited)
+ Item.first->removeDeadConstantUsers();
+}
+
+void collectConstantExprPaths(
+ Instruction *I, ConstantExpr *CE,
+ std::map<Use *, std::vector<std::vector<ConstantExpr *>>> &CEPaths) {
+ for (Use &U : I->operands()) {
+ // If the operand U is not a constant expression operand, then ignore it.
+ auto *CE2 = dyn_cast<ConstantExpr>(U.get());
+ if (!CE2)
+ continue;
+
+ // Holds all reachable paths from CE2 to CE.
+ std::vector<std::vector<ConstantExpr *>> Paths;
+
+ // Collect all reachable paths from CE2 to CE.
+ std::vector<ConstantExpr *> Path{CE2};
+ std::vector<std::vector<ConstantExpr *>> Stack{Path};
+ while (!Stack.empty()) {
+ std::vector<ConstantExpr *> TPath = Stack.back();
+ Stack.pop_back();
+ auto *CE3 = TPath.back();
+
+ if (CE3 == CE) {
+ Paths.push_back(TPath);
+ continue;
+ }
+
+ for (auto &UU : CE3->operands()) {
+ if (auto *CE4 = dyn_cast<ConstantExpr>(UU.get())) {
+ std::vector<ConstantExpr *> NPath(TPath.begin(), TPath.end());
+ NPath.push_back(CE4);
+ Stack.push_back(NPath);
+ }
+ }
+ }
+
+ // Associate all the collected paths with U, and save it.
+ if (!Paths.empty())
+ CEPaths[&U] = Paths;
+ }
+}
+
+} // namespace llvm